为什么按此顺序输出?

时间:2012-08-06 18:44:18

标签: java method-overriding

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()方法背后的原因吗?如果没有,那么这个输出顺序的原因是什么?

5 个答案:

答案 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。它的作用就像一个水果,但也做一些香蕉不会做的苹果。因此BA的行为方式相同,但也可以执行其他操作。因此,在您的示例中,您的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()执行相同的操作。