Questions tagged «inheritance»

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

9
设计继承如何导致额外的费用?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 6年前关闭。 所以,我想继承一个sealed class在CSHARP,结果被烧毁。除非您有权访问源,否则无法解封。 然后,我想到了“为什么sealed甚至存在?”。4个月前。尽管阅读了很多有关内容的文章,但我还是不知道,例如: 乔恩·斯凯特(Jon Skeet)的愿望是:“ 类在.NET中默认为封闭的。 ” 比继承更偏爱组成? “您不应该密封所有课程(...)” 您如何模拟密封课程? 从那以后我一直试图消化所有这些,但是对我来说太过分了。最终,昨天我再次尝试了。我再次扫描了所有这些文件,还有更多: 为什么一个班级应该不是“抽象”或“最终/密封”之外的任何东西? 在超过15年的编程时间中,我第一次听说SOLID时,是从已经链接的问题的答案中得出的,显然我四个月前都没有读过它 最后,经过深思熟虑,我决定根据新标题对原始问题进行大量编辑。 在老问题过于宽泛和主观的。基本上是在问: 旧标题中:使用密封的一个很好的理由 在正文中:如何正确修改密封类?忘记继承?使用成分? 但是现在,理解(我昨天没做过)所有事情sealed都在阻止继承,我们可以并且确实应该在继承上使用组合,我意识到我需要的是实际示例。 我想我的问题是(实际上一直都是)Mindor先生在聊天中向我提出的建议:继承设计如何导致额外的成本?
12 c#  inheritance 

