我在A类中创建了两个方法,在B类中重写,如下所示。我有一些与动态多态和覆盖有关的问题。
这是我的代码,其中B类扩展了A类。
public class A {
public void methoda()
{
System.out.println("a");
}
public void methodb()
{
System.out.println("aaa");
}
public static void main(String[] args) {
B a =new B();
A b=a;
b.methoda();
}
}
public class B extends A{
@overrides
public void methoda()
{
System.out.println("A");
}
@overrides
public void methodb()
{
System.out.println("g");
}
}
这里我重写了两个方法,当使用超类引用时,调用的方法取决于运行时决定的对象类型,是动态多态的一个例子。
但是如果我对子类对象使用子类引用并覆盖该方法,那么将在运行时重写被覆盖并且是动态多态的情况,或者仅在编译时解析,因为对象类型和引用是相同类型的不是动态多态的情况吗?
重写和动态多态同时发生吗?
答案 0 :(得分:3)
我不确定我是否理解这个问题,但多态方法总是在运行时解决。执行的方法是对象的具体运行时类型之一。引用它的变量的声明类型并不重要。
狮子是狮子,如果你把它称为动物,它就会一直咆哮。
答案 1 :(得分:1)
首先,(subtype) polymorphism始终是动态的(即在运行时),因此“动态”修饰符是多余的,除非它用于区分ad-hoc polymorphism或parametric polymorphism。
其次,@ Override(不是 @overrid )注释不是强制性的(实际上它只是由Java 5.0引入),尽管它建议更具可读性(明确显示重写方法)等等robust(编译器将检查拼写方法)代码。
总之,方法覆盖是OOP语言的关键特性,并且在编译时检查注释@Override,而在运行时解析多态行为。
答案 2 :(得分:0)
如果您通过子类引用则无关紧要。重要的是创建的实例。如果您的实例是从B创建的,那么您将获得B的结果。
答案 3 :(得分:0)
如果使用子类对子类引用的引用,则不需要重写。只有当基类的指针指向其子类之一的对象并且此指针调用基类的方法时才会发生覆盖。但是实际的方法来执行子类的方法。
答案 4 :(得分:0)
class Bike {
void run() {
System.out.println("running");
}
}
class Splender extends Bike {
void run() {
System.out.println("Bike is running");
}
public static void main(String args[]) {
Bike a = new Bike();
a.run(); //output: running
Bike b = new Splender();
b.run(); //output: Bike is running
}
}
这里Superclass(Bike)引用指向子类对象。对象在运行时创建,而不是在编译时创建。无论是否,
1)引用变量和对象类型相同或
2)引用变量是超类类型,对象是子类类型。
在上面的示例中,编译器无法确定对象类型,因为Splender的实例也是Bike的实例。 JVM在运行时根据创建的对象类型调用该方法。这两种情况都是动态多态性而不是编译时多态性。