Questions tagged «inheritance»

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

5
与定义一个方法可以调用相比,如何定义一个方法可以被覆盖更强的承诺?
来自:http : //www.artima.com/lejava/articles/designprinciples4.html 埃里希·伽玛(Erich Gamma):即使十年之后,我仍然认为这是真的。继承是改变行为的一种很酷的方法。但是我们知道它很脆弱,因为子类可以轻松地对调用其重写的方法的上下文进行假设。基类和子类之间存在紧密的耦合,因为隐式上下文将在其中调用我插入的子类代码。合成具有更好的属性。通过将一些较小的东西插入较大的对象中,可以减少耦合,而较大的对象仅将较小的对象回调。从API的角度来看,定义可以覆盖的方法比定义可以调用的方法要强。 我不明白他的意思。有人可以解释一下吗?

5
什么时候应该扩展Java Swing类?
我对继承实现的当前理解是,只有存在IS-A关系时,才应该扩展类。如果父类可以进一步具有具有不同功能的更特定的子类型,但将共享在父类中抽象的公共元素。 我质疑这种理解,因为我的Java教授建议我们这样做。他建议JSwing我们在课堂上建立一个应用程序 一个都应该延伸JSwing类(JFrame,JButton,JTextBox等)到单独的自定义类和在其中指定GUI相关的定制(例如部件尺寸,部件的标签,等) 到目前为止还算不错,但是他进一步建议每个JButton应该有自己的自定义扩展类,即使唯一的区别是标签。 例如,如果GUI有两个按钮,则“ 确定”和“ 取消”。他建议应将它们扩展如下: class OkayButton extends JButton{ MainUI mui; public OkayButton(MainUI mui) { setSize(80,60); setText("Okay"); this.mui = mui; mui.add(this); } } class CancelButton extends JButton{ MainUI mui; public CancelButton(MainUI mui) { setSize(80,60); setText("Cancel"); this.mui = mui; mui.add(this); } } 如您所见,唯一的区别在于setText功能。 那么这是标准做法吗? 顺便说一句,讨论该课程的课程称为Java最佳编程实践 [教授回覆] 因此,我与教授讨论了这个问题,并提出了答案中提到的所有观点。 他的理由是子类在遵循GUI设计标准的同时提供了可重用的代码。例如,如果开发人员在一个窗口中使用了自定义Okay和Cancel按钮,则将相同的按钮放置在其他Windows中也将变得更加容易。 我知道了我想起的原因,但它仍然只是在利用继承并使代码易碎。 …


3
Java开发是否通常比C#/。NET涉及更多的子类化?
我最近开始研究Android开发。这使我回到了Java软件开发领域。我承认,上一次我使用Java时,我对OOP的了解不如现在(我认为)那么多。 在我的职业生涯中主要使用C#之后,我注意到Java和C#在继承使用方式方面的惊人差异。 在C#中,似乎在大多数情况下都可以避免继承。通常,可以通过使用.NET框架的具体类来完成当前的任务。 在Java中,从我从代码示例中收集的信息来看,Java框架似乎提供了许多接口或抽象类,这些接口或抽象类将由开发人员实现/扩展。 这似乎太大了,不能简单地归结为风格。这背后的原因是什么?我觉得直到我理解这一点,我才会写干净的Java代码。 此外,这是否仅限于Android SDK还是Java范围内的OOP方法? 或换种说法, 这两种语言(似乎鼓励)比另一种或多或少使用继承的设计是什么? 如果语言对继承的处理相同,并且假设我的观察是有效的,则意味着这与框架/库的设计有关,而与语言无关。这种设计的动机是什么?

5
Python mixins是反模式吗?
我完全意识到,pylint其他静态分析工具并非一无所知,有时必须不听从他们的建议。(这适用于各种类型的消息,而不仅仅是conventions。) 如果我有像 class related_methods(): def a_method(self): self.stack.function(self.my_var) class more_methods(): def b_method(self): self.otherfunc() class implement_methods(related_methods, more_methods): def __init__(self): self.stack = some() self.my_var = other() def otherfunc(self): self.a_method() 显然,这是人为的。如果您愿意,这是一个更好的示例。 我相信使用“ mixins”来称呼这种风格。 像其他工具,pylint利率这个代码的-21.67 / 10,主要是因为它认为more_methods并related_methods没有self或属性otherfunc,stack,annd my_var因为没有运行的代码,它显然不能看到related_methods和more_methods在混合中implement_methods。 编译器和静态分析工具不能总是解决Halting问题,但是我认为这确实是一种情况,其中查看继承者的内容implement_methods将证明这是完全有效的,并且这很容易做到。 为什么静态分析工具会拒绝这种有效的(我认为)OOP模式? 要么: 他们甚至不尝试检查继承或 不鼓励在惯用且易读的Python中使用mixins #1显然是不正确,因为如果我问pylint告诉我的一类矿井的继承unittest.TestCase使用 self.assertEqual,(仅定义的东西unittest.TestCase),它并没有抱怨。 mixins是unpythonic还是不鼓励使用?

