Java继承讲解(第四节)继承与组合

 书接上回Java继承讲解(第三节)继承关系上的代码块执行顺序-CSDN博客

1. 继承(Inheritance)

1.1 继承的定义

继承是一种"是一个"**(is-a)的关系,指的是子类继承父类的属性和方法,子类可以扩展或重写父类的功能。继承通过 extends 关键字实现。

1.2 继承的优点
  • 代码复用:子类继承父类的属性和方法,避免重复编写相同的代码。
  • 方法重写:子类可以根据自身的需要,重写父类的方法,增强代码的扩展性。
  • 多态性:继承关系能够实现多态,允许子类对象通过父类引用来调用方法,实现动态绑定。
1.3 继承的示例
class Animal {
    public void eat() {
        System.out.println("动物正在吃东西");
    }
}

class Dog extends Animal {
    public void bark() {
        System.out.println("狗在叫");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();  // 子类可以继承父类的eat方法
        dog.bark(); // 子类自己扩展的方法
    }
}
1.4 继承的缺点
  • 继承是静态的:一旦子类继承了父类,就形成了一种强耦合关系,子类的行为依赖于父类的实现。如果父类发生变化,子类的行为也可能受到影响。
  • 滥用继承:如果继承层次过深,会导致系统复杂且难以维护。修改父类会对整个继承链产生影响。

2. 组合(Composition)

2.1 组合的定义

组合是一种"有一个"has-a)的关系,指的是一个类通过拥有另一个类的实例来使用它的功能。组合意味着类之间是关联关系**,而不是继承关系。通过组合,可以更灵活地构建类的行为。

2.2 组合的优点
  • 松耦合:组合使类与类之间的关系更松散,不同类的功能是通过对象关联而不是继承,修改某个类不会影响其他类。
  • 运行时动态替换:组合允许在运行时替换对象的行为,因为组合的类可以通过接口或者对象引用动态组合不同的实现。
  • 灵活性:相比继承,组合更灵活,它允许你根据需要组合不同的类,而不必在类的设计阶段决定继承层次。
2.3 组合的示例
class Engine {
    public void start() {
        System.out.println("引擎启动");
    }
}

class Car {
    private Engine engine;  // 组合关系

    public Car() {
        engine = new Engine();  // Car"有一个"Engine
    }

    public void drive() {
        engine.start();
        System.out.println("汽车正在行驶");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.drive();  // 组合方式下的行为调用
    }
}
2.4 组合的缺点
  • 可能增加代码复杂性:由于需要手动创建和管理组合对象的实例,有时候组合可能导致代码更加复杂。
  • 无法直接复用父类方法:与继承不同,组合无法直接使用被组合类的所有方法。如果需要复用某些行为,必须显式调用相应的方法。

3. 继承 vs. 组合

特性继承(Inheritance)组合(Composition)
关系类型"是一个"(is-a)"有一个"(has-a)
耦合性强耦合(子类与父类紧密相关)松耦合(类之间关联关系松散)
代码复用通过继承父类的方法和属性来复用代码通过组合其他对象来实现功能复用
灵活性继承层次一旦确定,不易修改组合灵活,可以在运行时动态替换行为
修改影响父类的修改可能影响所有子类类的修改不会影响其他类
实现复杂度相对简单,继承链清晰可能需要管理多个对象,增加复杂性

4. 组合与继承的结合使用

在实际开发中,继承和组合并不冲突,很多时候可以结合使用,以达到最佳效果。你可以使用继承来表达类之间的通用行为,然后使用组合来提供额外的功能。

示例:结合使用继承与组合
class Engine {
    public void start() {
        System.out.println("引擎启动");
    }
}

class Vehicle {
    public void move() {
        System.out.println("车辆移动");
    }
}

class Car extends Vehicle {
    private Engine engine;

    public Car() {
        this.engine = new Engine();
    }

    @Override
    public void move() {
        engine.start();  // 使用组合提供额外的功能
        super.move();    // 继承父类的通用行为
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.move();  // 既调用了父类方法,又使用了组合的Engine功能
    }
}
解释
  • Car 类继承了 Vehicle 类,使用了父类的 move() 方法来表示车辆移动的通用行为。
  • 同时,Car 类通过组合 Engine 对象,增加了引擎启动的功能。这种组合和继承的结合使用增强了类的灵活性和功能扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值