2
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();
    }
}

输出是:

showname child 中的
methodA methodB

问题 :-

由于在覆盖中,考虑了对象类型。是不是 B 类的 showName() 方法被称为不是 A 类的原因?如果不是,那么这个输出顺序的原因是什么?

4

5 回答 5

4

您创建了一个 B 类型的对象,因此对该对象调用的所有方法都将在 B 类上。如果 B 类没有实现某些方法(如方法 A),那么 Java 会尝试在父类 (A) 中查找方法。您应该阅读面向对象语言中的多态性:

http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming

于 2012-08-06T18:55:33.810 回答
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()。它们在 class 中被覆盖B,而 object a 是instanceof B,所以这就是使用它们(来自 B 类)的原因。

编辑如评论中所述:

@Jaikrat Singh,B 类仍然是 A 类(它的子类,但继承是类型的关系: IS-A )。类B继承了A类的方法。所以它也有methodA。所以最好说,这methodA也是从类中调用的,B但使用的是默认代码 - 与类中提供的相同A

于 2012-08-06T18:54:59.720 回答
2

当对象“a”被声明为类型 A 时,它被实例化为类型 B。多态性导致调用实例类型的方法而不是声明类型的方法,因此因为它在内部属于类型 B,所以 showName( ) 类 B 的方法被调用。

于 2012-08-06T18:55:11.690 回答
2

当你调用时a.methodA(),由于你的对象类型是B,它会methodA先查找B。由于 中没有这样的方法B,它会在它的超类中寻找这个方法,即A. methodA在 class中找到A,它将开始执行。

执行时,它会打印methodA并开始寻找下一个被调用的方法(methodB),该方法在B类中实现,然后它会打印methodB

下一个调用的方法是showName,它在两个类中都实现了。由于 Java 将开始在与对象类型相同的类中寻找实现,因此它会在第一次尝试中找到 class B

主要规则很简单:Java 将首先尝试在对象类型类(运算符后面的名称new)中查找方法。如果该方法没有在那里实现,它将开始向上通过超类。

于 2012-08-06T19:00:07.350 回答
0

你有抽象类A,它被扩展了B。扩展相当于B "is a" A. 例如,如果苹果扩展水果,apple 'is a' fruit. 它的作用就像水果,但也能做香蕉做不到的苹果事情。所以B行为与 相同A,但也可以做其他事情。因此,在您的示例中,您B覆盖了两种方法。B默认情况下,每个对象都会调用它们。为了A从 a 访问 's 方法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().

于 2012-08-06T18:56:09.737 回答