刚刚在我正在阅读的关于OOP的书中看到了这句话,
只允许孩子补充 功能和添加功能。 永远不允许儿童移除 功能。如果你确实找到了 孩子需要删除功能, 这表明孩子 应该出现在父母之前 继承层次结构!
但我的问题是,这不是最重要的吗?
答案 0 :(得分:4)
您可以通过覆盖删除功能。但通常你用它来改变行为。让班级表现得应该如此。
如果删除了行为,那么这往往是一个糟糕的课程设计的标志。
答案 1 :(得分:3)
孩子无法删除功能 - 它可以改变它,但是你不能将公共方法设为私有。
继承点是你可以像对待父母那样处理孩子。如果你有一个'Person'超类是一个'Employee'子类,那么Employee类没有没有pache()方法就没有意义。
答案 2 :(得分:1)
覆盖方法时,可以在覆盖期间的某个时刻调用父实现,因此使用覆盖来向父实现添加功能。
答案 3 :(得分:1)
没有。实际上你会增加功能(以负面的方式)
假设您的新功能是“什么都不做”,但代码的客户端看到的方法仍然是接口
您不能拥有删除其父级方法的子类。
这是可能的
class Parent {
public void method_one(){
print "Hello";
}
}
class Child extends Parent {
public void method_one(){
// do nothing
}
}
但这不是:
class Parent {
public void method_one(){
print "Hello";
}
}
class Child extends Parent {
// Attempt remove the method visibility, thus remove funcionality
private void method_one(){
// do nothing
}
}
答案 4 :(得分:0)
这就是为什么覆盖(以及一般来说,任何虚拟成员)都应该非常谨慎地完成的事情...... 实际上,通常,在重写时,您应该尝试对基类和派生类进行编码,以便派生类实现首先调用基本实现,然后执行它的附加功能......
但是这个原则并没有在OO语言中强制实施,而且经常被违反......
为什么这是不好的例子
想象一下,你有CompanyA设计类型(类)电话
namespace CompanyA {
class Phone {
public void Dial() {
// do work to dial the phone here
}
}
}
没有iagine公司B定义另一种类型BetterPhone,它使用公司A的电话作为基本类型......
namespace CompanyB {
class BetterPhone: CompanyA.Phone {
public void Dial() {
Console.WriteLine("BetterPhoneDial");
EstablishConenction();
base.Dial();
}
}
}
现在,其他公司(公司C,D等)正在使用其电话类的CompanyA决定在类中建立连接是有用的,并修改CompanyA.Phone,添加EsatblishCOnnection()方法也许,可能有不同的实现......在我们使用“new”关键字之前,这个场景会破坏CompanyB的BetterPhone类......这是他们第一次尝试使用新的基类。
答案 5 :(得分:0)
如果您的孩子需要删除父级的功能,则必须将父级声明为Interface。 因为Interface是定义必须遵守其实现者的契约的机制。
E.g。
public interface IContract
{
void DoWork();
}
public class BaseContract: IContract
{
public virtual void DoWork()
{
//perform operation A
}
}
现在,如果要声明新的EnhancedContract类,可以从BaseContract或IContract派生它,具体取决于要求。 如果要对base的操作A执行其他操作,可以从BaseContract继承它,如下所示。
public class EnhancedContract: BaseContract
{
public override void DoWork()
{
//perform operation B
base.DoWork();
//perform operation C
}
}
但如果您对在EnhancedContract的DoWork方法中执行操作A不感兴趣,那么从IContract继承它。
这确保了EnhancedWork将执行DoWork(),但不保证在其中执行'操作A'。
public class EnhancedWork:IContract
{
public void DoWork()
{
//perform operation D
}
}
这对于提示非常重要,因为它会阻止用户进行以下投射。
EnhancedContract e = new EnhancedContract();
BaseContract b = e;
我相信所有这些操作在理解Open Closed principle,Liskov substitution principle时非常重要。
继承的Thumb规则是“将其他功能添加到现有功能中”。