Skip to content

类和类的关系

类之间的关系有:

  • 泛化
    • 表示 is-a 的关系,主要表现为继承、实现
  • 包含
    • 表示 has-a 的关系,主要表现为关联、聚合、组合
  • 依赖
    • 表示 use-a(或者是 need-a)的关系

泛化

继承

  • 子类继承父类,通过关键字 extends 来实现
  • 子类的对象可以调用父类中的属性和方法(修饰符为 public、protected 的方法)
    • 在创建子类的对象时(调用子类的构造函数),会默认调用父类的构造函数,父类的构造函数执行前,会执行父类的程序块
  • 子类能够添加自己独有的属性和方法
  • 子类从父类继承过来的方法不能满足需要时,可以重写(Override)父类的方法
  • 每一个类都有继承类,默认继承 Object,如果写了 extends 关键字,则继承该关键字后面的类
    • 可以理解为 Object 是所有引用类型的父类,但 Object 没有父类
  • this 关键字指的是当前执行方法的对象
  • super 关键字指的是当前执行方法的对象的父类对象
java
public class Animal {
  public Animal() {
    System.out.println("Animal的无参构造函数");
  }
  
  public void eat() {
    System.out.println("动物吃饭");
  }
  
  public void sleep() {
    this.eat();
    System.out.println("动物睡觉");
  }
}
java
public class Person extends Animal {
  public Person() {
    // 此处有一个隐藏代码:super();
    // super表示父类的构造函数
    System.out.println("Person的无参构造函数");
  }
  
  public void eat() {
    System.out.println("人类吃饭");
  }
  
  public void study() {
    System.out.println("人类学习");
  }
}
java
public class Test {
  public static void main(String[] args) {
    Person p = new Person();
    p.eat();
    // 
    p.sleep();
    
    // output:
    // Animal的无参构造函数
    // Person的无参构造函数
    // 人类吃饭
    // 人类吃饭
    // 动物睡觉
  }
}

实现

包含

包含关系在 java 程序中,通常表现为一个类的对象作为另一个类的属性存储。

关联

关联关系,指的是两个类的对象,相互独立,当它们相互协作就形成了关联关系。

比如人和汽车,当人驾驶着汽车,它们就形成了关联关系。

聚合

聚合关系,指的是两个类的对象,相互独立,一个类的对象中,有另一个类的对象,它们在创建时有可能是分开的。这两个类的对象不会因为对方的销毁而销毁。

比如汽车和轮胎,它们是分开生产,后期组装在一起的。即使将汽车销毁,轮胎也能够拆卸下来保存。

一般情况下,复用代码推荐使用聚合。

组合

组合关系,指的是两个类的对象,彼此高度依赖,一个类的对象中,有另一个类的对象,它们在创建时就已经在一起了。作为子级的类的对象会因为作为父级的类的对象的销毁而销毁。

比如人和眼睛,人在出生时就已经有了眼睛,当人死亡时,眼睛也跟着消亡了。

java
public class Wheel {
    private String brand; // 品牌
    private String color; // 颜色

    public Wheel(String brand, String color) {
        this.brand = brand;
        this.color = color;
    }

    public String getBrand() {
        return brand;
    }

    public String getColor() {
        return color;
    }
}


public class Car {
    private String brand; // 汽车品牌
    private String color; // 颜色
    private Wheel wheel; // 汽车和轮胎 --> 聚合关系

    public Car(String brand, String color, Wheel wheel) {
        this.brand = brand;
        this.color = color;
        this.wheel = wheel;
    }

    public String getBrand() {
        return brand;
    }

    public void printCarInfo() {
        System.out.println("This is a " + color + " " + brand + " car with " + wheel.getColor() + " " + wheel.getBrand() + " wheel.");
    }
}


public class Eyes {
    private String pupilColor;

    public Eyes(String color) {
        pupilColor = color;
    }

    public String getPupilColor() {
        return pupilColor;
    }
}


public class Person {
    private String name;
    private Eyes eyes = new Eyes("brown"); // 人和眼睛 --> 组合关系

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void sayMyEyes() {
        System.out.println("My eyes are " + eyes.getPupilColor() + ".");
    }
}

public class Test {
    public static void main(String[] args) {
        Person p = new Person("Tom");
        p.sayMyEyes();
        Wheel w = new Wheel("Michelin", "white");
        Car c = new Car("benz", "black", w);
        // 人和汽车 --> 关联关系
        System.out.println(p.getName() + " is driving the " + c.getBrand() + " car.");
        c.printCarInfo();
    }
}

依赖

依赖关系,指的是两个类的对象,是使用与被使用的关系。

在 java 程序中通常表现为一个类的方法使用到了另一个类的对象,通常是:

  • 在方法中将另一个类的对象作为参数使用
  • 在方法中创建另一个类的对象使用
java
public class Oil {
    private int volume;

    public Oil(int v) {
        volume = v;
    }

    public int getVolume() {
        return volume;
    }
}

public class Motor {
    private int oilConsumption;

    public Motor(int oC) {
        oilConsumption = oC;
    }

    public void calcRunTime(Oil oil) {
        int runTime = oil.getVolume() / oilConsumption;
        System.out.println("The motor can run " + runTime + " hours.");
    }
}

public class Test {
    public static void main(String[] args) {
        Oil o = new Oil(10);
        Motor motor = new Motor(1);
        motor.calcRunTime(o);
    }
}