java - 在 Java 编译时检查组合与继承约束

标签 java inheritance composition

我有一个关于 Java 继承和组合最佳实践的问题:

Say you've got a Fruit which gets extended by Apple and Lemon.

Next to these you also got a Basket that gets extended by AppleBasket and LemonBasket.

Fruits have a bidirectional one-to-many relationship with their respective baskets, so Fruits have a basket, and baskets have a list of fruits.

现在我想做的就是强制 AppleBasket 在编译时只包含 Apple,LemonBaskets 也是如此。类似地,Apple 应该只具有 AppleBasket 作为属性,Lemons 也是如此。

我尝试过使用泛型、抽象方法和 protected 变量,但我总是找到不采用某种方法的理由。重要的是我们不要违反 SOLID 原则,因此例如父类(super class)应该包含 has-a 和 has-many 属性以避免代码重复等。

当有人试图将 Lemon 放入 AppleBasket 时,出现编译器错误的关键是,反之亦然。

干杯, 安德烈亚斯

最佳答案

通过谷歌搜索协变和逆变,您可能会找到一些有关更复杂类型的有用信息。

如果您不介意使用 Scala,它可以编译为可与 Java 程序一起使用的字节码,Scala 为您提供了一些很好的语法来执行此类操作(稍后使用 Java):

class Fruit
class Basket[T <: Fruit ] {
    def addToBasket(fruit:T) =  {}
}

class Apple extends Fruit
class Lemon extends Fruit

class AppleBasket extends Basket[Apple]

val applebasket = new AppleBasket

applebasket.addToBasket(new Apple)

applebasket.addToBasket(new Lemon)

此代码片段的最后一行给出了编译时错误:

 $ scala Test.scala
C:\cygwin\home\user\Test.scala:18: error: type mismatch;
 found   : this.Lemon
 required: this.Apple
applebasket.addToBasket(new Lemon)
                        ^
one error found

我最近一直在使用 Scala,在 Java 中思考这个问题时遇到了困难,但在 Java 中我可能会做更多类似这样的事情:

class Fruit{}
class Apple extends Fruit{}
class Lemon extends Fruit{}
class Basket<T extends Fruit>{
    public void addToBasket(T foo) {}
}
class Blah {
    void doIt() {
        Apple a = new Apple();
        Basket b = new Basket<Apple>();
        b.addToBasket(a);
        Lemon l = new Lemon();
        b.addToBasket(l);
    }
}

b.addToBasket(l) 行给出以下编译时类型错误:

The method addToBasket(Apple) in the type Basket<Apple> is not applicable for the arguments (Lemon)

另一个给出相同编译错误的选项(从注释中复制以使其更清晰):

//same definition of Fruit, Apple, and Basket, but with:
class AppleBasket extends Basket<Apple> {}
class Blah {
    void doIt() {
        Apple a = new Apple();
        Basket<Apple> b = new AppleBasket();
        b.addToBasket(a);
        Lemon l = new Lemon();
        b.addToBasket(l);
    }
}

关于java - 在 Java 编译时检查组合与继承约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11842001/

相关文章:

没有 Prism 的 WPF UI 组合

java - 在java中生成不重复的随机数

java - 如何通过 REST 从 Jhipster 应用程序下载文件?

java - 以某个字符串开头的字符串的正则表达式

c++ - 为什么通过公开继承另一个类来构建一个类是一种糟糕的做法?

javascript - 我想停止在 javascript 中使用 OOP 并改用委托(delegate)

java - 互相使用两个 struts2 标签库

c++ - *.h文件和*.cpp文件中派生类的定义和声明

java - 为什么我们不能在Java中实例化一个抽象类?

programming-languages - "compose well"对某些东西意味着什么?