在Java中,抽象类和接口是用来实现代码重构的强大工具。下面使用一个简单的例子来说明什么情况下需要进行这样的重构以及重构后的代码。
假设有一个汽车制造公司,该公司生产各种类型的汽车。最初的代码如下:
```java
public class Car {
private String brand;
private String model;
private int year;
public Car(String brand, String model, int year) {
this.brand = brand;
this.model = model;
this.year = year;
}
public void drive() {
System.out.println("Driving " + brand + " " + model);
}
}
public class Suv extends Car {
private boolean offRoad;
public Suv(String brand, String model, int year, boolean offRoad) {
super(brand, model, year);
this.offRoad = offRoad;
}
public void drive() {
System.out.println("Driving " + brand + " " + model + " off-road");
}
}
public class Sedan extends Car {
public Sedan(String brand, String model, int year) {
super(brand, model, year);
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Toyota", "Camry", 2022);
car1.drive();
Suv suv1 = new Suv("Ford", "Explorer", 2022, true);
suv1.drive();
Sedan sedan1 = new Sedan("Honda", "Accord", 2022);
sedan1.drive();
}
}
```
在上述代码中,汽车类型的特征和行为都放在了`Car`类中,而`Suv`类和`Sedan`类仅继承了`Car`类,并没有增加额外的特征或行为。
在这种情况下,可以使用抽象类和接口对代码进行重构。
首先,创建一个抽象类`Vehicle`,其中包含了所有车辆共有的特征和行为。抽象类可以定义抽象方法(没有具体实现)和具体方法(有具体实现),抽象类不能直接实例化,只能被继承。
```java
public abstract class Vehicle {
protected String brand;
protected String model;
protected int year;
public Vehicle(String brand, String model, int year) {
this.brand = brand;
this.model = model;
this.year = year;
}
public abstract void drive();
}
```
接下来,将`Car`类改为继承自`Vehicle`类,`Suv`和`Sedan`类也同样改为继承自`Vehicle`类。
```java
public class Car extends Vehicle {
public Car(String brand, String model, int year) {
super(brand, model, year);
}
@Override
public void drive() {
System.out.println("Driving " + brand + " " + model);
}
}
public class Suv extends Vehicle {
private boolean offRoad;
public Suv(String brand, String model, int year, boolean offRoad) {
super(brand, model, year);
this.offRoad = offRoad;
}
@Override
public void drive() {
System.out.println("Driving " + brand + " " + model + " off-road");
}
}
public class Sedan extends Vehicle {
public Sedan(String brand, String model, int year) {
super(brand, model, year);
}
@Override
public void drive() {
System.out.println("Driving " + brand + " " + model);
}
}
```
最后,修改`Main`类中的代码来使用重构后的类。
```java
public class Main {
public static void main(String[] args) {
Vehicle car1 = new Car("Toyota", "Camry", 2022);
car1.drive();
Vehicle suv1 = new Suv("Ford", "Explorer", 2022, true);
suv1.drive();
Vehicle sedan1 = new Sedan("Honda", "Accord", 2022);
sedan1.drive();
}
}
```
重构后的代码将共有的特征和行为提取到了抽象类`Vehicle`中,并通过继承来实现不同车辆类型的特定行为。这样做的好处是代码更加清晰、可维护性更高,当需要添加新的车辆类型时,只需要创建一个新的子类继承自`Vehicle`类并实现特定的行为即可。