Questions tagged «multiple-inheritance»

9
讨厌多重继承吗?
我一直很喜欢在一种语言中支持多重继承的想法。尽管通常是故意放弃的,但所谓的“替换”是接口。接口根本不能涵盖所有相同的多重继承,并且这种限制有时可能会导致产生更多样板代码。 我听说过的唯一基本原因是基类的钻石问题。我就是不能接受。对我来说,它的表现非常糟糕,例如:“嗯,有可能将其弄糟,所以这自然不是一个好主意。” 但是,您可以用编程语言修改任何内容,我的意思是。我只是不能认真对待这一点,至少没有没有更彻底的解释。 仅知道这个问题就占了90%。此外,我想我几年前听说过涉及通用解决方案的问题,该解决方案涉及“信封”算法或类似的东西(有人敲响铃吗?)。 关于钻石问题,我能想到的唯一潜在的真正问题是,如果您正在尝试使用第三方库,并且看不到该库中两个看似无关的类具有共同的基类,那么除了例如,文档是一种简单的语言功能,可能要求您明确声明要创建菱形的意图,然后才能为您实际编译菱形。有了这样的功能,任何钻石的制造要么是故意的,鲁ck的,要么是因为人们没有意识到这一陷阱。 所有人都这么说... 大多数人是否有真正的理由讨厌多重继承,还是仅仅是一堆歇斯底里会造成弊大于利?有没有我在这里看不到的东西?谢谢。 例 汽车扩展了WheeledVehicle,KIASpectra扩展了汽车和电子产品,KIASpectra包含无线电。为什么KIASpectra不包含电子产品? 因为它是电子的。继承vs.组合应该始终是is-a关系vs.has-a关系。 因为它是电子的。上下都有电线,电路板,开关等。 因为它是电子的。如果冬天电池没电了,您的麻烦就好像所有车轮突然丢失一样。 为什么不使用接口?以#3为例。我不想一遍又一遍地写这个,而且我真的不想创建一些奇怪的代理帮助器类来做到这一点: private void runOrDont() { if (this.battery) { if (this.battery.working && this.switchedOn) { this.run(); return; } } this.dontRun(); } (我们不会考虑该实现的好坏。)您可以想象如何可能有一些与电子相关的功能与WheeledVehicle中的任何内容都不相关,反之亦然。 我不确定是否要解决该示例,因为那里有解释的空间。您还可以考虑从平面扩展Vehicle和FlyingObject,以及从Bird扩展Animal和FlyingObject,或者从更纯粹的示例方面进行思考。

1
mixin或特性比纯多重继承更好吗?
C ++具有简单的多重继承,许多语言设计都将其视为危险。但是某些语言(例如Ruby和PHP)使用奇怪的语法来完成相同的操作,并将其称为mixin或traits。我多次听说,mixin /特性比普通的多重继承更难滥用。 是什么使它们危险性降低了?是否有不能用mixins / traits来实现,但是可以用C ++风格的多重继承来实现?他们有可能遇到钻石问题吗? 似乎我们在使用多重继承,但只是借口说它们是混合/特性,因此我们可以使用它们。

6
多重继承是否违反单一责任原则?
如果您有一个从两个不同的类继承的类,这是否意味着您的子类自动(至少)自动做2件事,每个超类都做一件? 我相信,如果您有多个接口继承,也没有什么区别。 编辑:明确地说,我认为如果子类化多个类违反了SRP,则实现多个(非标记或基本接口(例如,可比较)接口)也违反了SRP。

2
Scala的特征如何避免“钻石错误”?
(注意:出于明显的原因,我在标题中使用了“错误”而不是“问题”。))。 我对Scala的Traits做了一些基础阅读。它们类似于Java或C#中的接口,但是它们确实允许方法的默认实现。 我在想:这难道不会引起“钻石问题”吗?这就是为什么许多语言首先避免多重继承的原因? 如果是这样,Scala如何处理呢?

