java:inheritance

inheritance有哪些替代方案?

有效的Java:支持组合而不是inheritance。 (这实际上也来自Gang of Four)。

他提出的情况是,如果扩展类没有明确地设计为inheritance,那么inheritance会导致许多不合适的副作用。 例如,对super.someMethod()任何调用都会引导您通过未知代码的意外路径。

相反,请保留对您本来可以扩展的类的引用,并委托给它。

这是与Erich Gamma的访谈的链接,他在那里谈论了这个概念。

一些替代品:

  • 代表团 ,也称为Composition
  • 维基百科关于限制和inheritance替代方案的文章
  • 问:inheritance似乎容易出错。 我该如何防范这些错误? 而且,有哪些替代方案?

我假设你正在玩Java,它有一些关于inheritance的规则。

实现接口是一种常见且经常使用的选项。 因此,例如,如果您有一个与RDBMS对话的数据源类,而不是inheritance该类并使用它来实现NoSQL数据源,则两者都可以实现相同的接口。

而不是..

 public class RDBMSDataSource { ... public String loadSomeDataFromDataSource() { ...Do some stuff... } } public class NoSQLDataSource extends RDBMSDataSource { ... @Override public String loadSomeDataFromDataSource() { ...Do some other stuff... } } public class DataSourceClient { public void foo() { RDBMSDataSource ds = new NoSQLDataSource(); ds.loadSomeDataFromDataSource(); } } 

哪个有效,但很难读,你可以用这个…

 public interface DataSource { public String loadSomeDataFromDataSource(); } public class RDBMSDataSource implements DataSource { ... public String loadSomeDataFromDataSource() { ...Do some stuff... } } public class NoSQLDataSource implements DataSource { ... @Override public String loadSomeDataFromDataSource() { ...Do some other stuff... } } public class DataSourceClient { public void foo() { DataSource ds = new NoSQLDataSource(); ds.loadSomeDataFromDataSource(); } } 

另一种选择是组合。 假设您有员工和客户。 你的两个选择是……

 public class Person { protected String name; protected String address; ...More stuff... } public class Employee extends Person { protected String jobCode; protected String department; ...More stuff... } public class Customer extends Person { protected String salesPerson; protected Date registrationDate; ...More stuff... } 

…要么…

 public class ContactInfo { private String name; private String address; ...More stuff... } public class Employee { private ContactInfo contactInfo; private String jobCode; private String department; ...More stuff... } public class Customer { private ContactInfo contactInfo; private String salesPerson; private Date registrationDate; ...More stuff... } 

由于Java没有多重inheritance并且您可以实现多个接口,因此有时您需要执行上述操作以确保您的开发是干净且可读的。

我意识到这不是Java 本身 ,但Scala(在Java虚拟机上运行的语言)允许mixins (在Scala中称为traits )。

Mixins允许您将一些function现有类一起插入,而不是在inheritance树中。

当一个类包含一个mixin时,该类实现了接口,并包含而不是inheritance了mixin的所有属性和方法。 他们在编译期间成为class级的一部分

委托是inheritance的替代方案。

我认为你应该尝试委托,委托是inheritance的替代方案。 委派意味着您另一个类的实例包含为实例变量。 它起着有益的作用,它不会强迫你接受超类的所有方法。

尝试委托,也称为组合

还发现了新的替代品mixin

mixins是一种可组合的抽象类。 它们在多inheritance上下文中用于向类添加服务。 多inheritance用于根据需要使用尽可能多的mixin组成您的类。 例如,如果您有一个代表房屋的类,您可以从此类创建房屋,并通过inheritanceGarage和Garden等类来扩展它。 这是用Scala编写的这个例子:

val myHouse =带花园的新房子

您将获得有关mixin的更多信息https://kerflyn.wordpress.com/2012/07/09/java-8-now-you-have-mixins/