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/