Java编程思想:为何有时要将子类对象赋值给父类引用
为何有时要将子类对象赋值给父类引用,用父类来进行实例化?
这就要说多态的优势: 代码的扩展性和降低耦合度,而不是完全避免修改代码。
TuXing t = new Changfangxing();
Changfangxing k = (Changfangxing)t;
原因1: 代码可拓展性
通过父类引用调用方法时,实际执行的是子类的实现。
这样,当需要拓展系统时,只需要添加新的子类,而不需要修改现有的代码逻辑。
Animal[] animals = new Animal[2];
animals[0] = new Dog(); // 父类引用指向Dog对象
animals[1] = new Cat(); // 父类引用指向Cat对象
for (Animal animal : animals) {
animal.eat(); // 所有Animal子类都可以调用eat()方法
}
• 使用 Animal 类型的数组可以存储所有 Animal 子类的对象。
• 这样可以统一处理不同类型的对象,而不需要为每种类型编写单独的代码。
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog(); // 这里可以手动修改为 new Cat()
makeAnimalSound(myAnimal); // 调用方法
}
// 这个方法可以处理任意Animal子类对象
public static void makeAnimalSound(Animal animal) {
animal.makeSound();
}
}
原因2:接口与实现类分离
降低耦合度,多态通过将接口(父类)和实现(子类)分离,降低代码的耦合度。调用者只需要知道父类的接口,而不需要关心具体的子类实现。
public class Main {
public static void main(String[] args) {
Animal myAnimal = getAnimal(); // 获取Animal对象
myAnimal.makeSound(); // 调用方法
}
// 这个方法可以根据条件返回不同的Animal子类对象
public static Animal getAnimal() {
// 假设根据某些条件返回不同的子类对象
if (/* 条件 */) {
return new Dog();
} else {
return new Cat();
}
}
原因3: 工厂模式
进一步减少代码的修改,工厂模式将对象的创建逻辑分装到一个单独的类中,调用者只需要通过工厂获取对象,而不需要关心具体的子类类型。
class AnimalFactory {
public static Animal createAnimal(String type) {
if (type.equals("Dog")) {
return new Dog();
} else if (type.equals("Cat")) {
return new Cat();
} else {
throw new IllegalArgumentException("Unknown animal type");
}
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = AnimalFactory.createAnimal("Dog"); // 通过工厂获取Animal对象
myAnimal.makeSound(); // 调用方法
}
}
原因4: 限制对子类特定方法的访问
Animal myAnimal = new Dog(); // 父类引用指向Dog对象
myAnimal.eat(); // 可以调用
// myAnimal.bark(); // 编译错误,Animal类没有bark()方法
通过父类引用,你只能访问父类中定义的方法和属性,而不能访问子类特有的方法(如 bark())。
这样可以更好地控制对象的访问权限。