5
Java(Android)中多重继承的正确解决方法
我有一个概念上的问题,即代码的正确实现似乎需要多重继承,在许多OO语言中这不是问题,但是由于该项目是针对Android的,所以没有诸如multi之类的东西extends。 我有一堆的活动,从不同的基类,如简单的衍生Activity,TabActivity,ListActivity,ExpandableListActivity,等。此外我有我需要的地方变成一些代码片段onStart,onStop,onSaveInstanceState,onRestoreInstanceState和其他标准的事件中的所有活动处理器。 如果所有活动只有一个基类,则可以将代码放入一个特殊的中间派生类中,然后创建将其扩展的所有活动。不幸的是,事实并非如此,因为存在多个基类。但是,将代码的相同部分放入几个中间类并不是一种方法,恕我直言。 另一种方法可以是创建一个助手对象,并将上述事件的所有调用委托给助手。但这要求包括辅助对象,并在所有中间类中重新定义所有处理程序。因此,这里的第一种方法没有太大区别-仍然有很多代码重复。 如果在Windows下发生类似情况,我将继承基类(与ActivityAndroid中的类“相对应”的基类),并在那里(在一个地方)捕获适当的消息。 为此,在Java / Android中可以做什么?我知道有一些有趣的工具,例如Java工具(带有一些真实的示例),但是我不是Java专家,所以不确定在这种情况下是否值得尝试。 如果我错过了其他一些不错的解决方案,请提及它们。 更新: 对于那些可能对解决Android中的相同问题感兴趣的人,我发现了一个简单的解决方法。存在Application类,该类除其他外提供接口ActivityLifecycleCallbacks。它正是我所需要的,它使我们能够拦截所有活动的重要事件并为其添加一些价值。此方法的唯一缺点是,它从API级别14开始就可用,这在许多情况下还远远不够(目前对API级别10的支持已成为典型要求)。

7
多重继承用例
Java忽略了多重继承,因为它消除了保持语言简单性的设计目标。 我想知道Java(及其生态系统)是否真的“简单”。Python并不复杂,具有多重继承。因此,我的问题不是太主观,而是... 从旨在大量使用多重继承的代码中受益的典型问题模式有哪些?


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 …

4
我的体系结构的多重继承的替代方案(实时策略游戏中的NPC)?
编码实际上并不难。困难的部分是编写有意义,可读和可理解的代码。因此,我想找一个更好的开发人员并创建一些可靠的体系结构。 因此,我想为电子游戏中的NPC创建一个体系结构。这是一个实时战略游戏,例如《星际争霸》,《帝国时代》,《命令与征服》等。因此,我将拥有不同种类的NPC。一个NPC可以有一对多的能力,这些(方法): Build(),Farm()和Attack()。 例子: 工人可以Build()和Farm() 战士可以Attack() 公民可以Build(),Farm()和Attack() 渔民可以Farm()和Attack() 我希望到目前为止一切都清楚。 所以现在我有了我的NPC类型及其能力。但是让我们来谈谈技术/程序方面。 对于我不同种类的NPC,什么样的程序设计架构会很好? 好吧,我可以有一个基础课。实际上,我认为这是坚持DRY原则的好方法。因此,我可以WalkTo(x,y)在基类中使用类似的方法,因为每个NPC都可以移动。但是现在让我们来解决真正的问题。我在哪里实现我的能力?(记住:Build(),Farm()和Attack()) 由于这些能力将由相同的逻辑组成,因此为每个NPC(工人,战士,..)实施它们将是令人讨厌的/打破DRY原则。 好吧,我可以在基类中实现这些功能。这将需要某种逻辑来验证NPC是否可以使用X IsBuilder,... CanBuild,…… 能力。我想我想表达的很清楚。 但是我对这个想法不太满意。这听起来像一个功能过多的。肿基类。 我确实使用C#作为编程语言。因此,这里不能选择多重继承。意思是:拥有额外的基础类是Fisherman : Farmer, Attacker行不通的。

1
使用Python的方法解析顺序进行依赖注入-这样不好吗?
我观看了Raymond Hettinger在Pycon上发表的“超级被认为是超级”的演讲,并了解了一些Python的MRO(方法解析顺序),该方法以确定性方式线性化了“父”类。像下面的代码一样,我们可以利用它来发挥优势,进行依赖注入。因此,自然而然地,我现在想使用super所有功能! 在下面的示例中,User该类通过从LoggingService和继承来声明其依赖项UserService。这不是特别特殊。有趣的是,我们可以使用“方法解析顺序”来模拟单元测试期间的依赖关系。下面的代码创建一个MockUserService从继承UserService并提供我们要模拟的方法的实现。在下面的示例中,我们提供的实现validate_credentials。为了MockUserService处理任何呼叫,validate_credentials我们需要先将其UserService放置在MRO中。这通过创建一个包装类各地进行User所谓的MockUser和有它继承User和MockUserService。 现在,当我们执行MockUser.authenticate该操作时,它依次调用方法解析顺序中的super().validate_credentials() MockUserServicebefore UserService,因为它提供了validate_credentials该实现的具体实现。是的-我们已经UserService在单元测试中成功模拟了。考虑到这样UserService做可能会导致一些昂贵的网络或数据库调用-我们刚刚删除了此延迟因素。也没有UserService接触实时/生产数据的风险。 class LoggingService(object): """ Just a contrived logging class for demonstration purposes """ def log_error(self, error): pass class UserService(object): """ Provide a method to authenticate the user by performing some expensive DB or network operation. """ def validate_credentials(self, username, password): print('> UserService::validate_credentials') return username == …

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 …
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.