通常之间有五个关系:继承(实施),依赖关系,关联,聚合和组合。
继承(实施)
对于课堂,这种关系称为继承。对于接口,此关系称为实现。继承是一种“ IS-A”关系。
依靠
对依赖关系的简单理解意味着A类中的方法使用另一类B。
这种使用关系是偶然的,暂时的,而且非常弱,但是B级的变化会影响A。
例如,当我用笔写作时,我首先需要一个班级来代表自己,然后是代表笔的课程。最后,“我将在“笔”中调用该方法写作,并使用代码实现以下内容:
public class Pen {
public void write(){
System.out.println("use pen to write");
}
}
public class Me {
public void write(Pen pen){//这里,pen作为Me类方法的参数
pen.write();
}
}
---------------------
本文来自 clever_fan 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_31655965/article/details/54645220?utm_source=copy
这是类之间的关系,称为依赖关系。
这种关系是一种非常薄弱的关系,但是笔类的变化可能会影响我的班级结果。例如,如果我更改Pen类写入方法的方法主体,则将其调用后,我会得到不同的结果。 。
一般而言,依赖项反映在Java中,作为局部变量,方法的形式参数或对静态方法的调用。
有关的
该关联反映了两个类别或类和界面之间的语义水平上的强烈依赖性。
这种关系比依赖性更牢固,没有依赖性意外,并且关联不是暂时的,而是长期的,两方之间的关系通常是相等的,并且协会可以是单向或双向。
查看以下代码:
// pen 还是上面的pen
public class You {
private Pen pen; // 让pen成为you的类属性
public You(Pen p){
this.pen = p;
}
public void write(){
pen.write();
}
}
---------------------
本文来自 clever_fan 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_31655965/article/details/54645220?utm_source=copy
相关B类在关联A中作为类属性出现,或者A相关类A是指与类型相关类B类的全局变量的关系,该变量称为关联关系。
在Java中,通常使用成员变量实现关联关系。
聚合
汇总是一种相关关系的特殊情况,它反映了整个部分与财产之间的关系,即“ has-a”之间的关系。
查看以下代码:
public class Family {
private List children; //一个家庭里有许多孩子
// ...
}
---------------------
本文来自 clever_fan 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_31655965/article/details/54645220?utm_source=copy
在代码级别,聚合和关联是一致的,只能与语义级别区分开。在普通的关联关系中,A类和B类之间没有必要的联系,而在汇总中,B类需要成为A类的一部分,并且是一种“ HAS-A”关系,即A HAS-A B;例如,家庭有孩子,房间里有空调。
但是,不一定要有b可以拥有B。 A是整体,B是部门。整体是可分离的。他们可以拥有自己的生命周期。该部分可以属于多个整个对象,也可以由多个整个对象共享。
与关联关系的平等地位不同,聚合关系中这两个类别的状态不平等。
组合
结合也是关联关系的特殊情况。它反映了一种“ -a”关系,该关系比聚集更强,也称为强聚集。
让我们首先看一块代码:
public class Nose {
private Eye eye = new Eye(); //一个人有鼻子有眼睛
private Nose nose = new Nose();
// ....
}
---------------------
本文来自 clever_fan 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_31655965/article/details/54645220?utm_source=copy
组合也反映了整个部分之间的关系,但是目前整体是密不可分的,整个生命周期的终结意味着零件生命周期的终结。
仅查看代码,您就无法区分关联,聚合和组合。具体关系只能与语义级别区分开。
同样,在组合关系中,这两个类之间的关系也不平等。
结合,聚合和继承
每个Java程序都是必不可少的,因此我不会单独讨论它们。普通协会有什么特别的吗?让我们专注于组合,聚合和继承。
聚合和组合
1。聚集和组成都是相关的关系,但它们具有全部的其他含义。
2。组件的不同寿命
(1)在总体关系中,整个部分将没有组件的生命周期,因此,当删除整个零件时,将不会删除组件。此外,多个全部可以共享相同的组件。
(2)在组合关系中,整片具有组件的生命周期,因此,当整个零件被删除时,组件肯定会被删除。此外,多个整个部分不能同时共享相同的组件。
该差异可用于区分关联是组合还是聚集。如果两个类别的生命周期没有同步,那就是聚集关系,生命周期同步是一种组合关系。
(3)聚集关系是[has-a]关系,组合关系是[-a]关系。
当我们仅讨论组合和继承时,我们认为组合是一种[has-a]关系,但实际上,聚集是真正的[has-a]关系,组合是一种更深的[-a]关系。由于[-a]关系是一种更深的[has-a]关系,因此可以说组合是[has-a]关系的正确性。
结合和继承的组合和继承的弊端
组合
优势:
(1)不要破坏包装,而在整个阶层之间松散耦合,彼此相对独立
(2)具有良好的可伸缩性
(3)支持动态组合。在运行时,总体对象可以选择不同类型的本地对象
(4)整个类可以包装本地类,封装本地类的界面并提供新的接口
缺点:
(1)整个类无法自动获得与本地类相同的接口
(2)创建整个类的对象时,您需要创建所有本地类的对象
缺点分析:
1。整个类无法自动获得与本地类相同的接口。
如果几乎暴露了父类的方法子类,则使用组合可能会带来不便,并且使用继承似乎更简单,更方便。但是从另一个角度来看,实际上,这些方法不需要在子类中公开,并且客户端组合应用是足够的。因此,以上建议不是继承不是为继承设计的类。通常,为继承而设计的类是抽象类。
2。创建整个类的对象时,您需要创建所有本地类的对象
可能没有更好的方法可以做到这一点,但是实际应用程序中没有太多额外的代码。
继承
优势:
(1)子类可以自动继承父类的接口。
(2)创建子类的对象时,无需创建父类的对象。
缺点:
(1)销毁封装,在子类和母类之间紧密耦合,子类取决于父类的实现,并且子类缺乏独立性。
(2)支持扩展,但通常以增加系统结构的复杂性为代价。
(3)不支持动态继承动态继承。在运行时,子类无法选择其他父类。
(4)子类无法更改父类的接口。
缺点分析:
1。为什么继承破坏封装?
不需要在鸭中“飞”的方法,但是继承不能封装这种无用的“飞行”方法。
2。为什么继承紧密耦合:
当基本类是父级时,如果要将其修改为方法,则认为此名称是不合适的,那么使用子类对象方法将造成编译错误。您可能会认为这很容易更改,因为重建该工具同时还可以,并且很容易修改编译错误。但是,如果从不同组件中的子类升级组件,维护人员与子类不同,那么可以突然使用的代码无法使用,这仍然很难接受。
3。为什么继承更加复杂?
当书籍和数字产品的税收计算方法与数字产品的税收计算方法相同,并且消费产品的税收计算方法是相同的,如果采用了继承计划,则可能会演变为以下方法:
这样,如果产品继续增加并且税收计算方法继续增加,则继承水平将非常复杂且难以控制,并且使用组合可以很好地解决此问题
4。继承不能支持动态继承
这实际上很容易理解,因为继承是在编译期间确定的,并且在运行时不能更改。例如,在三种情况下,如果用户需要根据本地情况选择税收计算方法,则无法通过使用继承来解决它,并且使用组合和反思可以很好地解决。
5。为什么继承,子类无法更改父类接口
如图2所示,子类认为该方法是不合适的,并且希望使用该方法,因为继承无法更改。
组合与继承或组合之间有什么区别和联系?
首先,它们是重复使用系统功能和重复使用代码的最常用和有效的设计技术,它们都是设计模式中的基础架构。
许多人知道,面向对象的原则相对重要:“使用更多的组合并使用较少的继承”或“组合比继承更好”。从上一个介绍中,我们还可以看到,组合确实比继承更灵活,并且对代码维护更有帮助。
因此,建议在同样可行的情况下使用组合而不是继承。因为组合更安全,更简单,更灵活,更有效。
请注意,继承并不意味着它根本没有用。我之前所说的是[同样可行的时候。有些情况仍然需要继承,或者更适合继承。
继承应谨慎使用,其使用情况仅限于您确定该技术有效的情况。判断的一种方法是问自己是否需要从新课程转变为基础班。如有必要,需要继承。相反,您应该仔细考虑是否需要继承。
仅当子类真正是超级类的亚型时,继承才是合适的。换句话说,对于两个A和B类,B类应仅在两者之间存在IS-A关系时继承A类。
总结
根据我们之前所说的话,我们可以发现继承的缺点远胜于优势。尽管在学习OOP的过程中已经强调了继承,但这并不意味着应尽可能多地使用它。相反,使用时要特别小心。
只有在所有方法中都显然是最有效的,才能考虑使用。继承的最大优势是扩展很简单,但是大多数缺点是致命的。但是,由于这种扩展的优势太明显了,因此许多人对此没有深入思考,因此他们会造成太多问题。
最后,让我们总结一下:
1。专门为继承的精心设计课程。继承树的抽象层应相对稳定,通常不超过三层。
2。对于不专门用于继承的类,禁止其继承。
3。优先使用组合关系来改善代码的可重复性。
4。子类是一种特殊类型,而不仅仅是父级的角色。
5。子类扩展,而不是覆盖或无效父母类的功能。