Oop 破坏继承的封装?
人们说继承破坏了封装,我同意这一点。他们说委派更好——尽管委派中的修饰语也可以是公共的/受保护的Oop 破坏继承的封装?,oop,encapsulation,access-modifiers,Oop,Encapsulation,Access Modifiers,人们说继承破坏了封装,我同意这一点。他们说委派更好——尽管委派中的修饰语也可以是公共的/受保护的 那么,继承破坏封装的真正原因是因为来自超类的公共/受保护修饰符的“连锁反应”效应被暴露给任何扩展当前子类的新类吗?是的。因为它让派生类访问基类的成员(取决于哪种语言和哪种继承),所以据说它破坏了封装。依我看,这只有在你坚持用最严格的术语来封装的情况下才行。可以合理地说,您接受派生类作为基类的扩展,因此在某种程度上是相关的,而不是真正破坏封装。 纯粹主义者不会同意这一点 查看并搜索“中断”以获得学术解
那么,继承破坏封装的真正原因是因为来自超类的公共/受保护修饰符的“连锁反应”效应被暴露给任何扩展当前子类的新类吗?是的。因为它让派生类访问基类的成员(取决于哪种语言和哪种继承),所以据说它破坏了封装。依我看,这只有在你坚持用最严格的术语来封装的情况下才行。可以合理地说,您接受派生类作为基类的扩展,因此在某种程度上是相关的,而不是真正破坏封装。 纯粹主义者不会同意这一点
查看并搜索“中断”以获得学术解释。这取决于我们如何设计类。在设计类时,我们应该牢记原则。当我们谈论封装时,我们谈论的是修改,当我们谈论继承时,我们谈论的是扩展应用程序,作为设计者,我们应该选择我们应该保护哪些内容不被修改(在我们的类中使用私有修饰符),从而封装我们的类,以及为将来扩展保留的类的开放面(受保护的membmers)。(可以将其视为.net语言中的一个部分概念,即每个类可以分离为不同的文件,因此程序员可以扩展其中一些类,而其他一些类则使用代码生成工具生成)我认为,从我的角度来看,如果在基类或超类中添加新方法,它就会中断。如果
A
是B
的子类,即使A
没有任何修改,B
中的更改也会中断A
(这称为连锁反应)
示例:假设A
通过首先验证每个方法中的输入参数来覆盖B
中的所有方法(,出于安全原因)。如果向B
添加新方法,并且A
未更新,则新继承的方法将引入安全漏洞
要摆脱继承中的陷阱,请支持或使用“组合”而不是继承,使用简单聚合而不是继承,下面是一个示例:
设想两个类,Person
和Employee
。不要求Employee
继承Person
,您可以在Employee
内部组合Person
,并将对Person
功能的请求转发给组合类,这样我们仍然可以获得重用Person>的好处
class
注意事项:
类可能是抽象类或Person
类可能与人员
员工
class A {
void foo(){
...
this.bar();
...
}
void bar(){
...
}
}
class B extends A {
//override bar
void bar(){
...
}
}
class C {
void bazz(){
B b = new B();
// which bar would be called?
B.foo();
}
}
正如您在
bazz
方法中看到的,将调用哪个bar
?将调用类B中的第二个bar
。但是,这里的问题是什么?问题是类A中的foo
方法不知道类B中对bar
方法的重写,那么您的不变量可能会被违反。因为se foo可能期望bar方法的唯一行为是在自己的类中,而不是被重写。这个问题称为脆弱基类问题继承会破坏封装?只有在误用时……继承是面向对象设计的一个组成部分。继承不会破坏封装。派生类不会ot有权接触其基类的私人成员。“连锁反应”是OOP的一个组成部分;如果动物呼吸,那么狗、猫、人……也会呼吸。他们没有泄露动物的内在本质,只是意识到了这一点。谷歌搜索“继承vs委派”和“继承vs组合”在这个主题上产生了一些非常好的文章。不幸的是,我们不同意你问题的前提,这对我们来说是错误的。@Jon:请注意,你反对继承的论点几乎都适用于封装。假设有人可能错误地制作一个受保护的接口,从而破坏了封装隔离(通过固有),为什么你认为公共接口(通过委托)无法破坏封装?您的解决方案和您的前提一样有缺陷。继承不会破坏封装,即使是在纯粹的意义上。如果这些成员被封装并且无法从派生类访问,它们就不会是公共/受保护的。@MooingDuck看一下我回答中的链接。人们普遍认为我n继承打破了纯粹意义上的封装。“如果允许派生类访问从基类继承的成员,则基类中的更改也可能需要维护派生类。”如果允许实现更改通过接口泄漏,那么这不适用于任何类的任何使用者吗?我发现引用的源代码中的参数很弱。派生类只有在允许的情况下才能直接操作基类的数据(通过protected
access修饰符)。如果你错误地将私有字段标记为受保护的,那么是你的设计被破坏了。@Douglas“破坏继承的封装”的学术论点是关于“受保护”的能力所有成员。仅仅是能够这样做的想法,即使是有意的,也是OOP纯粹主义者说继承破坏了封装的原因。但是超级类的设计者不能知道每一个可能扩展它的类?所以继承赋予的特权可能会被第六代/第七代子类滥用?你怎么看