10
即使对象污染了其子类的API,也可以使用强制转换的对象吗?
我有一个基础课,Base。它有两个子类,Sub1和Sub2。每个子类都有一些其他方法。例如,Sub1has Sandwich makeASandwich(Ingredients... ingredients)和Sub2has boolean contactAliens(Frequency onFrequency)。 由于这些方法采用不同的参数并且做的事情完全不同,因此它们是完全不兼容的,我不能仅使用多态来解决此问题。 Base提供了大多数功能,并且我有大量的Base对象集合。但是,所有Base对象都是a Sub1或a Sub2,有时我需要知道它们是什么。 执行以下操作似乎是个坏主意: for (Base base : bases) { if (base instanceof Sub1) { ((Sub1) base).makeASandwich(getRandomIngredients()); // ... etc. } else { // must be Sub2 ((Sub2) base).contactAliens(getFrequency()); // ... etc. } } 因此,我想出了一个避免这种情况的策略。 Base现在有以下方法: boolean isSub1(); Sub1 asSub1(); Sub2 asSub2(); …

7
为什么不继承构造函数?
我对如果构造函数是从基类继承而可能出现的问题感到困惑。Cpp Primer Plus说, 构造函数与其他类方法的不同之处在于它们创建新对象,而其他方法则由现有对象调用。这是构造函数不被继承的原因之一。继承意味着派生的对象可以使用基类方法,但是对于构造函数,该对象直到构造函数完成工作后才存在。 我了解在对象构造完成之前调用了构造函数。 如果子类继承(父类是指子类能够覆盖父类方法等,而不仅仅是访问父类方法),则父构造函数会导致问题吗? 我知道没有必要从代码中显式调用构造函数(尚不知道。),而在创建对象时除外。即使这样,您也可以使用某种机制来调用父构造器(在cpp中,使用::或使用member initialiser list,在java中使用super)。在Java中,在第一行有一个强制调用它,我知道这是要确保首先创建父对象,然后再进行子对象构造。 它可能会覆盖它。但是,我无法提出可能造成问题的情况。如果孩子确实继承了父构造函数,那会出错吗? 这样只是为了避免继承不必要的功能。还是还有更多呢?
33 c++  inheritance 

10
如果可以使用后者,那么“父项x = new Child();”而不是“ Child x = new Child();”是一种不好的做法吗?
例如,我看过一些代码创建了这样的片段: Fragment myFragment=new MyFragment(); 它声明一个变量为Fragment而不是MyFragment,MyFragment是Fragment的子类。我对这行代码不满意,因为我认为该代码应为: MyFragment myFragment=new MyFragment(); 哪个更具体,是真的吗? 还是概括地说,使用以下做法是错误的做法: Parent x=new Child(); 代替 Child x=new Child(); 是否可以在没有编译错误的情况下将前一个更改为后一个?


7
我应该测试继承的方法吗?
假设我有一个从基类Employee派生的类Manager,并且该Employee有一个由Manager继承的方法getEmail()。我是否应该测试经理的getEmail()方法的行为实际上与员工的行为相同? 在编写这些测试时,其行为将是相同的,但是当然在将来的某个时候,有人可能会重写此方法,更改其行为,从而破坏我的应用程序。但是,从根本上测试是否存在干预代码似乎有些奇怪。 (请注意,在创建/覆盖Manager :: getEmail()之前,测试Manager :: getEmail()方法不会提高代码覆盖率(或其他任何代码质量指标(?))。 (如果答案是“是”,则有关如何管理基类和派生类之间共享的测试的一些信息将很有用。) 问题的等价表述: 如果派生类从基类继承方法,则如何表达(测试)是否期望继承的方法: 行为与现在的基础完全相同(如果基础的行为发生了变化,则派生方法的行为不会发生变化); 始终具有与基类完全相同的方式(如果基类的行为发生变化,派生类的行为也发生变化);要么 但是,它要表现出来(您不必关心此方法的行为,因为您从不调用它)。

4
原型继承实际上与经典继承有何不同?
继承,多态性和封装是OOP的三个最不同的重要特征,从它们来看,继承如今具有很高的使用统计。我正在学习JavaScript,在这里,他们都说它具有原型继承,而且各地的人们都说它与经典继承大不相同。 但是,从实际使用的角度来看,我不明白它们有什么区别?换句话说,当您定义基类(原型)然后从中派生一些子类时,您都可以访问基类的功能性对象,并且可以在派生类上扩展功能。如果我们认为我所说的是继承的预期结果,那么为什么我们要使用原型还是经典版本呢? 为了使自己更加清楚,我认为原型继承和经典继承的有用性和使用方式没有区别。这导致我没有兴趣去了解它们为何不同的原因,因为它们都导致同一件事,OOAD。原型继承实际上(不是理论上)与经典继承有何不同?

5
许多小类与逻辑(但)复杂的继承
我想知道在良好的OOP设计,干净的代码,灵活性以及将来避免代码异味方面有什么更好的选择。图像情况,您需要将很多非常相似的对象表示为类。这些类没有任何特定的功能,只是数据类,而只是名称(和上下文)不同而已。示例: Class A { String name; string description; } Class B { String name; String count; String description; } Class C { String name; String count; String description; String imageUrl; } Class D { String name; String count; } Class E { String name; String count; String imageUrl; String age; …

3
是否有没有继承的OO语言?
在今天的代码审查中,我的一位同事说了一些有趣的事情: prototype仅在需要继承时才有用- 何时继承是个好主意? 我考虑了一下,然后意识到,我通常使用继承来解决最初设计不好的代码。现代的OO风格更喜欢使用组合而不是继承,但是我不知道有哪一种语言能够真正做到这一点并真正执行它。 是否有带有类,对象,方法,接口等的通用编程语言,这些语言不允许基于类的继承?(如果这样的想法没有意义,为什么不呢?)

3
具有共同功能的Windows窗体的最佳设计
过去,我使用继承来允许在应用程序中扩展Windows窗体。如果我所有的表单都具有公共控件,插图和功能,那么我将创建一个实现公共控件和功能的基本表单,然后允许其他控件从该基本表单继承。但是,我在设计时遇到了一些问题。 控件一次只能放在一个容器中,因此您拥有的任何静态控件都将很棘手。例如:假设您有一个称为BaseForm的基本表单,其中包含一个TreeView,并对其进行了保护和静态处理,以便此类的所有其他(派生)实例都可以修改和显示相同的TreeView。这对于从BaseForm继承的多个类不起作用,因为TreeView一次只能位于一个容器中。它可能在初始化的最后一个表单上。尽管每个实例都可以编辑该控件,但在给定时间只能显示一个。当然,有一些变通方法,但是它们都很丑陋。(这对我来说似乎是一个非常糟糕的设计。为什么多个容器不能存储指向同一对象的指针?无论如何,它就是它。) 表单之间的状态,即按钮状态,标签文本等,我必须使用全局变量并在Load上重置状态。 Visual Studio的设计师并不能很好地支持此功能。 是否有更好但仍易于维护的设计可供使用?还是形式继承仍然是最好的方法? 更新 从查看MVC到MVP,从观察者模式到事件模式。这是我目前的想法,请批评: 我的BaseForm类将仅包含控件以及与这些控件相关的事件。需要任何逻辑来处理它们的所有事件都将立即传递给BaseFormPresenter类。此类将处理来自UI的数据,执行任何逻辑操作,然后更新BaseFormModel。该模型会将事件(状态更改时将触发)的事件公开给Presenter类,该类将订阅(或观察)该事件。演示者收到事件通知后,它将执行任何逻辑,然后演示者将相应地修改视图。 内存中每个Model类只有一个,但是可能存在许多BaseForm实例,因此有BaseFormPresenter。这将解决我将BaseForm的每个实例同步到相同数据模型的问题。 问题: 哪一层应该存储最后按下的按钮之类的内容,以便我可以在表单之间为用户(例如CSS菜单中)突出显示它? 请批评这个设计。谢谢你的帮助!


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.