我知道这三个概念。
但我记得还有另一个定义: 假设基类有2个虚方法:Foo()和Foo(int a)。 是否有任何规则,当派生类重写Foo(int a)时必须覆盖Foo的所有其他重载?
是Java吗?我相信它在C#中不存在。
由于
答案 0 :(得分:6)
不,没有这样的规则,至少在Java中没有。这样的规则将具有令人难以置信的限制,因为有时子类只有其中一个重载的新实现等。
答案 1 :(得分:4)
这不是Java中的规则。你在想一个界面吗?如果一个类实现了一个接口,那么它必须具有在接口上声明的每个方法的实现。
答案 2 :(得分:2)
<强> C ++:强>
您所指的是C ++中的name hiding。当你有一个具有覆盖方法的类,并且你扩展这个类覆盖其中一个覆盖的方法时,你需要覆盖所有重载的方法。如果没有,在扩展类中调用非重写的重载将不起作用。
例如:
class Base {
public:
virtual void A (int);
virtual void A (int, int);
};
void Base::A(int i) {
std::cout << “Hi\n”;
}
void Base::A (int i, int j) {
std::cout << “Bye!!\n”;
}
假设您只覆盖其中一个方法:
class Sub: public Base {
public:
void A(int);
};
void Sub::A(int i) {
std::cout << “Hey, La!\n”;
}
void main () {
Sub a;
a.A(1);
a.A(1, 1);//won't compile
}
第二次通话无效,因为A(int, int)
不可见。这是名字隐藏。
如果您想绕过这一点,可以使用using
关键字,如下所示:
class Sub: public Base {
public:
void A(int);
using Base::A;
};
void Sub::A(int i) {
std::cout << “Hey, La!\n”;
}
void main () {
Sub a;
a.A(1);
a.A(1, 1);//will compile
}
Java:
Java没有这样的概念。你可以自己尝试一下。请注意,根据虚拟C ++方法,默认情况下所有Java方法都是虚拟的。
public class Base {
public void A() {
System.out.println("Hi");
}
public void A(int i, int j) {
System.out.println("Bye");
}
}
public class Sub extends Base {
public void A() {
System.out.println("Hey, La!");
}
}
public class Test {
public static void main(String[] args) {
Sub a = new Sub();
a.A();
a.A(1, 1);//perfectly fine
}
}
<强>除了:强>
我希望你不是指扩展一个抽象类 - 如果扩展一个抽象类,你需要覆盖所有抽象方法,否则你的类必须被声明为抽象类。
实现接口的所有方法都需要实现。
答案 3 :(得分:2)
否实际上不适用于Java。但是,如果实现接口,则需要实现其中的所有方法。但是当你使用extends
即继承时,你会覆盖你想要的方法,在这种情况下,Foo(int x)与Foo()不同,无论它们的返回类型是否相同。 / p>
答案 4 :(得分:0)
但是,如果要创建非抽象类(扩展基类),则必须实现所有抽象方法。
答案 5 :(得分:0)
只是为了添加其他人已经说过的内容,在java中,使用包含其返回类型,名称和参数的完整签名来清楚地识别每个方法。所以当你定义一个抽象方法(虚函数)时,你只能将它定义为具有签名的那个函数的抽象。
无论如何你可以在你的IDE中尝试这个以获得乐趣,并且会在一分钟内得到答案。 :P