引言:为什么需要继承?
在Java编程中,我们经常会遇到多个类具有相似的属性和方法的情况。比如在动物世界中,猫、狗、牛等动物都有名字、颜色,都能跑、能吃。如果没有继承机制,我们就需要为每个类重复编写这些相同的代码,这不仅效率低下,还容易出错。
一、继承的基本概念
1.1 什么是继承?
继承是面向对象编程的三大特性之一(封装、继承、多态),它的本质就是代码的复用。通过继承,子类可以自动拥有父类的公有(public)和保护(protected)成员变量和方法。
1.2 继承的基本语法
// 父类
public class Animal {
public String name;
public String color;
public void run() {
// 跑步的具体实现
}
public void eat() {
// 吃东西的具体实现
}
}
// 子类继承父类
public class Cat extends Animal {
// Cat类自动继承了name、color属性和run()、eat()方法
// 可以添加Cat特有的属性和方法
}
public class Dog extends Animal {
// Dog类同样继承了父类的所有公有和保护成员
}
二、继承在内存中的实现
2.1 对象创建过程
当我们创建子类对象时,在内存中会发生以下过程:
创建 Cat 对象时:
1. 首先创建父类 Animal 对象(0x1)
- 分配内存空间
- 初始化父类属性:name=null, color=null
- 加载父类方法:run(), eat()
2. 然后创建子类 Cat 对象(0x2)
- 分配内存空间
- 初始化子类特有属性
- 加载子类方法
2.2 创建顺序的重要性
为什么创建子类对象时,要先创建父类对象?
这是因为子类的实现依赖于父类的完整结构。子类可能会重写父类的方法,或者调用父类的构造方法。如果父类没有先初始化,子类就无法正常使用从父类继承来的功能。
三、方法重写(Override)
3.1 方法重写的概念
当父类的方法不能完全适用于子类时,子类可以重新定义父类的方法,这就叫做方法重写。
public class Animal {
public void run() {
System.out.println("动物在奔跑");
}
}
public class Cat extends Animal {
@Override
public void run() {
System.out.println("猫在轻盈地奔跑");
}
}
public class Dog extends Animal {
@Override
public void run() {
System.out.println("狗在快速地奔跑");
}
}
3.2 方法重写的特点
- 方法名、参数列表必须完全相同
- 返回类型可以相同或是父类方法返回类型的子类型
- 访问权限不能比父类方法更严格
- 可以使用 @Override 注解来显式声明
四、方法重载(Overload)
4.1 方法重载的概念
public class Calculator {
// 方法重载示例
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
}
.2 方法签名
Java通过方法签名来识别不同的方法。方法签名由**方法名 + 参数列表(数据类型)**组成。
4.3 面试重点:重载 vs 重写
|
特性 |
方法重载(Overload) |
方法重写(Override) |
|
发生位置 |
同一个类中 |
父子类之间 |
|
方法名 |
相同 |
相同 |
|
参数列表 |
必须不同 |
必须相同 |
|
返回类型 |
可以不同 |
相同或子类型 |
|
访问权限 |
可以不同 |
不能更严格 |
|
异常声明 |
可以不同 |
不能抛出更广泛的异常 |
五、super关键字
5.1 super的作用
super 关键字代表父类,用于调用父类中的方法和变量。
public class Cat extends Animal {
public void display() {
super.run(); // 调用父类的run方法
System.out.println(super.color); // 访问父类的color属性
}
}
5.2 super()调用父类构造方法
public class Animal {
public Animal(String name) {
this.name = name;
}
}
public class Cat extends Animal {
public Cat(String name, String breed) {
super(name); // 调用父类构造方法,必须是第一条语句
this.breed = breed;
}
}
- 只能在构造方法中使用super()
- 必须是构造方法中的第一条语句
- 不能和this()一起使用
六、this关键字
6.1 this的含义
6.2 this的用法
public class Animal {
private String name;
public Animal(String name) {
this.name = name; // 区分成员变量和参数
}
public void printInfo() {
System.out.println(this.name); // 访问当前对象的属性
this.run(); // 调用当前对象的方法
}
}
6.3 this()调用其他构造方法
public class Animal {
private String name;
private String color;
public Animal() {
this("未知", "未知"); // 调用另一个构造方法
}
public Animal(String name, String color) {
this.name = name;
this.color = color;
}
}
七、Java继承层次
7.1 单继承原则
Java只支持单继承,即一个子类只能有一个直接父类。

7.2 多层继承
虽然Java不支持多继承,但支持多层继承:

7.3 为什么设计单继承?
八、继承的最佳实践
8.1 合理使用继承
- 只有在"is-a"关系成立时才使用继承
- 优先使用组合而非继承
- 合理设计类的层次结构
8.2 继承的设计原则
- 里氏替换原则:子类应该能够替换父类出现在任何地方
- 开闭原则:对扩展开放,对修改关闭
- 单一职责原则:每个类应该有明确的职责
Java继承与面向对象设计
1567

被折叠的 条评论
为什么被折叠?



