abstract class A {
public void methodA() {
System.out.println("methodA");
methodB();
showName();
}
public abstract void methodB();
public void showName() {
System.out.println("in showname base");
}
}
class B extends A {
public void methodB() {
System.out.println("methodB");
}
public void showName() {
System.out.println("in showname child");
}
}
public class SampleClass {
public static void main(String[] args) {
A a = new B();
a.methodA();
}
}
输出是:
了methodA 的methodB
在showame孩子
问题: -
由于在重写时,会考虑对象类型。这是B类的showName()方法背后的原因吗?如果没有,那么这个输出顺序的原因是什么?
答案 0 :(得分:4)
您创建了一个B类型的对象,因此调用该对象的所有方法都将在B类上。如果B类没有实现某些方法(如methodA),那么Java会尝试在父类中找到一个方法(A )。您应该阅读面向对象语言中的多态性:
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
答案 1 :(得分:3)
很简单:
A a = new B();
a.methodA();
这里知道a是B
类的对象,因此如果没有覆盖,则可以在类B
中使用可以在类B
中覆盖的每个方法,然后从必须使用课程A
。
考虑顺序:
您调用声明为的methodA
:
public void methodA() {
System.out.println("methodA");
methodB();
showName();
}
从methodA()
内部调用methodB()
和showName()
。它们在类B
中被覆盖,对象a被instanceof B
覆盖,这就是它们(来自B类)被使用的原因。
编辑,如评论中所述:
@Jaikrat Singh,B级仍然是A类(它的孩子,但继承是类型的关系:IS-A)。类B
继承了A
类的方法。所以它也有methodA
。所以最好说,methodA
也是从类B
调用的,但是默认代码 - 与类A
中提供的相同
答案 2 :(得分:2)
虽然对象'a'被声明为类型A,但它被实例化为类型B.多态性导致实例类型的方法被调用而不是声明类型的方法,因为它在内部是类型B,调用类B的showName()方法。
答案 3 :(得分:2)
当您致电a.methodA()
时,由于您的对象类型为B
,因此它会在methodA
中首先查找B
。由于B
中没有这样的方法,它将在其超类中查找此方法,即A
。在课程methodA
中查找A
,它将开始执行。
执行时,它将打印methodA
并开始寻找下一个被调用的方法(methodB
),该方法在B
类中实现,然后它将打印methodB
下一个被调用的方法是showName
,它在两个类中实现。由于Java将开始在与对象类型相同的类中查找实现,因此它将在第一次尝试时找到,即类B
。
主要规则很简单:Java将首先尝试在对象类型类(在new
运算符之后的名称)中查找该方法。如果没有在那里实现该方法,它将开始通过超类。
答案 4 :(得分:0)
您有抽象类A
,它由B
扩展。延伸相当于B "is a" A
。例如,如果苹果延长了果实,apple 'is a' fruit
。它的作用就像一个水果,但也做一些香蕉不会做的苹果。因此B
与A
的行为方式相同,但也可以执行其他操作。因此,在您的示例中,您的B
会覆盖两种方法。默认情况下,每个B
对象都会调用它们。要从A
访问B
方法,您需要使用关键字super
。
它是多态性(java编程中的一个关键点)的一部分,一个对象首先会找到它自己的任何方法(即使它们是从父级覆盖的)然后它会爬上继承树来找到一个方法不是直接在那个班级。
对于你的例子:
public void methodA() {
System.out.println("methodA"); //This prints no problem.
methodB(); //This searches the "B" class for a method called "methodB" If it can't find it, it checks its parent for a "methodB"
showName();//This searches the "B" class for a method called "showName" If it can't find it, it checks its parent for a "showName"
}
调用上面的代码。你知道的很多(从你做的其他评论,我假设这一点。)一旦调用行methodB()
,你的类型B
的对象检查整个B文件的方法。如果该方法不存在,它只会跳到A
。然后它会对showName()
执行相同的操作。