在使用A
的实例(来自foo()
,而非B
调用)时,如何强制调用main
的{{1}}方法?
我可以发誓我以前见过它。也许是C ++ ??
super
答案 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)
从A
和B
的类定义之外,您无法强制运行超类方法。 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"
,如果它真的需要。