2012-04-20 91 views
-1

如果Fruit类是超类和水果AppleOrange是子类, 和GoldenDeliciousMacintoshApple子类。继承和多态冲突

假设如下声明中给出:

Fruit fruit = new GoldenDelicious(); 
Orange orange = new Orange(); 

回答这个问题解释

假设方法makeAppleCiderApple类中定义。 fruit可以调用这个方法吗?橙色可以调用这个方法吗?

我的答案是:可以 水果调用这个方法吗?没有理由没有明确的投射,必须做明确的投影果实例以启用Apple类中定义的方法。剂量这个答案是真的吗?

+3

这看起来极像是一个家庭作业。是吗? – Jasper 2012-04-20 20:55:34

+0

@Aidanc - 在最后一段的问题末尾有一个建议的解决方案。 – Flexo 2012-04-20 20:59:46

+0

不,我正在从java书的介绍学习java,并且在每章之后解决问题。 所以,我想知道真正的答案,因为我在对象投射和多态性方面有冲突。 它没有一个功课。 我正在研究它自学 – MUE 2012-04-20 21:02:48

回答

0

A Fruit没有makeAppleCider方法的“知识”。 makeAppleCider在子类中定义,不是Fruit的成员。一个类只能访问它或其父母定义的方法。给定一个特定类型的类,你必须追溯类层次结构来查看你可以访问哪些方法。你可以将变量的类型想象为走回类层次结构的起始位置。

如果您希望所有类都有权访问某个方法,请将其放入层次结构的根目录中。显然,使用该方法的逻辑应该是有意义的,否则使用你的代码的人会感到困惑。

0

另一种选择当然是使用“接口” - 一种穷人的多重继承(但比完全多重继承更容易理解和实现)。

,你可以,例如,有一个接口八九不离十等(未语法检查):

public interface CiderFruit { 
    public void makeCider(); 
} 

那么苹果可能实现的接口:

public class Apple extends Fruit implements CiderFruit { 
    .... 
    public void makeCider() { 
     doStuff(); 
    } 
    .... 
} 

如果再有一个木瓜类它可以实现相同的界面,可以选择Apple或Quince,将它投射到CiderFruit(如果不确定它是Apple还是Quince),并调用makeCider()。 (也可以直接调用Apple或Quince类型的引用)。

1

这可以深入到变量的静态和动态类型中。

Fruit fruit; 

这行声明静态类型Fruit可变fruit。这种类型永远不会改变(它毕竟是静态的),并且是你通常使用的。

fruit = new GoldenDelicious(); 

这一行是一个分配一个值,该值是一个GoldenDelicious到该变量。变量的动态类型确实会发生变化以反映这种变化。毕竟,变量实际上包含一个GoldenDelicious现在。动态类型是你通常不会使用的东西,但它是当你使用(邪恶)instanceof(并确保在正确的地方调用覆盖函数)时使用的类型。

现在,你想这样做:

fruit.makeAppleCider(); 

这是行不通的。在水果中,我们基本上只知道静态类型,而静态类型Fruit对这种方法一无所知。 (然而,在幕后,如果GoldenDeliciousMacintosh以不同方式实现的功能,动态类型将确保正确的版本叫做)

正如你在答复中提到,显式转换可以用来改变你正在使用的静态类型,因此你可以使它以这种方式工作。尽管如此,最好不要这样做,因为应该避免演员阵容,而不是“适当的面对面”。

总之,是的,你的回答是正确的。

(是的,我的描述是有些技术性的。我希望你能原谅我这一...)

+0

谢谢,我已经原谅你:)) – MUE 2012-04-20 21:55:10

+0

很好的答案。不同的视角。 – Dhananjay 2012-04-21 09:38:10