类C具有void方法m,但不带参数。另一个D类扩展C并覆盖m。每个类都有一个没有参数的构造函数。在下面的每一个中,说出它是否合法,如果是,那么将使用m的哪个定义。Java继承
我)C x = new D(); x.m();
II)D x = new C(); x.m();
我想我是合法的,并且ii并不违法。不知道我怎样才能解决这个问题,欢迎提供任何提示。
类C具有void方法m,但不带参数。另一个D类扩展C并覆盖m。每个类都有一个没有参数的构造函数。在下面的每一个中,说出它是否合法,如果是,那么将使用m的哪个定义。Java继承
我)C x = new D(); x.m();
II)D x = new C(); x.m();
我想我是合法的,并且ii并不违法。不知道我怎样才能解决这个问题,欢迎提供任何提示。
回答这个问题的最好方法是写一些代码,看看会发生什么。在您的m
的实现中使用System.out.println("method called from C");
来确定调用哪个实现。话虽如此,重写一个方法的重点就是使新的实现能够被使用。如果你的对象是C
,那么将调用C
的方法。如果您的对象是D
类型,那么D
的方法将被调用,而不管参考是什么类型。
第一个答案:
C x = new D();
是合法的,因为和类型D
的对象是C
,以及(因为D
延伸C
)。
第二个答案:
D x = new C();
是不合法的,因为到D
参考无法保持其超C
的对象。
是的,你是对的。
(i)是合法的,这将是D
的是获取运行m
方法(这被称为多态性)。 (ii)是非法的,甚至不会编译,因为D
不是超类型的C
(实际上,它是一个子类型)。我们可以把它写它作为编译:
D x = (D) new C(); x.m();
,但随后会在运行时失败了ClassCastException
尝试从“是”的关系来考虑继承。
如果D extends C
那么这意味着每个d是C,但并不意味着每一个C是D.
要应用的思维,问题转化为一个“是”的问题。
C x = new D()
是需要一个new D()
是C
的声明。
在String s = new Object()
,问问自己“是new Object()
a String
?”反之亦然呢?
祝你好运学习OOP。
i)是合法的,ii)不是。很容易看出你是否使用了一个隐喻,比如C类是Animal,D类是Dog,m()是makeNoise。 现在有一个动物类变量并为其指定一个狗是合法的(因为狗是“动物”),但是将动物实例化并将它分配给狗是不合法的,因为狗比动物更具体(我们不能说动物是“狗”)。
现在对于方法:该方法总是在运行时类型上调用,而不是在变量类型上调用(所有方法调用在Java中都是所谓的虚拟),所以在i)它调用m()方法D级,而不是C级。
非常感谢您的快速回复。你已经帮我:-) – Paradox 2011-05-07 13:06:28