Java多态问题
对于 SCJP,大多数时候会提出如下问题来查找多态方法调用的有效示例。但是,人们究竟应该寻找什么来确定它是否是多态使用呢?
abstract class A {
abstract void a1();
void a2() { }
}
class B extends A {
void a1() { }
void a2() { }
}
class C extends B {
void c1() { }
}
以及:
A x = new B();
C y = new C();
A z = new C();
多态方法调用的四个有效示例是什么? (选择四项。)
A. x.a2();
B. z.a2();
C. z.c1();
D. z.a1();
E. y.c1();
F. x.a1();
答案:A、B、D、F
For SCJP most of the time question such as below is asked to find valid example of polymorphic method calls. But what should one exactly look for to find is it polymorphic use or not ?
abstract class A {
abstract void a1();
void a2() { }
}
class B extends A {
void a1() { }
void a2() { }
}
class C extends B {
void c1() { }
}
and:
A x = new B();
C y = new C();
A z = new C();
What are four valid examples of polymorphic method calls? (Choose four.)
A. x.a2();
B. z.a2();
C. z.c1();
D. z.a1();
E. y.c1();
F. x.a1();
Answer: A, B, D, F
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
答案 C 无法编译(声明的类中未定义方法)。答案 E 不是多态的(方法在声明的类中定义)。所有剩余的答案都使用一个方法,该方法要么被实现(来自抽象定义),要么被重写,要么被子类化(其中所有都是多态行为)。
概述如下:
Answer C won't compile (method isn't defined in the declared class). Answer E isn't polymorphic (method is definied in the declared class). All remaining answers uses a method which are either implemented (from an abstract definition), or overridden, or subclassed (of which all are polymorphic behaviours).
Here's an overview:
我是美国一所主要大学的助教,教授 Java 课程,这就是我总是向我的学生解释多态性的方式:
这里实际上发生了两件事,非常相似:多态性和动态绑定。
多态性简单地定义为引用类型和对象类型不同。经典的例子是 Animal anim = new Dog();与狗延伸动物。 anim 的引用类型 (Animal) 与其对象类型 (Dog) 不同,因此 anim 是多态引用。
第二部分是动态绑定,它与进行方法调用时实际运行的方法有关。动态绑定意味着实际运行的方法是位于引用类型和对象类型之间的类层次结构最下面的方法。您也可以将其视为属于最接近对象类型的类的方法。
类层次结构是您看到的树,其中每个类都是其父类的一个分支。由于 Java 是单继承的(C++ 和其他语言允许扩展多个类,但在 Java 中只能扩展一个类),类层次结构通常是一棵树。请记住,接口和抽象类也包含在类层次结构中,因此由于接口的原因,它不一定是一棵树。
多态性和动态绑定经常一起使用的原因是,如果没有动态绑定,多态性就没有多大意义。能够让方法的运行依赖于对象类型而不是引用类型,这就是多态性的全部点!
I'm a TA for a major American university teaching a Java class, and this is how I always explain polymorphism to my students:
There are actually two things going on here, which are very similar: polymorphism and dynamic binding.
Polymorphism is simply defined as when the reference type and object type are different. The classic example is Animal anim = new Dog(); with Dog extending Animal. The reference type of anim (Animal) is different than its object type (Dog) so anim is a polymorphic reference.
The second part is dynamic binding, which has to do with what method is actually run when you make a method call. Dynamic binding means that the method that actually runs is the method that is farthest down the class hierarchy between the reference type and object type. You can also think of it as the method the belongs to the class closest to the object type.
The class hierarchy is the tree you see where each class is a branch of its parent class. Since Java is single-inheritance (C++ and others allow you to extend multiple classes, but in Java you can only extend one) the class hierarchy is typically a tree. Keep in mind that interfaces and abstract classes are also included in the class hierarchy, so it's not necessarily a tree due to interfaces.
The reason that polymorphism and dynamic binding are used so often together is that polymorphism doesn't make much sense without dynamic binding. Being able to have the method that runs depend on the object type instead of the reference type is the entire point of polymorphism!
A 有效,因为您正在调用已在
B
中覆盖的a2()
。 C 甚至无法编译,因为类A
中不存在c1()
方法。 E 无效,因为类型和实际实例相同,不需要多态性。同样,您可以考虑其他选择。A is valid because you are calling
a2()
which has been overridden inB
. C will not even compile because thec1()
method is not present in classA
. E is not valid because the type and the actual instances are same, no need for polymorphism. Similarly, you can figure other options.在这个问题中,多态方法调用似乎是对属于继承链中比调用它的对象类型更高的对象的方法的调用,而不是对在继承链中编写或重载的方法的调用。给定对象的类。
因此,由于 c 和 e 正在调用它们自己的类中的方法,因此它们不会调用链上更高层的类的方法 - 它们正在调用重载版本。
希望这有帮助。
It would appear that, in this question, polymorphic method calls are calls to a method that belong to object that is higher up in the inheritance chain than the type of the object that is invoking it, and NOT a method that written or overloaded in the given object's class.
So since c and e are calling methods within their own class, they are not calling methods of classes higher up the chain - they are calling the overloaded versions.
Hope this helps.