2
为什么Java不支持像C ++这样的私有/受保护的继承?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 在C ++中继承类时,用户可以指定访问说明符,例如, class Base { public int mem1; protected in mem2; }; class Derived1 : **private** Base { // mem1 will be private here. // mem2 will be private here. }; class Derived2 : **protected** Base { // mem1 will be protected here. // mem2 will be protected …

4
并行层次结构-部分相同,部分不同
那里有很多类似的问题 1,2,3,4,但是在这个问题上似乎并非如此,解决方案也不是最优的。 假设多态性,泛型和混合可用,这是一个普遍的OOP问题。实际使用的语言是OOP Javascript(Typescript),但是在Java或C ++中,这是同样的问题。 我有并行的类层次结构,有时具有相同的行为(接口和实现),但有时每个都有其自己的“受保护”行为。像这样说明: 这仅是为了说明目的 ; 这不是实际的类图。阅读: Canvas(左)和SVG(右)层次结构共享公共层次结构(中心)中的任何内容。分享是指接口和实现。 仅左列或右列中的任何内容均表示特定于该层次结构的行为(方法和成员)。例如: 左和右层次结构都使用完全相同的验证机制,Viewee.validate()在通用层次结构上显示为单个方法()。 仅画布层次结构具有方法paint()。此方法在所有子项上调用paint方法。 SVG层次结构需要覆盖的addChild()方法Composite,但是canvas层次结构并非如此。 不能从两个侧面层次结构中混合构造。工厂确保做到这一点。 解决方案I-逗弄继承 Fowler的“逗趣分开继承”在这里似乎不起作用,因为两个相似之处之间存在一些差异。 解决方案II-Mixins 这是我目前唯一能想到的。这两个层次结构是分别开发的,但是在每个级别上,这些类都混合在公共类中,而这并不属于类层次结构。省略structural叉子,将如下所示: 请注意,每列将位于其自己的名称空间中,因此类名不会冲突。 问题 谁能看到这种方法的缺点?谁能想到更好的解决方案? 附录 这是一些示例代码,该如何使用。命名空间svg可以替换为canvas: var iView = document.getElementById( 'view' ), iKandinsky = new svg.Kandinsky(), iEpigone = new svg.Epigone(), iTonyBlair = new svg.TonyBlair( iView, iKandinsky ), iLayer = new svg.Layer(), iZoomer …

5
在这种情况下,我应该选择组合还是继承?
考虑一个接口: interface IWaveGenerator { SoundWave GenerateWave(double frequency, double lengthInSeconds); } 此接口由许多类实现,这些类生成不同形状的波(例如SineWaveGenerator和SquareWaveGenerator)。 我想实现一个SoundWave基于音乐数据而不是原始声音数据生成类的类。它会收到音符的名称和以拍子(不是秒)为单位的长度,并在内部使用该IWaveGenerator功能来创建一个音符SoundWave。 问题是,应该NoteGenerator包含IWaveGenerator还是应该从IWaveGenerator实现中继承? 由于两个原因,我倾向于合成: 1 -它让我注入任何IWaveGenerator的NoteGenerator动态。另外,我只需要一个NoteGenerator类,而不是SineNoteGenerator,SquareNoteGenerator等等。 2-无需NoteGenerator公开由定义的较低级接口IWaveGenerator。 但是,我发布此问题是为了听取对此的其他意见,也许是我没有想到的要点。 顺便说一句:我会说NoteGenerator 从概念上讲是an,IWaveGenerator因为它生成SoundWaves。

5
突变方法的单独界面
我一直在进行一些代码的重构,我想我可能已经迈出了第一步。我正在用Java编写示例,但我想它可能是不可知的。 我有一个Foo定义为的接口 public interface Foo { int getX(); int getY(); int getZ(); } 和一个实现 public final class DefaultFoo implements Foo { public DefaultFoo(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } public int getX() { return x; } public int getY() { …

9
使用哪种OO设计(是否有设计模式)?
我有两个代表“酒吧/俱乐部”(您喝酒/社交的地方)的对象。 在一种情况下,我需要栏名称,地址,距离,标语 在另一种情况下,我需要栏名称,地址,网站网址,徽标 因此,我有两个对象代表相同的事物,但具有不同的字段。 我喜欢使用不可变的对象,因此所有字段都是从构造函数设置的。 一种选择是拥有两个构造函数,而其他字段为空,即: class Bar { private final String name; private final Distance distance; private final Url url; public Bar(String name, Distance distance){ this.name = name; this.distance = distance; this.url = null; } public Bar(String name, Url url){ this.name = name; this.distance = null; this.url = url; …

5
如何实现RealNumber和ComplexNumber继承?
希望不是太学术... 假设我的SW库中需要实数和复数。 根据is-a(或here)关系,实数是复数,其中复数虚部中的b就是0。 另一方面,我的实现是,该子对象扩展父对象,因此在父对象RealNumber中,我将拥有实部,而子对象ComplexNumber将添加虚构图。 还有一种观点认为继承是邪恶的。 我记得像昨天一样,当我在大学学习OOP时,我的教授说,这不是继承的一个很好的例子,因为这两者的绝对值是用不同的方式计算的(但为此我们有方法重载/多态主义,对吗?)。 。 我的经验是,我们经常使用继承来解决DRY,因此,我们经常在层次结构中人工构造抽象类(由于名称不能代表真实世界中的对象,因此经常很难找到名称)。

5
违反LSP可以吗?
我正在跟进这个问题,但是我将重点从代码转换为原则。 根据我对Liskov替换原理(LSP)的理解,无论我的基类中有什么方法,它们都必须在我的子类中实现,并且根据此页面,如果您在基类中重写了一个方法,则它什么也不做或抛出一个错误。例外,您违反了该原则。 现在,我的问题可以这样总结:我有一个abstract Weapon class,两个类,Sword和Reloadable。如果Reloadable包含一个特定的method,称为Reload(),我将不得不向下访问以访问该method,并且理想情况下,您希望避免这种情况。 然后,我想到了使用Strategy Pattern。这样,每把武器都只知道它能够执行的动作,因此,例如,一种Reloadable武器显然可以重新装弹,但是Sword不能,甚至不知道Reload class/method。正如我在Stack Overflow帖子中所说的那样,我不必沮丧,也可以维护List<Weapon>收藏集。 在另一个论坛上,第一个答案建议让其Sword意识到Reload,只是什么也不要做。我在上面链接到的“堆栈溢出”页面上也给出了相同的答案。 我不完全明白为什么。为什么要违反该原则并让Sword知道Reload并保留为空?正如我在Stack Overflow帖子中所说,SP几乎解决了我的问题。 为什么它不是可行的解决方案? public final Weapon{ private final String name; private final int damage; private final List<AttackStrategy> validactions; private final List<Actions> standardActions; private Weapon(String name, int damage, List<AttackStrategy> standardActions, List<Actions> attacks) { this.name = name; this.damage = damage; standardActions = …

1
是否存在使用弱引用而不是简单组合更好的情况?
虽然Java文档指定,即弱引用主要用于映射进行规范化,你会发现很多,很多,很多人在互联网上声称,该WeakHashMap中是完美的在其一生中存储的对象元数据。但是,没有人愿意做一个易于理解和适当的例子。 使用WeakHashMap向对象添加一些属性或存储元数据的声音对我来说,就像一个基于将要使用该死的东西的意愿的任意决定。换句话说-一个不好的设计。我了解,在某些情况下继承可能不可用(最终类,接口),但是组合又如何呢?我想不出一个例子,其中组合不是一种选择。当然,这是一个更好的选择,因为它依赖于公认的原则,而不是“语言怪癖”。 那么,有没有一种情况,使用弱引用而不是简单的组合会更好?如果没有,为什么互联网上的每个人似乎都会出错?

2
Python的继承是“ is-a”继承样式还是组合样式?
考虑到Python允许多重继承,Python中的惯用继承是什么样的? 在具有单一继承的语言(例如Java)中,当您可以说一个对象是另一个对象的“是”并且想要在对象之间共享代码(从父对象到子对象)时,将使用继承。例如,您可以说这Dog是一个Animal: public class Animal {...} public class Dog extends Animal {...} 但是由于Python支持多重继承,我们可以通过将许多其他对象组合在一起来创建对象。考虑下面的示例: class UserService(object): def validate_credentials(self, username, password): # validate the user credentials are correct pass class LoggingService(object): def log_error(self, error): # log an error pass class User(UserService, LoggingService): def __init__(self, username, password): self.username = username self.password = password …

3
继承:是将代码从超类实际上“复制”到子类,还是“由子类”引用?
类Sub是class的子类Sup。这实际上意味着什么?换句话说,“继承”的实际含义是什么? 选项1:将Sup中的代码虚拟复制到Sub。(如在“复制-粘贴”,但没有复制的代码视觉上在子类中看到的)。 示例:methodA()最初是Sup中的一种方法。Sub扩展了Sup,因此methodA()(实际上)被复制粘贴到Sub。现在Sub具有一个名为的方法methodA()。它methodA()在每一行代码中均与Sup相同,但完全属于Sub,并且不依赖于Sup或以任何方式与Sup相关。 选项2: Sup中的代码实际上没有复制到Sub。它仍然只在超类中。但是该代码可以通过子类访问,并且可以由子类使用。 示例:methodA()是Sup中的一种方法。Sub扩展了Sup,因此现在methodA()可以通过Sub进行访问,如下所示:subInstance.methodA()。但这实际上将methodA()在超类中调用。这意味着methodA()将在超类的上下文中运行,即使它是由子类调用的。 问题:这两个选项中的哪一个实际上是如何工作的?如果它们都不是,那么请描述这些事情实际上是如何工作的。

12
“如果重新使用某个方法而不进行更改,将该方法放在基类中,否则创建一个接口”是否是一种很好的经验法则?
我的一位同事想出了一个在创建基类或接口之间进行选择的经验法则。 他说: 想象一下您将要实现的每个新方法。对于它们中的每一个,请考虑以下问题:是否可以由多个类以完全相同的形式实现此方法,而无需进行任何更改?如果答案为“是”,则创建一个基类。在其他所有情况下,请创建一个接口。 例如: 考虑类cat和dog,它们扩展了类mammal并具有一个方法pet()。然后我们添加类alligator,该类不会扩展任何内容并且具有一个方法slither()。 现在,我们要eat()为所有这些方法添加一个方法。 如果实施eat()方法将是完全一样的cat,dog而且alligator,我们应该创建一个基类(比方说,animal),它实现了这个方法。 但是,如果它的实现alligator有丝毫不同,我们应该创建一个IEat接口并制作mammal和alligator实现它。 他坚持认为这种方法适用于所有情况,但对我来说似乎过于简化了。 遵循此经验法则是否值得?

2
为什么在创建原型时不鼓励使用构造函数?
快速背景:在JavaScript中,每种对象类型的构造函数都有一个prototype属性。的prototype是指一个对象,各构造对象的用途如在其原型链中的下一步骤的。当您希望一种类型可以是另一种类型固有的类型时,可以将prototype子类型的设置为父类型的新实例。 例如: var Parent = function() { /* constructor business */ } Parent.prototype.parentProp = "some parent property"; var Child = function() { /* constructor business */ } Child.prototype = /*** !! Some prototype object goes here !! ***/ 我的问题询问上面的代码中应在“ Some prototype object goes here”位置添加哪些代码。我的第一个本能是构造父对象的实例(即new Parent()),但在评论“关于将这样的对象原型复制到另一个对象的安全方法吗?”的评论中。,一位用户写道: 不,请勿new bar()用于原型对象! (...这是我在许多答案和评论中都看到的一种观点,但这是我目前手头唯一的例子。) 另一种选择是Object.create(Parent.prototype)用作Child.prototype。据我所知,这还会创建一个新Parent实例,但不会运行Parent构造函数。 有人可以解释为什么从父类型生成原型对象时应避免运行构造函数的原因吗?是否会出现一些重大的技术问题(也许具有多个继承级别)?还是这种模式会误用构造函数,从而与一些典型的最佳实践相冲突(例如,在创建原型时运行构造函数违反了某些关注点分离)?


5
接口和继承:两全其美?
我“发现”了界面,并开始喜欢它们。接口的优点在于它是一个契约,任何需要履行该契约的对象都可以在需要该接口的任何地方使用。 接口的问题是它不能具有默认实现,这对于平凡的属性是一种痛苦,并且会破坏DRY。这也很好,因为它可以使实现与系统保持分离。一方面,继承会保持更紧密的耦合,并且有可能破坏封装。 案例1(与私有成员的继承,良好的封装,紧密耦合) class Employee { int money_earned; string name; public: void do_work(){money_earned++;}; string get_name(return name;); }; class Nurse : public Employee: { public: void do_work(/*do work. Oops, can't update money_earned. Unaware I have to call superclass' do_work()*/); }; void HireNurse(Nurse *n) { nurse->do_work(); ) 情况2(只是一个接口) class IEmployee { virtual …

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.