Java 运行时多态性的方法访问
Java method access on runtime polymorphism
我有以下 java 代码。
class A {
public void method1() {
System.out.println("A 1");
method2();
}
public void method2() {
System.out.println("A 2");
}
}
class B extends A {
@Override
public void method2() {
System.out.println("B 2");
}
}
public class Tester {
public static void main(String[] args) {
A a = new B();
a.method1();
}
}
它打印
A 1
B 2
- 调用 a.method1() 时在运行时究竟发生了什么?
- 如何从父级调用派生方法?
- 是看对象和方法名字符串调用
运行时的方法?
- 默认是调用this.method2()吗?
What exactly happens at runtime when a.method1() is called?
ClassA 调用的方法 1()。
How is the derived method getting called from the parent?
由于您已经在 class B 中验证了方法 method2
,因此这将是将在运行时调用的方法。
Is it looking at the object and the method name string and calling the method during runtime?
不要在这里混淆。当你写
A a = new B();
来自 Class 的方法如果被验证则调用 B,否则调用 A 的方法。
Is it calling this.method2() by default?
再说一遍,这不是违约。如果你 ovveride 它会从 B 调用。如果你不 ovveride,它会从 A
调用
由于方法 method1(...)
从未被覆盖,B 继承了 A 的 method1()
并且它被调用就好像它是在 B 中定义的一样。
由于 method1()
调用 method2()
在 B 中定义的覆盖方法 method2()
被调用,当使用 B 构造函数创建实例时。
如果您创建另一个实例,使用 A 构造函数,您将不会获得 B 中定义的覆盖 method2(...)
,而是获得 A 中定义的原始 method2(...)
。
因为您的对象实际上是继承自 A
的 B
类型。在你的 B
的 class 中你覆盖了 method2 这就是它调用 B.method2()
的原因
A a = new B();
要从 A
调用 method2
,请使用:
A a = new A();
当 B 类型的对象被初始化时,它是 class B 的实例,即使它被隐式转换为 A 类型的对象。
因此,当您调用 a.method1()
时,因为 method1()
未在 class B 中定义,它会调用基 class 中定义的方法。然后反过来,当调用 method2()
时,它在 class B 中定义,并且由于对象是 B 类型,因此调用 class B 中的方法。
您已经创建了子对象 class 和一个引用类型的对象。
引用的类型为 Parent(向下转换)
当你调用引用的任何方法时,都会调用引用类型的方法。但是如果该方法在引用类型中不可用,它将从父类(继承)中调用。
在您的示例中,编译器检查对象 A 中的 method1 并在那里找到它。
其次,当 method2 被调用时,它是从当前对象(对象 B 而不是引用 A)调用的。
请注意,当您从 A 的引用调用它时,方法 2 被覆盖,它将从对象 A(父)调用方法,如果您从引用 B 调用它,它将从对象 B(子)调用。
这里要记住的关键点是引用和对象的区别。它们都是不同的实体。
*如果你从抽象 class 调用一个具体方法而调用相同 class 的抽象方法,也会发生同样的事情。子 class 的实现方法将被调用。
我有以下 java 代码。
class A {
public void method1() {
System.out.println("A 1");
method2();
}
public void method2() {
System.out.println("A 2");
}
}
class B extends A {
@Override
public void method2() {
System.out.println("B 2");
}
}
public class Tester {
public static void main(String[] args) {
A a = new B();
a.method1();
}
}
它打印
A 1
B 2
- 调用 a.method1() 时在运行时究竟发生了什么?
- 如何从父级调用派生方法?
- 是看对象和方法名字符串调用 运行时的方法?
- 默认是调用this.method2()吗?
What exactly happens at runtime when a.method1() is called?
ClassA 调用的方法 1()。
How is the derived method getting called from the parent?
由于您已经在 class B 中验证了方法 method2
,因此这将是将在运行时调用的方法。
Is it looking at the object and the method name string and calling the method during runtime?
不要在这里混淆。当你写
A a = new B();
来自 Class 的方法如果被验证则调用 B,否则调用 A 的方法。
Is it calling this.method2() by default?
再说一遍,这不是违约。如果你 ovveride 它会从 B 调用。如果你不 ovveride,它会从 A
调用由于方法 method1(...)
从未被覆盖,B 继承了 A 的 method1()
并且它被调用就好像它是在 B 中定义的一样。
由于 method1()
调用 method2()
在 B 中定义的覆盖方法 method2()
被调用,当使用 B 构造函数创建实例时。
如果您创建另一个实例,使用 A 构造函数,您将不会获得 B 中定义的覆盖 method2(...)
,而是获得 A 中定义的原始 method2(...)
。
因为您的对象实际上是继承自 A
的 B
类型。在你的 B
的 class 中你覆盖了 method2 这就是它调用 B.method2()
A a = new B();
要从 A
调用 method2
,请使用:
A a = new A();
当 B 类型的对象被初始化时,它是 class B 的实例,即使它被隐式转换为 A 类型的对象。
因此,当您调用 a.method1()
时,因为 method1()
未在 class B 中定义,它会调用基 class 中定义的方法。然后反过来,当调用 method2()
时,它在 class B 中定义,并且由于对象是 B 类型,因此调用 class B 中的方法。
您已经创建了子对象 class 和一个引用类型的对象。 引用的类型为 Parent(向下转换)
当你调用引用的任何方法时,都会调用引用类型的方法。但是如果该方法在引用类型中不可用,它将从父类(继承)中调用。
在您的示例中,编译器检查对象 A 中的 method1 并在那里找到它。 其次,当 method2 被调用时,它是从当前对象(对象 B 而不是引用 A)调用的。
请注意,当您从 A 的引用调用它时,方法 2 被覆盖,它将从对象 A(父)调用方法,如果您从引用 B 调用它,它将从对象 B(子)调用。
这里要记住的关键点是引用和对象的区别。它们都是不同的实体。
*如果你从抽象 class 调用一个具体方法而调用相同 class 的抽象方法,也会发生同样的事情。子 class 的实现方法将被调用。