Java Top.

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程

1.概述

遗产而组合——以及抽象、封装和多态——是面向对象编程(OOP)。

在本教程中,我们将介绍继承和组合的基础知识,并将重点关注于发现两种类型的关系之间的差异。

2.继承的基础知识

继承是一种强大但被滥用和误用的机制。

简单地说,通过继承,基类(也就是基类型)定义了给定类型的状态和行为公共,并让子类(也就是子类型)提供该状态和行为的专门化版本。

要清楚地了解如何使用继承,让我们创建一个天真的榜样:一个基类这定义了一个人的公共字段和方法,而子类女服务员女演员提供额外的细粒度方法实现。

这是这一点类:

公共班人{私人最终字符串名称;//其他字段,标准构造函数,getters}

这些是子类:

公共类女服务员扩展人员{公共字符串serveStarter(String Starter){返回“+ starter;} //其他方法/构造函数}
公共类女演员扩展人员{公共字符串READScript(String Movie){return“读取”+电影的脚本;} //其他方法/构造函数}

此外,让我们创建一个单元测试来验证该单元的情况女服务员女演员课程也是从而显示“是”条件在类型级别满足:

@Test public void givenWaitressInstance_whenCheckedType_thenIsInstanceOfPerson() {assert (new Waitress("Mary", "Mary"), "(电子邮件保护)“,22)).isinstanceof(person.class); @test public voidedactressinstance_whencheckedtype_thenisinstanceofperson(){assertthat(新女演员(”苏珊“,”(电子邮件保护)”,30)).isInstanceOf (Person.class);}

在这里强调遗产的语义方面很重要。控件的实现除了重用之外人类我们创造了一个明确的“是”的关系在基类型之间和亚型女服务员女演员。女服务员和女演员实际上都是人。

这可能会导致我们问:在哪些用例中继承是正确的方法?

如果亚型符合“是”条件,并且主要提供进一步的附加功能,因此在类层级中提供添加功能,那就继承吧。

当然,只要覆盖方法保留促进的基础类型/亚型取代性,就允许使用方法覆盖Liskov替换原则

此外,我们应该记住子类型继承了基本类型的API,在某些情况下可能是过度的或仅仅是不受欢迎的。

否则,我们应该使用组成。

3.在设计模式中遗传

虽然共识是我们应该有利于尽可能过继承的组合,但遗产有一些典型用例。

3.1。层超类型模式

在这种情况下,我们使用继承将公共代码移动到基类(SuperType),以每层为基础

下面是这个模式在领域层的基本实现:

公共班实体{受保护的Long ID;// setter}
公共类用户扩展实体{//其他字段和方法}

我们可以将相同的方法应用到系统中的其他层,如服务层和持久层。

3.2。模板方法模式

在模板方法模式中,我们可以使用基类来定义算法的不变部分,然后在子类中实现变体部件

公共抽象类ComputerBuilder {Public Final Computer BuildComputer(){addProcessor();addmemory();}公共抽象void addProcessor();公共抽象void addmemory();}
公共类StandicComputerBuilder扩展了ComputerBuilder {@override public void addprocessor(){//方法实现} @override public void addmemory(){//方法实现}}

4.作文的基础知识

该组合物是OOP提供的另一种机制,用于重用实施。

简而言之,组成允许我们模拟由其他对象组成的对象,从而定义它们之间的“具有”关系。

此外,该组合物是最强的形式协会,这意味着组成或包含一个对象的对象也会在该对象被销毁时被销毁

为了更好地了解构图工作原理,让我们假设我们需要使用代表计算机的对象

计算机由不同的部分组成,包括微处理器、内存、声卡等等,因此我们可以把计算机和它的每个部分都建模为单独的类。

下面是一个简单的实现电脑类可能是:

公共类计算机{私有处理器处理器;私有内存记忆;私人的声卡声卡;//标准的getter /setter /构造函数public可选 getsondcard () {return Optional. ofnullable (SoundCard);}}

以下类模型进行微处理器,存储器和声卡(为简洁起见省略接口):

公共类StartalProcessor实现处理器{私有字符串模型;//标准getters / setter}
公共类StandardMemory实现内存{私有字符串品牌;私有字符串大小;//标准构造函数,getters,toString}
public class StandardSoundCard implements SoundCard {private String brand;//标准构造函数,getters,toString}

很容易理解推动推动构成的动机。在每个可能在给定类和其他类之间建立语义上正确的“have -a”关系的场景中,组合都是正确的选择。

在上面的例子中,电脑符合模拟其部件的类的“具有”条件。

在这种情况下,它也值得注意,包含电脑对象具有包含对象的所有权如果并且只有对象不能在其他对象中重用电脑对象。如果他们可以,我们将使用聚合,而不是组合,在那里不暗示所有权。

5.没有抽象的组成

或者,我们可以通过硬编码依赖性来定义组合关系电脑类,而不是在构造函数中声明它们:

public class Computer {private StandardProcessor processor = new StandardProcessor("Intel I3");private StandardMemory memory = new StandardMemory("Kingston", "1TB");//附加字段/方法}

当然,这将是一个刚性,紧密的设计,我们正在制作电脑强烈依赖于的特定实现处理器记忆

我们不会利用接口和提供的抽象级别依赖注入

利用基于接口的初始设计,我们获得了一个松散耦合的设计,这也更容易测试。

六,结论

在本文中,我们学习了Java中的继承和组合的基础知识,并深入探讨了两种关系类型(“is-a”和“have -a”)之间的区别。

和往常一样,本教程中显示的所有代码示例都是可用的在GitHub

Java底部

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程
本文评论关闭!