Questions tagged «inheritance»

继承是一种重用现有对象的代码或从现有对象建立子类型的方法,或两者​​都取决于编程语言的支持。

4
动态语言中的继承vs mixins?
什么时候应该使用继承模式而不是动态语言中的mixins? 所谓混入,是指实际正确混入,例如在运行时将函数和数据成员插入对象中。 例如,什么时候使用原型继承而不是mixins?为了更清楚地说明我的意思,mixin,一些伪代码: asCircle(obj) { obj.radius = 0 obj.area = function() { return this.radius * this.radius * 3.14 } myObject = {} asCircle(myObject) myObject.area() // -> 0

1
为什么(/ did)Bertrand Meyer认为子类化是扩展“封闭式”模块的唯一方法?
在Meyer的“ 面向对象的软件构造”(1988)中,他将开放/封闭原则定义如下: 如果模块仍可扩展,则称其为打开状态。例如,应该可以向其包含的数据结构添加字段,或者向其执行的功能集添加新元素。 如果某个模块可供其他模块使用,则将其称为已关闭。假设已为模块提供了良好定义的稳定描述(信息隐藏的界面)。 他接着说: 如果重新打开模块,则还必须重新打开其所有客户端以对其进行更新,因为它们依赖于旧版本。…[此问题]每当模块必须由新功能或数据元素扩展时触发,从而触发直接和间接客户端中的更改。...使用经典的设计和编程方法,无法编写打开和关闭的模块。 Meyer解决这个难题的方法是:永远不要通过修改现有的类来扩展库模块;而是编写一个新模块来对现有类进行子类化,并使新客户端依赖于该新模块。 现在,在1988年,我正在用Turbo Pascal和Blankenship Basic编写玩具(程序)程序,而我在21世纪的专业经验是使用JVM,CLR和动态语言,所以我不知道Meyer的意思。通过“经典的设计和编程方法”。 Meyer的一个具体示例说明了为什么必须重新打开客户端模块(枚举上的switch语句,现在有更多的成员,需要更多的情况)似乎很合理,但是他几乎没有断言每次向库添加功能时都会断言模块,您需要更新其所有客户端。 是否有历史原因使该主张在1988年显得不言而喻?例如,向C静态库添加函数或数据结构是否更改了布局,以至于即使使用向后兼容的API,也必须重新编译客户端?还是Meyer真的只是在谈论一种用于强制API向后兼容的机制?


5
何时使用继承,何时使用“仅布尔字段”?
在我们的Rails应用程序中,我们正在添加通知。其中一些是blocking:它们会停止添加任何资源的进度,因为缺少该资源的某些信息。 其他通知是简单通知,仅提供信息。 今天,我与团队中的另一个程序员进行了讨论。我创建了这样的继承结构: 但是,他希望我只是blocking在每个Notification上添加为布尔返回方法,并指定在Notification父类内阻塞的子类列表。 这些方法之间的差异不是很大。在我的方法中,不必指定此列表,以使根类保持整洁。另一方面,Notification::Blocking现在发生的特殊逻辑也不是很大。 哪种抽象更适合此问题?

4
为什么在Java中没有“仅子类”访问修饰符?
在Java中,方法有四个可用的访问修饰符: public -任何类都可以使用此方法。 protected -同一包中的类和任何包中的子类都可以使用此方法。 private -只有此类可以使用此方法。 no modifier (“包私有”)-只有同一包中的类才能使用此方法。 经常发生的事情是,我想在超类中拥有所有子类都可以使用的有用方法。但是其他类访问此方法没有任何意义,从某种意义上说,它将破坏封装。 因此,我必须在超类publicor中声明这些有用的方法protected,这至少在包中将它们公开给所有其他类。即使它们仅打算由子类使用。 有没有理由subclasses-only在Java中没有访问修饰符?对我来说似乎很奇怪。我想念什么吗? 同样,subclasses-only当您只想将变量公开给子类时,访问修饰符也很有用。在我身上发生的事情很多。

4
何时将公共字段移入基类?
我目前有两个派生类A和B,它们都有一个共同的字段,并且我试图确定它是否应该进入基类。 永远不会从基类中引用它,并且说如果在将来的某个时刻派生出另一个没有的类C,那么它不会_field1违反“最低特权”(或某些东西)的原则。是吗 public abstract class Base { // Should _field1 be brought up to Base? //protected int Field1 { get; set; } } public class A : Base { private int _field1; } public class B : Base { private int _field1; } public class C : Base { // …

14
我如何解释继承的用处?[关闭]
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 6年前关闭。 当试图解释OOP中的继承概念时,常见的例子通常是哺乳动物。恕我直言,这确实是一个不好的例子,因为它将导致新手以错误的方式使用此概念。而且,他们在日常设计工作中将面临的不是常见的设计。 那么,使用继承解决的一个好,简单而具体的问题是什么?

1
如何在继承层次结构中验证Liskov替换原理?
灵感来自这个答案: 里氏替换原则要求 是 前提条件不能在子类型中得到加强。 子条件不能弱化后置条件。 超类型的不变量必须保留在子类型中。 历史记录约束(“历史记录规则”)。只能通过对象的方法(封装)将其视为可修改的对象。由于子类型可能会引入父类型中不存在的方法,因此这些方法的引入可能会导致子类型中状态不允许在父类型中发生变化。历史记录约束禁止这样做。 我希望有人能发布违反这4点的类层次结构,以及如何相应地解决它们。 我正在寻找出于教育目的的详细说明,以了解如何识别层次结构中的四个点以及解决该问题的最佳方法。 注意: 我希望发布代码示例供人们使用,但是问题本身是关于如何识别错误的层次结构的:)

6
受保护方法的真实场景
今天,我注意到我基本上从不使用protectedC ++代码中的方法,因为我很少感到需要调用父级的非公共方法。我确实在模板方法模式中使用了Java中的protected,但是由于您可以在C ++中覆盖私有方法,因此我也不需要protected。 那么,在哪些实际场景中我想protected在C ++代码中使用方法? (请注意,我一般不太喜欢实现继承,这可能会解释很多...)

8
“优先考虑组成而不是继承”-防御签名变更的唯一理由是吗?
此页面使用以下参数提倡在继承上进行组合(用我的措辞重新表述): 当我们使用继承时,超类方法签名的更改(尚未在子类中重写)会在许多地方引起其他更改。但是,当我们使用Composition时,所需的其他更改仅在单个位置:子类。 难道这真的是偏向于继承而不是继承的唯一理由吗?因为是这样的话,即使子类不更改实现(即在子类中放置虚拟替代),也可以通过强制采用提倡重写超类的所有方法的编码样式来轻松缓解此问题。我在这里想念什么吗?

2
如何避免在包装器中编写大量传递函数?
我有一个类,它包装了一个通用基本类型的另一个类。由于基本类型的接口很大,因此需要编写许多传递函数。我正在寻找避免这种情况的方法。 让我们举个例子: Car / \ Volvo VolvoWithTrailer 现在,我必须在VolvoWithTrailer的car接口中实现每个函数,并在包装​​好的Volvo对象上调用适当的函数,但GetMaxSpeed()可能会返回更低的值。基本上我将有很多功能,例如 int VolvoWithTrailer::GetNumSeats() { return mVolvo.GetNumSeats() } 解决此问题的一个明显方法是使VolvoWithTrailer成为Volvo的子类。 Car | Volvo | VolvoWithTrailer 但这似乎违反了主张组成优先于继承的原则。 我还要如何避免编写所有这些包装器(语言是C ++)?或者-如果那是您的职位-为什么我应该只写它们/只使用继承?有没有模板魔术可以帮助解决这个问题?

3
组成重于继承,但
我试图自学软件工程,遇到一些使我感到困惑的冲突信息。 我一直在学习OOP,以及什么是抽象类/接口以及如何使用它们,但是随后我读到,应该“偏重于继承而不是继承”。我知道组合是指一个类组成/创建另一个类的对象以利用/与该新对象的功能交互。 所以我的问题是...我应该不使用抽象类和接口吗?是否不创建抽象类并在具体类中扩展/继承该抽象类的功能,而是仅编写新对象以使用其他类的功能? 或者,我应该使用组合并从抽象类继承吗?两者结合使用?如果是这样,您能否提供一些示例,说明其工作方式及其好处? 因为我最熟悉PHP,所以在继续使用其他语言并转移我新获得的SE技能之前,我正在使用它来提高OOP / SE技能,因此,使用PHP的示例非常受赞赏。

2
如果派生类没有分配原始动态内存,为什么基类在这里需要有一个虚拟析构函数?
以下代码导致内存泄漏: #include <iostream> #include <memory> #include <vector> using namespace std; class base { void virtual initialize_vector() = 0; }; class derived : public base { private: vector<int> vec; public: derived() { initialize_vector(); } void initialize_vector() { for (int i = 0; i < 1000000; i++) { vec.push_back(i); } } }; …

5
继承与具有空值的其他属性
对于具有可选字段的类,使用继承或可为空的属性更好吗?考虑以下示例: class Book { private String name; } class BookWithColor extends Book { private String color; } 要么 class Book { private String name; private String color; //when this is null then it is "Book" otherwise "BookWithColor" } 要么 class Book { private String name; private Optional<String> color; //when isPresent() …
12 java  inheritance  class  null 

3
如果某个接口继承自其他接口,是否将其视为“空”?
据我所知,空接口通常被认为是不好的做法-特别是在语言支持的属性之类的地方。 但是,如果某个接口继承自其他接口,是否将其视为“空”? interface I1 { ... } interface I2 { ... } //unrelated to I1 interface I3 : I1, I2 { // empty body } 任何实现I3将需要实现I1和I2,并从不同的类,这些类继承的对象I3然后可以互换使用(见下文),所以是不是叫I3 空?如果是这样,哪种更好的架构方法呢? // with I3 interface class A : I3 { ... } class B : I3 { ... } class Test { void foo() …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.