java中类与类之间的关系讲解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中类与类之间的关系讲解相关的知识,希望对你有一定的参考价值。
1.关联关联即对象与对象之间的连接。java类之间的关联是一个类的作为另一个的属性被定义,即“has-a”的关系。关联又分为组合与聚合两种。示例如下:
//两个类之间的聚合public class Carpublic class Person
private Car car;
//两个类之间的组合public class Carpublic class Person
private Car car=new Car();//创建一个Car对象123456789101112
关联又分为单向关联与双向关联,以上代码为单向关联(Person类关联Car类),双向关联(Person类关联Car类,同时Car类关联Person类)代码如下:
public class Car
private Person per;
public class Person
private Car car;
123456
类之间的关联,可以一对一的关联,也可以一对多的关联。
2.依赖
依赖的具体表现是将一个类的对象当做方法参数传给另一个类的方法,是一种use-a的关系。如:
public class Person
public void dirve(Car car)
1234
关联与依赖的区别在于:关联是has-a的关系,依赖是use-a的关系;而且关联中Person关联Car,只要Person类对象存在,Car对象就存在;依赖中只有Person类对象调用到dirve()方法时,Car对象才会被创建,方法执行结束后,Car对象就被收回。
3.继承
类与类的另一个关系是继承。继承是一个类的定义基于另一个存在的类,即子类基于父类,如此可实现代码的重用,子类能够继承父类可访问的方法、属性,并能扩展新的能力,而且子类可重写父类方法以满足子类需要。在继承中子类可调用父类的构造方法,子类构造方法总是先调用父类的构造方法,而且默认情况下调用父类的无参构造方法,在子类构造方法的第一行使用super关键字即可调用父类构造方法。示例代码如下:
public class Point
private double x; private double y; public double getX() return x;
public void setX(double x) this.x = x;
public double getY() return y;
public void setY(double y) this.y = y;
//无参构造方法
public Point()
//有参构造方法
public Point(double x, double y) this.x = x; this.y = y;
//draw()方法
public void draw()
public class Circle extends Point
private double r; public double getR() return r;
public void setR(double r) this.r = r;
//有参构造方法
public Circle(double x, double y) super(x, y);
public void draw()
System.out.println("半径为:" + this.r + " x坐标为:" + getX() + " y坐标为:" + getY() + "的圆绘制成功!");
public class Test
public static void main(String[] args)
Circle circle = new Circle(2, 3);
circle.setR(3);
circle.draw();
参考技术A 1、继承关系
2、实现关系
3、依赖关系
4、关联关系
5、聚合关系
6、组合关系
Python设计模式 - 基础 - 类与类之间的六种关系
在程序中需要把世间万物抽象成相应的类,现实世界中物与物之间的关系和程序中类与类之间的关系相对应,因为世间万物是普遍联系的,所以程序中类与类之间也不是孤立的。在系统分析和框架设计中,根据面向对象机制的三大特性:封装、继承、多态,归纳和扩展出类与类之间六种不同的关系:
- 依赖关系Dependency: 在局部变量,方法的形参,或者对静态方法的调用中实现
- 关联关系Association: 在类的成员变量中实现,可以双向也可以单向
- 聚合关系Aggregation: 强关联,整体与部分的关系,但是可分离
- 组合关系Composition: 更强关联,整体与部分的关系,不可分离
- 继承关系Generalization:类与类,或接口与接口之间的父子关系
- 实现关系Implementation: 接口或抽象类定义好的操作集合,由实现类完成接口或抽象类的具体操作
其实从更宽泛的角度来说,类与类之间的关系其实只有三种:继承、实现、关联(依赖是一种弱关联,聚合和组合是关联中的特例)。继承和实现是类与类之间的纵向关系,比如A类继承了B类,C类实现了D接口;而关联是类与类之间的横向关系,类与类之间的关联关系从弱到强依次为:依赖 < 关联 < 聚合 < 组合。
纵向的继承和实现关系很容易理解,横向的关联关系相对复杂些,尤其是对生命周期的不同处理,关联、聚合、组合只能结合上下文语义才好判断。下面就重点介绍下这些容易相互混淆的关联关系。
依赖关系(Dependency)
概念说明
可以简单地理解,依赖就是一个类A使用到了另一个类B,仅仅是“使用到”,类B本身并不属于类A,或者说类A并不拥有类B。依赖关系是偶然性的、临时性的,但是因为类B本身被类A引用到,所以B类的变化也会影响到类A。比较常见的场景就是人乘飞机从一地到另一地,飞机和人之间并没有所属关系,只是一种临时性的出行工具,此时人和飞机之间就是依赖关系。
代码实现
依赖关系在代码上体现为三种形式:
- 类B作为类A方法的形参
- 类B作为类A方法的局部变量
- 类A调用类B的静态方法
# 类B作为类A方法的形参 class Person(object): def flying(self, plane): plane.fly() class Plane(object): def fly(self): print ("The plane is flying.") >>> person = Person() >>> plane = Plane() >>> person.flying(plane) The plane is flying. >>>
# 类B作为类A方法的局部变量 class Person(object): def flying(self): self.plane = Plane() plane.fly() class Plane(object): def fly(self): print ("The plane is flying") >>> person = Person() >>> person.flying() The plane is flying. >>>
# 类A调用类B的静态方法 class Person(object): def flying(self): Plane.fly() class Plane(object): @staticmethod def fly(): print ("The plane is flying.") >>> person = Person() >>> person.flying() The plane is flying. >>>
UML类图
UML中使用带箭头的虚线表示,箭头指向表示调用关系,从类A指向类B
关联关系(Association)
概念说明
关联关系一般长期性的、拥有性的关系,而且双方的关系一般是平等的,如学校与学生之间、老师与学生之间。被关联类B以类的属性形式出现在关联类A中,关联可以是单向的,也可以是双向的。
依赖关系与关联关系的区别有动静之分,依赖关系的偶然性和临时性说明了动态性,关联关系的长期性、拥有性静态地展示了对被关联类的引用。
代码实现
关联关系在代码上体现为四种形式:
- 单向关联:单向拥有关系,只有一个类知道另一个类的属性和方法
- 双向关联:双向拥有关系,双方都知道对方的属性和方法
- 自身关联:自己关联自己,这种情况比较少但也有用到,如链表
- 多重性关联:表示两个类的对象在数量上的对应关系,多重性可在关联线上用数字范围表示
multiplicity: 多重性
1 仅为1
* 从0到无穷大
0..1 0 或者 1
n..m [n, m]之间的任何数
# 单向关联
class Student(object): def __init__(self): self.title = "Seno"
def study(self): print ("Studying...") class School(object): def __init__(self): self.address = "ABC Street" self.student = Student() def act(self): print (self.student.title) self.student.study() >>> school = School() >>> school.act() Seno Studying... >>>
# 双向关联
class Student(object): def __init__(self): self.school = School() class School(object): def __init__(self): self.student = Student()
# 自身关联 class Node(object): def __init__(self): self.next = Node()
UML类图
UML中使用直线箭头表示,箭头指向为被关联的类,从类A指向类B
单向关联
双向关联
自我关联
多重性关联
聚合关系(Aggregation)
概念说明
聚合关系是也是关联关系的特例。普通关联关系的两个类一般处于同一平等层次上,而聚合关系的两个类处于不同的层次,是整体与部分的关系。聚合关系中的整体和部分是可以分离的,生命周期也是相互独立的,如公司与员工之间。
代码实现
聚合关系在代码上体现为:类A由类B聚合而成,类A包含有类B的全局对象,但类B的对象可以不在类A创建的时刻创建。
class School(object): def __init__(self): self.__students = [] def add_student(self, student): self.__students.append(student) class Student(object): pass >>> student = Student() >>> school = School() >>> school.add_student(student) >>>
UML类图
UML中使用空心菱形+实线箭头表示,空心菱形边指向类A(整体),实现箭头边指向部分类B(部分)
组合关系(Composition)
概念说明
组合关系也是关联关系的特例,属于强聚合,本身也表示整体与部分的关系,但是组合关系中的整体和部分是不可分离的,整体生命周期的结束时也是部分的生命周期到头时。如人和大脑。
聚合和组合其实都是关联的特例,都是整体与部分的关系。它们的区别在于整体和部分是否可分离,聚合的两个对象之间是可分离的,且具有各自的生命周期,而组合的两个对象往往表现为一种同命相连的关系。
代码实现
组合关系在代码上体现为在整体类的构造方法中直接实例化成员类,因为类组合关系中整体与部分是共生的。
class Person(object): def __init__(self): print ("Person Iinitialization Start") self.__brain = Brain() print ("Person Iinitialization End") def run(self): print ("Running...") class Brain(object): def __init__(self): print ("Brain Initialization Start") print ("Brain Initialization End") >>> person = Person() Person Iinitialization Start Brain Initialization Start Brain Initialization End Person Iinitialization End >>> person.run() Running... >>>
UML类图
UML中使用实心菱形+实线箭头表示,实心菱形边指向类A(整体),实线箭头边指向类B(部分)
继承关系(Generalization)
概念说明
继承指的是子类继承父类、或子接口继承父接口的功能并增加自己新功能的过程,是两个类之间耦合度最大的关系之一。父类称为基类或超类,子类也称为派生类。子类可以继承自抽象类或普通类。
代码实现
继承关系在代码上体现为二种形式:
- 子类继承自抽象类或普通类
- 子接口继承自父接口:适用于Java
# 子类继承自抽象类,必须实现父类中@abstractmethod修饰的抽象方法
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta): def __init__(self): self.name = "Animal" @abstractmethod def run(self): print ("Animal is running.") def play(self): print ("Animal is playing.") class Dog(Animal): def __init__(self): self.name = "Dog" def run(self): print ("Dog is running.") def __bark(self): print ("Dog is barking.") class Cat(Animal): def __init__(self): self.name = "Cat" def run(self): print ("Animal is running.") def play(self): print ("Cat is running.") def __jump(self): print ("Cat is jumping.") >>> dog = Dog() >>> cat = Cat() >>> dog.run() Dog is running. >>> dog.play() Animal is playing.>>> cat.run() Animal is running. >>> cat.play() Cat is running.>>>
# 子类继承自普通类,子类方法重写父类同名非私有方法
class Animal(object): def __init__(self): self.name = "Animal" def run(self): print ("Animal is running.") def play(self): print ("Animal is playing.") class Dog(Animal): def __init__(self): self.name = "Dog" def run(self): print ("Dog is running.") def __bark(self): print ("Dog is barking.") class Cat(Animal): def __init__(self): self.name = "Cat" def play(self): print ("Cat is running.") def __jump(self): print ("Cat is jumping.") >>> dog = Dog() >>> cat = Cat() >>> dog.run() Dog is running. >>> dog.play() Animal is playing.>>> cat.run() Animal is running. >>> cat.play() Cat is running.>>>
UML类图
UML中使用实线+空心箭头表示,箭头由子类指向父类、或子接口指向父接口
实现关系(Implementation)
概念说明
实现关系是指一个类实现一个或多个接口功能的过程,这里的接口更多的是一种契约或规范。实现是两个类之间或类与接口之间耦合度最大的关系之一,在这种关系中,类实现了接口或接口类中所声明的操作。
代码实现
实现关系在代码上体现为二种形式:
- 类具体实现接口中所声明的操作:如Java中支持原生interface,可以直接implement
- 类具体实现接口类中所声明的操作:如python中无原生interface,这里的接口类更多的是逻辑上的契约或规范
class Car(object): def engine(self): raise NotImplementedError class Benz(Car): def engine(self): print ("Benz is running.") class BMW(Car): def engine(self): print ("BMW is running.") >>> benz = Benz() >>> bmw = BMW() >>> benz.engine() Benz is running. >>> bmw.engine() BMW is running. >>>
UML类图
UML中使用虚线+空心箭头表示,箭头由实现类指向接口
以上是关于java中类与类之间的关系讲解的主要内容,如果未能解决你的问题,请参考以下文章
java中类与类之间的关系有依赖和继承,那么这两种关系哪个效率高?
java中GregorianCalendar类与Calendar类的关系与区别?