如何通过扩展实例调用BaseClass方法

时间:2018-01-19 06:51:31

标签: java inheritance

请考虑以下课程:

public interface BaseInterface {

    void method1();
    void method2();
    void method3();
}


public class BaseClass implements BaseInterface {

    @Override
    public void method1() {
        System.out.println("BaseClass.method1 IN");
        this.method3();
        System.out.println("BaseClass.method1 OUT");
    }

    @Override
    public void method2() {
        System.out.println("BaseClass.method2 IN");
        System.out.println("BaseClass.method2 OUT");
    }

    @Override
    public void method3() {
        System.out.println("BaseClass.method3 IN");
        System.out.println("BaseClass.method3 OUT");
    }
}


public class ChildClass extends BaseClass {

    @Override
    public void method1() {
        System.out.println("ChildClass.method1 IN");
        super.method1();
        System.out.println("ChildClass.method1 OUT");
    }

    @Override
    public void method2() {
        System.out.println("ChildClass.method2 IN");
        super.method2();
        System.out.println("ChildClass.method2 OUT");
    }

    @Override
    public void method3() {
        System.out.println("ChildClass.method3 IN");
        System.out.println("ChildClass.method3()");
        System.out.println("ChildClass.method3 OUT");
    }
}

在这种情况下,如果我创建ChildClass的实例:

BaseInterface cc1 = new ChildClass();

然后运行此类的method1

cc1.method1();

它将返回以下输出:

ChildClass.method1 IN
BaseClass.method1 IN
ChildClass.method3 IN
ChildClass.method3()
ChildClass.method3 OUT
BaseClass.method1 OUT
ChildClass.method1 OUT

因此,当我从超类(this.method3())调用method3()(或仅BaseClass)时,method3的{​​{1}}会被执行。我知道这是预期的行为,但我只是想知道如何在此设置中仍然可以调用ChildClass?这可能吗?

请注意,这是一个纯粹的理论问题,我理解实际上我可能应该首先实例化一个BaseClass.method3实例。这是解决这个问题的唯一方法吗?

2 个答案:

答案 0 :(得分:3)

解决方法是在BaseClass中创建一个私有方法,然后从method3调用此方法:

public class BaseClass implements BaseInterface {

    @Override
    public void method1() {
        System.out.println("BaseClass.method1 IN");
        this.internalMethod3();
        System.out.println("BaseClass.method1 OUT");
    }

    @Override
    public void method2() {
        System.out.println("BaseClass.method2 IN");
        System.out.println("BaseClass.method2 OUT");
    }
    private void internalMethod3() {

        System.out.println("BaseClass.method3 IN");
        System.out.println("BaseClass.method3 OUT");
    }

    @Override
    public void method3() {
        this.internalMethod3();
    }
}

会完成同样的事情

此外,对How to call a superclass method using Java reflection中发布的解决方案的评论是,如果可能,您不应该这样做。重构你的代码将其分解为更小的函数将是这里的方法。在制定这个问题时,重构代码没有问题。

答案 1 :(得分:2)

这是可覆盖方法的工作方式:在运行时,调用运行时对象的方法 在这里this.method3();this是运行时对象,method3()是可覆盖的方法。所以发生了多态性。

要实现预期的行为,您应该使用不允许覆盖的单个访问修饰符:private。 将method3()实施委托给private方法,现在您可以从method1()访问它:

@Override
public void method1() {
    System.out.println("BaseClass.method1 IN");
    method3Internal();
    System.out.println("BaseClass.method1 OUT");
}

@Override
public void method3() {
    method3Internal();
}

private void method3Internal() {
    System.out.println("BaseClass.method3 IN");
    System.out.println("BaseClass.method3 OUT");
}