- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
组合和继承。
我知道它们都是在适当时选择的工具,并且上下文对于在组合和继承之间进行选择非常重要。然而,关于每种情况的适当上下文的讨论通常有点模糊。这让我开始考虑继承和多态是传统 OOP 的不同方面有多么明显。
多态性允许人们平等地指定“is-a”关系以及继承。特别是,从基类继承隐含地在该类与其子类之间创建了多态关系。然而,虽然多态可以使用纯接口(interface)来实现,但继承通过同时传递实现细节使多态关系复杂化。通过这种方式,继承与纯多态完全不同。
作为一种工具,继承通过简化实现重用为程序员提供不同于多态性(通过纯接口(interface))的服务。在琐碎的情况下 .然而,在大多数情况下,父类(super class)的实现细节与子类的要求存在微妙的冲突。这就是我们有“覆盖”和“成员隐藏”的原因。在这些情况下,继承提供的实现重用是通过验证状态更改和跨级联代码级别的执行路径的额外努力来购买的:子类的完整“扁平化”实现细节分布在多个类之间,这通常意味着多个文件,其中只有部分适用于所讨论的子类。在处理继承时,查看该层次结构是绝对必要的,因为如果不查看父类(super class)的代码,就无法知道哪些未覆盖的细节会影响您的状态或转移您的执行。
相比之下,组合的独占使用保证您将看到哪些状态可以被显式实例化的对象修改,这些对象的方法由您自行决定调用。仍然没有实现真正扁平化的实现(实际上甚至是不可取的,因为结构化编程的好处是实现细节的封装和抽象)但是您仍然可以重用代码,并且您只需要查看一个地方当代码行为不端时。
为了在实践中测试这些想法,避免传统的继承以结合纯基于接口(interface)的多态性和对象组合,我想知道,
有什么对象组合和接口(interface)不能实现继承可以吗?
编辑
在迄今为止的答复中,ewernli 认为没有一种技术可以用于技术专长,而另一种则没有。他后来提到了每种技术所固有的不同模式和设计方法。这是有道理的。但是,该建议使我通过询问排他使用组合和接口(interface)来代替传统继承是否会禁止使用任何主要设计模式来完善我的问题?如果是这样,在我的情况下没有等效的模式吗?
最佳答案
从技术上讲,所有可以通过继承实现的东西也可以通过委托(delegate)来实现。所以答案是“不”。
将继承转化为委托(delegate)
假设我们有以下通过继承实现的类:
public class A {
String a = "A";
void doSomething() { .... }
void getDisplayName() { return a }
void printName { System.out.println( this.getDisplayName() };
}
public class B extends A {
String b = "B";
void getDisplayName() { return a + " " + b; }
void doSomething() { super.doSomething() ; ... }
}
printName
在 B 的实例上将打印
"A B"
在控制台中。
public class A {
String a = "A";
void doSomething() { .... }
void getDisplayName() { return a }
void printName { System.out.println( this.getName() };
}
public class B {
String b = "B";
A delegate = new A();
void getDisplayName() { return delegate.a + " " + b; }
void doSomething() { delegate.doSomething() ; ... }
void printName() { delegate.printName() ; ... }
}
printName
在 B 中,并在实例化 B 时创建委托(delegate)。调用
doSomething
将以与继承类似的方式工作。但是调用
printName
将打印
"A"
在控制台中。实际上,通过委托(delegate),我们失去了“this”绑定(bind)到对象实例和能够调用已被覆盖的方法的基本方法的强大概念。
this.getName()
will 启动类 B 的方法分派(dispatch)。我们实现与继承相同的方法。这是
prototype-based 中使用的机制语言如
Self具有委托(delegate)功能的内置功能(您可以阅读
here Self 中的继承如何工作)。
public class A implements AInterface {
String a = "A";
AInterface owner; // replace "this"
A ( AInterface o ) { owner = o }
void doSomething() { .... }
void getDisplayName() { return a }
void printName { System.out.println( owner.getName() };
}
public class B implements AInterface {
String b = "B";
A delegate = new A( this );
void getDisplayName() { return delegate.a + " " + b; }
void doSomething() { delegate.doSomething() ; ... }
void printName() { delegate.printName() ; ... }
}
hashCode
和
equals
如果使用继承。但另一方面,它仍然是解决一些问题的一种非常优雅的方式。
Inheritance and delegation are alternate methods for incremental definition and sharing. It has commonly been believed that delegation provides a more powerful model. This paper demonstrates that there is a “natural” model of inheritance which captures all of the properties of delegation. Independently, certain constraints on the ability of delegation to capture inheritance are demonstrated. Finally, a new framework which fully captures both delegation and inheritance is outlined, and some of the ramifications of this hybrid model are explored.
One of the most intriguing—and at the same time most problematic—notions in object-oriented programing is inheritance. Inheritance is commonly regarded as the feature that distinguishes object-oriented programming from other modern programming paradigms, but researchers rarely agree on its meaning and usage. [...]
Because of the strong coupling of classes and the proliferation of unneeded class members induced by inheritance, the suggestion to use composition and delegation instead has become commonplace. The presentation of a corresponding refactoring in the literature may lead one to believe that such a transformation is a straightforward undertaking. [...]
关于oop - 有什么组合不能实现继承可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2238642/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 4年前关闭。 Improve t
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
在面向对象的编程中,“基类”是派生其他类的类(http://en.wikipedia.org/wiki/Base_class)。 但是,基类的反面是什么?换句话说,什么是没有任何子类的类? 编辑:我正
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 8年前关闭。 Improve this questi
据我了解,OOP 是大型项目最常用的范式。我也知道大系统的一些较小的子集使用其他范式(例如 SQL,它是声明性的),并且我也意识到在较低级别的计算 OOP 并不真正可行。但在我看来,通常更高级别的解决
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
最近听说OOP(Java)有9条规则。我只知道四种:抽象、多态、继承和封装。 OOP 还有更多规则吗? 最佳答案 看来您正在寻找的是 Principles of Object-Oriented Des
我曾经在一次采访中被问到“OOP 的 3 个主要概念是什么?”。我回答说,我认为有4个,如下: 继承 封装 抽象 多态性 我说得对吗? 最佳答案 语言要成为面向对象有3个要求: 仅支持封装(对象)的语
我有一个关于特定 OOP 问题的组织的简单问题。 假设我有一个地形类,里面充满了瓷砖。 Tile 类有多个派生类,即 Door。 Door 类有一个名为 open() 的方法,用于打开门,还有一个名为
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
我是 Go 的新手,然后我通过示例搜索了很多如何拥有带有静态函数/变量的静态类,例如 C#。但是,我找不到任何可以很好地回答它的东西。也许这个问题看起来很愚蠢,但我不喜欢不确定或不完全理解某事。 假设
我曾尝试搜索此问题的答案,但很难用语言表达,而且许多问题要么是关于如何创建类,要么是关于如何做非常具体的事情。我需要更多的实用概述 - 我是自学成才的,我了解对象是什么(以及如何创建它们),但我从未见
在开始编码之前,我通常会尝试在没有太多分析(没有图表)的情况下进行 TDD。通常我发现自己将一个类拆分为其他类以分离关注点。我想知道更深入的分析是否会阻止这种情况。我认为大部分面向对象分析无法预测其中
在阅读单例时,我发现这个解释是使用单例的原因: since these object methods are not changing the internal class state, we can
如这里所述 https://standardofnorms.wordpress.com/2012/09/02/4-pillars-of-object-oriented-programming/ 并作为
我是这个网站的新手,所以如果我在发布问题时做错了什么,请告诉我,以便我下次修复。 我很好奇从单个基类继承多个类是否是糟糕的 OOP 实践。这可能不太合理,所以我要详细说明一下。 例如,假设您正在设计一
我对“工厂相关”设计模式及其 OOP 实现的理解一直很简单。 一个 《工厂法》是类内部的一个方法,它有一个接口(interface)(或抽象类)作为返回类型,并根据一些内部逻辑构造实现该接口(inte
C# 中的“密封”关键字,Java 中的 Final。 因为我几乎从不创建任何图表并且我只使用已经完成的类(来自框架)我多年后仍然不知道为什么有人会“锁定”一个类所以它永远不会被扩展/继承。 它是有益
我正在研究面向对象的概念,抽象概念基本上被描述为对用户隐藏实现。因此,如果类中有一个成员函数并且我们为某些任务调用该函数,抽象表示用户不应该关心事情是如何完成的,而应该只知道正在完成什么。但即使在非面
我是一名优秀的程序员,十分优秀!