强制调用基类方法

时间:2014-03-07 19:04:16

标签: java

在使用A的实例(来自foo(),而非B调用)时,如何强制调用main的{​​{1}}方法?

我可以发誓我以前见过它。也许是C ++ ??

super

3 个答案:

答案 0 :(得分:2)

  

我可以发誓我以前见过它。也许是C ++?

此处的关键字为virtual。这在C ++和C#等语言中是可行的,因为程序员可以将方法定义为virtual。我已将此代码改编为C ++:

#include <iostream>
using namespace std;

class A {
    public:
        void foo() {
            std::cout << "A" << endl;
        }
};
class B: public A {
    public:
        void foo() {
            std::cout << "B" << endl;
        }
};

int main() {
    // your code goes here
    A* a = new A();
    B* b = new B();
    A* aa = new B();
    a->foo();
    b->foo();
    aa->foo();
    return 0;
}

打印:

A
B
A

现在,使用virtual关键字(仅发布上述示例中的相关代码):

class A {
    public:
        virtual void foo() {
            std::cout << "A" << endl;
        }
};

打印:

A
B
B

在Java中,无法期望这一点,因为默认情况下所有方法都是virtual。所以,对你的问题:

  

在使用A#foo实例而不是通过B来电时,如何强制调用super

在Java中,你不能

答案 1 :(得分:1)

您无法在其他对象中调用超级方法 - 这会违反封装。重点是对象控制其重写方法的作用。例如,您可以覆盖集合的add方法以在某些情况下抛出异常,因此它可以确保只有&#34;有效&#34;项目已添加到集合中。如果打电话者可以用演员来绕过它,那将毫无意义!

对象为自己调用super.foo()的唯一原因是通过使用父实现来启用一个调用。它取决于课堂上的代码,以确保它只能做到明智。同样,要采用add-in-a-collection示例,如果集合覆盖添加,则必须有一些方法将经过验证的项添加到集合中,这将与super.add()一起使用。

答案 2 :(得分:1)

AB的类定义之外,您无法强制运行超类方法。 B已覆盖它,因此如果A引用引用B,则B的{​​{1}}方法将运行并打印foo。这些类之外的任何更改都不能更改此多态行为 - 实际的"B"对象将打印B

要强制它打印"B",您必须更改"B" / A类中的代码。您可以在B中将foo标记为final,以便A无法覆盖它。 (可选)您可以选择在B的{​​{1}}中A覆盖另一个方法调用,以便foo可以保证B将被打印,但是A在调用"A"时仍然可以做任何事情。

B

此处,foo将始终打印static class A { public final void foo() { System.out.println("A"); // Optional. bar(); } protected void bar() {} } static class B extends A { // Can't override "foo" now -- can't prevent "A" from being printed. //public void foo() { // System.out.println("B"); //} // Optional. @Override protected void bar() { System.out.println("B"); } } ,但foo也可以打印"A",如果它真的需要。