继承

继承是面向对象的核心特性之一,实现代码复用。

什么是继承

继承是子类继承父类的属性和方法,实现代码复用。

继承的好处

好处 说明
代码复用 父类的代码不用重复写
扩展性 子类可以添加自己的属性和方法
多态基础 继承是多态的前提

extends关键字

语法

JAVA
public class 子类 extends 父类 {
    // 子类特有的属性和方法
}

示例:继承

JAVA
// 父类
public class Animal {
    String name;
    int age;
    
    public void eat() {
        System.out.println(name + "正在吃东西");
    }
    
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}

// 子类
public class Dog extends Animal {
    String breed;  // 品种
    
    public void bark() {
        System.out.println(name + "汪汪叫");
    }
}

public class Cat extends Animal {
    String color;  // 颜色
    
    public void meow() {
        System.out.println(name + "喵喵叫");
    }
}

public class InheritanceDemo {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "旺财";
        dog.age = 3;
        dog.breed = "金毛";
        
        dog.eat();    // 旺财正在吃东西(继承自Animal)
        dog.sleep();  // 旺财正在睡觉(继承自Animal)
        dog.bark();   // 旺财汪汪叫(Dog自己的方法)
        
        Cat cat = new Cat();
        cat.name = "咪咪";
        cat.age = 2;
        cat.color = "白色";
        
        cat.eat();    // 咪咪正在吃东西
        cat.meow();   // 咪咪喵喵叫
    }
}
▶ 试一试

super关键字

super代表父类的引用。

用途1:调用父类构造方法

JAVA
public class Animal {
    String name;
    int age;
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class Dog extends Animal {
    String breed;
    
    public Dog(String name, int age, String breed) {
        super(name, age);  // 调用父类构造方法
        this.breed = breed;
    }
}

用途2:调用父类方法

JAVA
public class Animal {
    public void eat() {
        System.out.println("动物在吃东西");
    }
}

public class Dog extends Animal {
    @Override
    public void eat() {
        super.eat();  // 调用父类的eat
        System.out.println("狗在啃骨头");
    }
}

示例:super的使用

JAVA
public class Person {
    protected String name;
    protected int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class Student extends Person {
    private double score;
    
    public Student(String name, int age, double score) {
        super(name, age);  // 调用父类构造方法
        this.score = score;
    }
    
    @Override
    public void showInfo() {
        super.showInfo();  // 调用父类的showInfo
        System.out.println("分数:" + score);
    }
}

public class SuperDemo {
    public static void main(String[] args) {
        Student stu = new Student("Alice", 20, 95.5);
        stu.showInfo();
        // 姓名:Alice,年龄:20
        // 分数:95.5
    }
}
▶ 试一试

方法重写

子类可以重写父类的方法,实现不同的行为。

重写规则

规则 说明
方法名相同 必须一致
参数列表相同 必须一致
返回类型相同 或是父类返回类型的子类
访问权限不能缩小 可以扩大

@Override注解

JAVA
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗在啃骨头");
    }
}
💡 建议: 重写方法时加上@Override注解,编译器会检查是否正确重写。

Object类

所有类都直接或间接继承自Object类。

Object常用方法

方法 说明
toString() 返回对象的字符串表示
equals() 比较对象是否相等
hashCode() 返回对象的哈希码
getClass() 返回对象的类信息

重写toString()

JAVA
public class Student {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + "}";
    }
    
    public static void main(String[] args) {
        Student stu = new Student("Alice", 20);
        System.out.println(stu);  // 自动调用toString()
        // 输出:Student{name='Alice', age=20}
    }
}

重写equals()

JAVA
public class Student {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Student other = (Student) obj;
        return age == other.age && name.equals(other.name);
    }
    
    @Override
    public int hashCode() {
        return name.hashCode() * 31 + age;
    }
    
    public static void main(String[] args) {
        Student s1 = new Student("Alice", 20);
        Student s2 = new Student("Alice", 20);
        
        System.out.println(s1 == s2);      // false(不同对象)
        System.out.println(s1.equals(s2)); // true(内容相同)
    }
}

instanceof

instanceof判断对象是否是某个类的实例。

JAVA
public class instanceofDemo {
    public static void main(String[] args) {
        Dog dog = new Dog();
        
        System.out.println(dog instanceof Dog);    // true
        System.out.println(dog instanceof Animal); // true
        System.out.println(dog instanceof Object); // true
    }
}

继承的注意事项

注意事项 说明
单继承 Java只支持单继承
不能继承private private成员不能被继承
不能继承构造方法 构造方法不能被继承
Object是根类 所有类都继承自Object

❓ 常见问题

Q 为什么不支持多继承?
A 避免菱形继承问题(多个父类有同名方法时无法确定调用哪个)。Java用接口实现类似功能。
Q 什么时候用继承?
A 当两个类有"is-a"关系时,如Dog is a Animal。
Q 继承和组合怎么选?
A 优先使用组合(has-a关系),继承会增加耦合度。

📖 小节

📝 作业

  1. Shape体系: 定义Shape父类,Circle、Rectangle子类,计算面积
  2. Employee体系: 定义Employee父类,Manager、Developer子类
  3. toString/equals: 重写Student类的toString和equals方法

下一课

下一课我们将学习 多态与抽象,了解面向对象的核心特性。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