Java多态性问题

Java多态性问题,java,polymorphism,scjp,Java,Polymorphism,Scjp,对于SCJP,大多数情况下都会询问下面这样的问题,以找到多态方法调用的有效示例。但我们到底应该寻找什么来发现它是否具有多态性 abstract class A { abstract void a1(); void a2() { } } class B extends A { void a1() { } void a2() { } } class C extends B { void c1() { } } 以及: 多态方法调用的四个有效示例是什么?(

对于SCJP,大多数情况下都会询问下面这样的问题,以找到多态方法调用的有效示例。但我们到底应该寻找什么来发现它是否具有多态性

 abstract class A {
   abstract void a1();
   void a2() { }

 }
 class B extends A {
   void a1() { }
   void a2() { }
 }
 class C extends B { 
   void c1() { }
 }
以及:

多态方法调用的四个有效示例是什么?(选择四个。)


答:A、B、D、FA是有效的,因为您正在调用
a2()
,该函数已在
B
中被重写。C甚至不会编译,因为类
A
中不存在
c1()
方法。E无效,因为类型和实际实例相同,不需要多态性。类似地,您也可以找到其他选项。

A是有效的,因为您正在调用
a2()
,它已在
B
中被覆盖。C甚至不会编译,因为类
A
中不存在
c1()
方法。E无效,因为类型和实际实例相同,不需要多态性。类似地,您可以找到其他选项。

在这个问题中,多态方法调用似乎是对属于继承链中高于调用它的对象类型的对象的方法的调用,而不是在给定对象的类中写入或重载的方法

因此,由于c和e在它们自己的类中调用方法,它们不是调用链上更高级别的类的方法,而是调用重载版本


希望这有帮助。

在这个问题中,多态方法调用似乎是对属于继承链中高于调用它的对象类型的对象的方法的调用,而不是在给定对象的类中编写或重载的方法

因此,由于c和e在它们自己的类中调用方法,它们不是调用链上更高级别的类的方法,而是调用重载版本

希望这有帮助。

答案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.
答案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.

我是美国一所主要大学的助教,教授Java课程,我总是这样向学生解释多态性:

实际上这里发生了两件非常相似的事情:多态性和动态绑定

多态性仅定义为引用类型和对象类型不同时的多态性。经典的例子是anim=newdog();和狗一起伸展的动物。anim(动物)的参考类型与其对象类型(狗)不同,因此anim是多态参考

第二部分是动态绑定,它与在进行方法调用时实际运行的方法有关。动态绑定意味着实际运行的方法是引用类型和对象类型之间的类层次结构中最底层的方法。您还可以将其视为属于最接近对象类型的类的方法

类层次结构是您看到的树,其中每个类都是其父类的一个分支。由于Java是单继承(C++和其他语言允许扩展多个类,但在Java中只能扩展一个),因此类层次结构通常是一个树。请记住,接口和抽象类也包含在类层次结构中,因此由于接口的原因,它不一定是树


多态性和动态绑定经常一起使用的原因是,没有动态绑定,多态性就没有多大意义。能够让运行的方法依赖于对象类型而不是引用类型是多态性的关键所在

我是美国一所主要大学的助教,教授Java课程,我总是这样向学生解释多态性:

实际上这里发生了两件非常相似的事情:多态性和动态绑定

多态性仅定义为引用类型和对象类型不同时的多态性。经典的例子是anim=newdog();和狗一起伸展的动物。anim(动物)的参考类型与其对象类型(狗)不同,因此anim是多态参考

第二部分是动态绑定,它与在进行方法调用时实际运行的方法有关。动态绑定意味着实际运行的方法是引用类型和对象类型之间的类层次结构中最底层的方法。您还可以将其视为属于最接近对象类型的类的方法

类层次结构是您看到的树,其中每个类都是其父类的一个分支。由于Java是单继承(C++和其他语言允许扩展多个类,但在Java中只能扩展一个),因此类层次结构通常是一个树。请记住,接口和抽象类也包含在类层次结构中,因此由于接口的原因,它不一定是树


多态性和动态绑定经常一起使用的原因是,没有动态绑定,多态性就没有多大意义。能够让运行的方法依赖于对象类型而不是引用类型是多态性的关键所在

这就是为什么认证是愚蠢的。为什么他们不问你方法调用会做什么,而不是哪些是“多态的”?我是一个相当好的JavaP
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.