2011-08-19 63 views
2

我知道这3个概念。覆盖,超载和隐藏在OOP

但我记得还有另外一个定义: 假设一个基类有2个虚拟方法:Foo()和Foo(int a)。 是否有任何规则,当派生类重写Foo(int a)必须重写Foo的所有其他重载?

它在Java吗?我相信它不存在于C#中。

感谢

回答

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 
    } 
} 

旁白:

我希望你不是指如果你扩展一个抽象类扩展一个抽象类 - ,你需要重写所有抽象方法否则你的类必须声明为abstract 。

虽然实现的接口的所有方法都需要实现。

+0

您可以在C++中使用using语句来解析添加unoverriden方法,而不必重写它们。 –

+0

所以名称隐藏在可能只在cpp中,而不是在c#和java中?你会如何配合Chris Thompson的回答?在OO语言中是cpp。 –

+0

发现这个伟大的链接:http://www.ikriv.com/en/prog/info/dotnet/Overloading.html –

6

没有,有没有这样的规则,至少不是在Java中。这种规则将是令人难以置信的限制,因为有时一个子类只能有一个新的执行这些重载之一的,等

+0

“这样的规则将会非常有限” - 我同意,但它存在于cpp中。见Dhruv Gairola的答案。 –

4

这不是Java中的规则。你在想一个界面吗?如果一个类实现了一个接口,它必须实现接口上声明的每个方法。

+1

+1因为比我更快地指出接口! –

2

否实际上,这不适用于Java。但是,如果你实现一个接口,那么你需要实现其中的所有方法。但是当你使用extends即继承,那么你重写你想要的方法,在这种情况下,Foo(int x)与Foo()不同,不管它们的返回类型是否相同。

+0

+1用于思考相同的方向 –

0

但是,如果你想创建非抽象类(扩展基类),你必须实现所有的抽象方法。

0

只是添加到其他人已经说过的内容,在java中,每种方法都使用其完整签名(包括其返回类型,名称和参数)进行明确标识。所以当你定义一个抽象方法(虚函数)时,你将它定义为只有该函数具有其签名的抽象。

无论如何,你可以尝试这个在你的IDE的乐趣,并会在一分钟内得到答案。 :P