1.1 什么是Java继承
想象一下生物界的遗传现象——孩子会继承父母的特征。Java中的继承也是类似的概念。它允许我们创建一个新类(子类)来继承现有类(父类)的属性和方法。这种机制让代码复用变得简单自然。
记得我第一次接触继承时,正在开发一个简单的员工管理系统。我发现经理和普通员工有很多相同的属性:姓名、工号、部门。与其在两个类中重复定义这些字段,不如创建一个基础的Employee类,然后让Manager类和Staff类都继承它。这种设计思路让代码量减少了近40%,维护起来也轻松多了。
继承本质上是一种"is-a"关系。如果说"经理是员工",那么Manager类继承Employee类就是合理的。这种关系判断在实际开发中非常实用,能帮助我们做出正确的继承决策。
1.2 继承的核心特性
继承带来了几个关键特性,理解这些特性对掌握面向对象编程至关重要。
代码复用是最直观的好处。父类中定义的方法和属性,子类无需重复编写就能直接使用。这就像获得了一个现成的工具箱,里面装满了可用的工具。
方法重写允许子类根据需要修改从父类继承来的方法。比如父类Employee有个calculateSalary()方法,经理的薪资计算方式可能不同,Manager类就可以重写这个方法。这种灵活性让继承既保持了统一性,又兼顾了特殊性。
我曾在项目中遇到一个有趣的情况:一个基础的支付处理类,不同的支付渠道(支付宝、微信、银联)都继承它,但每个渠道都需要重写具体的支付逻辑。这种设计让系统扩展变得异常简单。
继承还支持多态——这是面向对象编程的精华所在。你可以用父类引用指向子类对象,在运行时确定具体调用哪个类的方法。这种特性极大地提升了代码的灵活性和可扩展性。
1.3 继承与面向对象编程的关系
继承不是孤立存在的,它是面向对象三大特性(封装、继承、多态)中的重要一环。这三者共同构成了面向对象编程的基石。
封装将数据和行为包装在类中,继承在这些封装好的类之间建立层次关系,多态则让这个层次结构活起来。它们就像一套精密的齿轮系统,彼此咬合,协同工作。
在实际开发中,过度使用继承会导致设计僵化。我见过一些项目因为继承层次过深而变得难以维护——修改一个基类可能引发连锁反应。好的面向对象设计需要在继承和组合之间找到平衡。
继承体现了抽象和具体的关系。父类通常定义通用的抽象概念,子类实现具体的业务逻辑。这种从一般到特殊的思维模式,恰恰反映了我们认识世界的方式。
面向对象编程通过继承实现了概念的层次化组织,让复杂的软件系统具备了清晰的结构。这种思维方式一旦掌握,你会发现它不仅能用在编程中,还能帮助你更好地分析各种复杂问题。 class Animal {
String name;
public void eat() {
System.out.println("动物在进食");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("汪汪叫");
}
}
class Parent {
public Parent() {
System.out.println("父类构造方法执行");
}
}
class Child extends Parent {
public Child() {
// 这里隐含了super();
System.out.println("子类构造方法执行");
}
}
class Animal {
public void eat() {
System.out.println("动物在进食");
}
}
class Mammal extends Animal {
public void giveBirth() {
System.out.println("哺乳动物胎生");
}
}
class Dog extends Mammal {
public void bark() {
System.out.println("狗在叫");
}
}
class Animal {
public void makeSound() {
System.out.println("动物发出声音");
}
// 重载示例
public void makeSound(int volume) {
System.out.println("动物以音量" + volume + "发出声音");
}
}
class Cat extends Animal {
// 重写示例
@Override
public void makeSound() {
System.out.println("喵喵叫");
}
}
// 基础商品类 abstract class Product {
protected String sku;
protected String name;
protected BigDecimal price;
public Product(String sku, String name, BigDecimal price) {
this.sku = sku;
this.name = name;
this.price = price;
}
public abstract String getProductType();
public abstract boolean validate();
// 公共业务逻辑
public BigDecimal calculateDiscount(BigDecimal discountRate) {
return price.multiply(discountRate);
}
}
// 实体商品 class PhysicalProduct extends Product {
private double weight;
private Dimensions dimensions;
public PhysicalProduct(String sku, String name, BigDecimal price,
double weight, Dimensions dimensions) {
super(sku, name, price);
this.weight = weight;
this.dimensions = dimensions;
}
@Override
public String getProductType() {
return "PHYSICAL";
}
@Override
public boolean validate() {
return sku != null && weight > 0 && dimensions != null;
}
// 特有的物流相关方法
public ShippingCost calculateShipping(String destination) {
// 计算物流费用的具体实现
return new ShippingCost(weight, dimensions, destination);
}
}
// 数字商品 class DigitalProduct extends Product {
private String downloadUrl;
private long fileSize;
public DigitalProduct(String sku, String name, BigDecimal price,
String downloadUrl, long fileSize) {
super(sku, name, price);
this.downloadUrl = downloadUrl;
this.fileSize = fileSize;
}
@Override
public String getProductType() {
return "DIGITAL";
}
@Override
public boolean validate() {
return downloadUrl != null && fileSize > 0;
}
// 数字商品特有的方法
public String generateDownloadLink(User user) {
return downloadUrl + "?token=" + generateAccessToken(user);
}
}