我有三个类命名A,B和Test类,每个类有三个方法,如下面的代码所示。现在从Test类我创建一个B类对象并将其放在A中,这是父类。现在A的方法没有被调用但B的方法被调用,为什么?此外,当我将方法设置为静态时,将调用A类的方法。这背后的原因是什么?
class A {
void test1() {
System.out.println("hello");
}
}
class B extends A {
void test1() {
System.out.println("From B class");
}
}
class Test extends B{
public static void main(String args[]){
A obj=new B();
obj.test1();
}
public void test1(){
System.out.println("from Test class");
}
}
答案 0 :(得分:1)
在类定义方法中,子类(即B)中的test1()会覆盖父类中定义的方法(即A)
下面的代码使用类型“A”
的引用创建B的对象实例A obj = new B();
将在实际实例(即B类)上调用所有非静态方法
所有静态方法都将在引用时调用,因此它将引用A类。静态方法不能被覆盖。
答案 1 :(得分:0)
您描述的行为正是它应该如何在Java中,默认情况下方法是虚拟的。您使用的B
实例上的访问权限取决于obj
引用的值的实际类型(B
),而不是引用obj
的类型声明(A
)。如果方法是静态的,则引用特定的类。
答案 2 :(得分:0)
因为你覆盖了方法,从A到B,你需要调查多态
答案 3 :(得分:0)
在运行时,将调用重写的方法。 无法覆盖静态方法,而是可以隐藏子类的父实现。
这将 NOT 取决于引用类型。
A obj = new B();
obj.test1();//Method on B will be invoked.
B obj = new B();
obj.test1();//Still method on B will be invoked.Because at runtime we have B obj
原因:您已在test
类型的对象中为B
方法提供了具体实施。 Please read about Polymorphism。
答案 4 :(得分:0)
第一种情况与动态(或晚期)绑定有关。编译器在运行时计算出对象类型,因此在运行时将选择调用某个对象的某个方法。 第二种情况与静态(或早期)绑定有关。编译器知道静态方法不能被覆盖,因此它可以在编译时绑定。作为与其类相关但不与该类的某个实例相关的静态方法,将调用此类的方法(在您的情况下为A)。