gpt4 book ai didi

c++ - 对象设计的抽象

转载 作者:行者123 更新时间:2023-11-30 04:29:19 24 4
gpt4 key购买 nike

如果我们只在父类(super class)中使用 protected 和 private 访问修饰符,继承如何破坏封装?

有时声称继承公开父类(super class)实现。如果成员变量被声明为私有(private),这肯定不是真的吗?如果这是指在父类(super class)中所做的更改会破坏子类,这不会影响非继承吗?

在公开底层实现方面,我也看不出组合有何不同?我们只能使用组合方法来使用公共(public)函数——这肯定会暴露更多吗?

最佳答案

派生类可以访问基类的部分实现。例如。如果您对基类中的任何或所有成员使用 protected,那么基类将无法强制执行它自己的不变量。这可能会破坏基类的功能。更改字段名称或删除或添加字段名称可能会导致派生类出现问题,除非它们是私有(private)的,因此再次公开实现可能会破坏原本正确的代码。

模板模式是一种故意暴露基类部分实现的方式,它是故意的并不意味着它不暴露(部分)实现。使用组合(策略)来获得相同的结果(通常与开放/封闭原则相关)具有更松散的耦合。例如。如果您更改其中一个虚拟方法的签名(例如名称)或添加在模板模式中使用的新(抽象)方法,将级联更改为所有派生类。在组合的情况下,您可以更改进行组合的类中所有方法的名称,而无需更改您组合的任何类。您还可以在不更改其他类的情况下向算法添加另一个步骤(只要您组成的部分之一已经支持此功能)

另一种看待为什么虚拟方法会破坏封装的方式:

上这门课

class ArrayPrinter{
private bool CanContinue<T>(T[] array, int newIndex){
return newIndex<array.Length;
}

public void Print<T>(T[] array){
for(var i = 0;CanContinue(array,i);i++){
Console.WriteLine(string.Format("{0}",array[i]);
}
}
}

在上面的示例中,我们可以确定 Print 的实现不会导致索引越界(线程安全除外),并且数组的所有元素都将被打印(除非 Console.WriteLine 或 string.Fromat 失败).但是,如果我们将 CanContinue 的签名更改为以下内容

   protected virtual bool CanContinue<T>(t[] array, int newIndex)

ArrayPrinter 将正常工作不再有任何保证。我们已经可以从类的外部更改 Print 的实现,因此破坏了封装。有些人可能会争辩说,如果你公开你的领域,你只会破坏封装。我不同意下面的代码遇到与上面完全相同的问题,尽管它公开了一个字段(通过一个属性,只是为了表明隐藏你是属性后面的字段并不能确保你没有封装破损)

class ArrayPrinter<T>{
private Func<T[],int,bool> _canContinue;
protected Func<T[],int,bool> CanContinue{
get{
return _canContinue ?? canContinue;
}
set{
_canContinue = value;
}
}
private bool canContinue(T[] array, int newIndex){
return newIndex<array.Length;
}

public void Print<T>(T[] array){
for(var i = 0;CanContinue(array,i);i++){
Console.WriteLine(string.Format("{0}",array[i]);
}
}
}

关于c++ - 对象设计的抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9463966/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com