java中类的关系的总结

类和类之间存在多种关系,而这种关系在我们的代码中司空见惯,有时多种类关系很难区分
(由于水平有限,没有画出类的关系图,关系图可以参考参考链接)

  • 继承关系
    继承是指一个子类(子接口)继承父类(父接口)然后拓展子类的功能

  • 实现关系
    实现是指一个类实现接口(或多个接口)在java中很常见

  • 依赖关系

,依赖就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。
表现在代码层面,为类B作为参数被类A在某个method方法中使用。(函数的引用传递)

  • 关联关系
    关联体现的是两个类之间语义级别的一种强依赖关系,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量,如有一个人有一本书,一本书属于一个人,在人这个类中如果没有书这个属性,并不影响人这个类的完整性,同样书这个类中没有人这个属性也不影响书的完整性,他们之间仅仅是一种关联的关系

关联关系举例

//描述类中的关联关系
//以书和人为例子 表现相关关联
class Book{
	private String name;//书名
	private String author;//作者
	private Person person;//该书的拥有者
	
	//构造方法为该书的属性赋值
	public Book(String name,String author){
		setName(name);
		setAuthor(author);
	}
	public String getName(){
		return this.name;
	}
	public String getAuthor(){
		return this.author;
	}
	//获得该书的拥有者
	public Person getPerson(){
		return person;
	}
	public void setName(String name){
		this.name=name;
	}
	public void setAuthor(String author){
		this.author=author;
	}
	//设置该书的拥有者
	public void setPerson(Person person){
		this.person=person;
	}
	
}

//定义Person类
class Person{
	private String name;//姓名
	private int age;//年龄
	private Book book;//该人所拥有的书
    public Person(){};
	//构造方法为人的属性赋值
	public Person(int age,String name){
		setAge(age);
		setName(name);
	}
	public int getAge(){
		return this.age;
	}
	public String getName(){
		return this.name;
	}
	public Book getBook(){
		return book;
	}
	public void setAge(int age){
		this.age=age;
	}
	public void setName(String name){
		this.name=name;
	}
	public void setBook(Book book){
		this.book=book;
	}
	

}


//测试类
public class AssociationTest{
	public static void main(String[]args){
		//分别实例化人和书
		Book book1=new Book("java编程思想","seefeccve");
		Person per1=new Person(23,"刘涛");
		
		//设置书和人双向对应的关系
		per1.setBook(book1);//设置该人的书
		book1.setPerson(per1);//设置该书属于什么人
		System.out.println("通过人找到书: 姓名:"+per1.getName()+"年龄:"+per1.getAge()+"书名"+per1.getBook().getName()+"作者"+per1.getBook().getAuthor());
		System.out.println("通过书找到人: 书名:"+book1.getName()+"作者:"+book1.getAuthor()+"拥有者:"+book1.getPerson().getName()+"年龄:"+book1.getPerson().getAge());
		
	}
	
}


虽然说构造方法的作用是设置类中的属性,但在该处比较特殊,Book类中的person ,Person 类中的book的设置并没有用构造方法而是单独设置

  • 解释1
    构造方法的是将类的属性进行设置,但该处的book和person虽然属于该类但与该类仅仅是关联关系,意思是如果没有该属性,该类依然完整,如果一个人没有书,难道就不是一个人了吗,一本书如果没有一个拥有者难道就不是一本是了吗,如果用构造方法设置才显得突兀了

  • 解释2
    我们还需要设置这两个类的关系,如果将book和person都放在构造方法中初始化就无法表示这种关系了,想想一下,初始化Book 需要传入一个person对象,而得到person对象又要Book对象,但Book对象还没有实现呢,反过来也是一样,这样2者都无法实现

  • 聚合关系

聚合是关联关系的一种特例,它体现的是整体与部分的关系,即has-a的关系。此时整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。思考一下继承的关系是不是可以用has-a的关系来表示
举例说明

一个人有一个孩子,每个孩子有一本书

//描述聚合关系
//一本书属于一个人 一个人有一本书(关联关系)
//一个孩子 有一本书 一个人有一个孩子


class Book{
	private String name;//书名
	private String author;//作者
	private Person person;//该书的拥有者
	
	//构造方法为该书的属性赋值
	public Book(String name,String author){
		setName(name);
		setAuthor(author);
	}
	public String getName(){
		return this.name;
	}
	public String getAuthor(){
		return this.author;
	}
	//获得该书的拥有者
	public Person getPerson(){
		return person;
	}
	public void setName(String name){
		this.name=name;
	}
	public void setAuthor(String author){
		this.author=author;
	}
	//设置该书的拥有者
	public void setPerson(Person person){
		this.person=person;
	}
	
}

class Person{
	private String name;//姓名
	private int age;//年龄
	private Book book;//该人有一本书
	private Person child;//该人有一个孩子
	public Person(){};
	public Person(String name,int age){
		setName(name);
		setAge(age);
	}
	public String getName(){
		return this.name;
	}
	public int getAge(){
		return this.age;
	}
	public Book getBook(){
		return book;
	}
	public Person getChild(){//注意该处返回类型
		return child;
	}
	public void setName(String name){
		this.name=name;
	}
	public void setAge(int age){
		this.age=age;
	}
	public void setBook(Book book){
		this.book=book;
	}
	public void setChild(Person child){//注意该处的参数类型
		this.child=child;
	}
	
}

//测试类
public class Aggregation{
	public static void main(String[]args){
		Book book1=new Book("java开发","张三");
		Person per1=new Person("大刘",34);
		Person child1=new Person ("小刘",2);
		//关系设置
		book1.setPerson(per1);//该书属于一个人
		per1.setBook(book1);//该人拥有一本书
		child1.setBook(book1);//没有孩子拥有一本书
		per1.setChild(child1);//一个人拥有一个孩子
	    
		//验证关联关系
			System.out.println("通过人找到书: 姓名:"+per1.getName()+"年龄:"+per1.getAge()+"书名"+per1.getBook().getName()+"作者"+per1.getBook().getAuthor());
		System.out.println("通过书找到人: 书名:"+book1.getName()+"作者:"+book1.getAuthor()+"拥有者:"+book1.getPerson().getName()+"年龄:"+book1.getPerson().getAge());
		//验证聚合关系
	    System.out.println("通过人找到孩子:姓名:"+per1.getName()+"年龄:"+per1.getAge()+per1.getChild().getName()+"年龄:"+per1.getChild().getAge());
		
		
		//后面通过孩子找到书,其实是和关联关系联合才能实现的 后面不实现
	、
		
		
	}
}

这里孩子的类其实是不用实现的,可以借用Person类进行表示

  • 组合关系
    组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分,这种关系是最强的

后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖。

参考:
总结的很好很棒

https://pdai.tech/md/java/basic/java-basic-oop.html#%E6%B3%9B%E5%8C%96%E5%85%B3%E7%B3%BB-generalization

posted @ 2022-10-27 22:57  一往而深,  阅读(143)  评论(0编辑  收藏  举报