对于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
答案 0 :(得分:9)
答案C不会编译(方法未在声明的类中定义)。答案E不是多态的(方法在声明的类中定义)。所有剩余的答案都使用一种方法,该方法可以实现(从抽象定义),也可以覆盖,或者子类化(其中所有都是多态行为)。
以下是概述:
A x = new B();
C y = new C();
A z = new C();
A. x.a2(); // Method is overriden.
B. z.a2(); // Method is inherited.
C. z.c1(); // Won't compile. Method isn't defined in A.
D. z.a1(); // Method is implemented.
E. y.c1(); // Not polymorphic. Method is defined in declared class C.
F. x.a1(); // Method is implemented.
答案 1 :(得分:8)
我是一所美国大学教授Java课程的助教,这就是我总是向学生解释多态性的方法:
这里实际上有两件事情非常相似:多态和动态绑定。
多态性简单地定义为引用类型和对象类型不同时。经典的例子是Animal anim = new Dog();与狗延伸动物。 anim(Animal)的引用类型与其对象类型(Dog)不同,因此anim是一个多态引用。
第二部分是动态绑定,它与进行方法调用时实际运行的方法有关。动态绑定意味着实际运行的方法是在引用类型和对象类型之间的类层次结构中最远的方法。您还可以将其视为属于最接近对象类型的类的方法。
类层次结构是您看到的树,其中每个类是其父类的分支。由于Java是单继承(C ++和其他允许您扩展多个类,但在Java中只能扩展一个),因此类层次结构通常是树。请记住,接口和抽象类也包含在类层次结构中,因此接口不一定是树。
多态性和动态绑定经常一起使用的原因是没有动态绑定,多态性没有多大意义。能够运行的方法取决于对象类型而不是引用类型是多态的整个点!
答案 2 :(得分:0)
A是有效的,因为您正在调用已在a2()
中覆盖的B
。 C甚至不会编译,因为类c1()
中不存在A
方法。 E无效,因为类型和实际实例相同,不需要多态。同样,你可以想出其他选择。
答案 3 :(得分:0)
在这个问题中,似乎多态方法调用是对属于对象的方法的调用,该对象在继承链中比调用它的对象的类型更高,而不是写入的方法或者在给定对象的类中重载。
因为c和e在它们自己的类中调用方法,所以它们不会调用链上方的类的方法 - 它们正在调用重载的版本。
希望这有帮助。