Java从零到熟练(五):面向对象进阶
·
继承让代码复用,多态让代码灵活,接口让代码解耦。
目录
1. 继承
继承是面向对象的重要特性,允许子类复用父类的属性和方法。
1.1 基本继承
// 父类(超类、基类)
public class Animal {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name + "正在吃东西");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
// 子类(派生类)
public class Dog extends Animal {
String breed; // 子类特有的属性
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类构造函数
this.breed = breed;
}
public void bark() { // 子类特有的方法
System.out.println(name + "正在汪汪叫");
}
public void fetch() {
System.out.println(name + "正在捡球");
}
}
// 另一个子类
public class Cat extends Animal {
boolean isIndoor;
public Cat(String name, int age, boolean isIndoor) {
super(name, age);
this.isIndoor = isIndoor;
}
public void meow() {
System.out.println(name + "正在喵喵叫");
}
}
1.2 使用继承
public class InheritanceDemo {
public static void main(String[] args) {
// 创建Dog对象
Dog dog = new Dog("旺财", 3, "金毛");
dog.eat(); // 继承自Animal
dog.sleep(); // 继承自Animal
dog.bark(); // Dog特有方法
dog.fetch(); // Dog特有方法
System.out.println();
// 创建Cat对象
Cat cat = new Cat("咪咪", 2, true);
cat.eat(); // 继承自Animal
cat.sleep(); // 继承自Animal
cat.meow(); // Cat特有方法
}
}
1.3 方法重写(Override)
子类可以重写父类的方法:
public class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public double area() {
return 0; // 基类默认实现
}
public void draw() {
System.out.println("绘制一个" + color + "的图形");
}
}
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public void draw() {
System.out.println("绘制一个" + color + "的圆形,半径:" + radius);
}
}
public class Rectangle extends Shape {
private double width, height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
@Override
public void draw() {
System.out.println("绘制一个" + color + "的矩形,宽:" + width + ",高:" + height);
}
}
1.4 继承的注意事项
// 1. Java是单继承:一个类只能有一个父类
// class Child extends Parent1, Parent2 {} // 编译错误!
// 2. 所有类都继承自Object类
// class MyClass {} 等价于 class MyClass extends Object {}
// 3. final类不能被继承
final class FinalClass {
// 不能被继承
}
// 4. 构造函数不能被继承
// 子类必须调用父类构造函数(通过super)
2. 多态
多态是指同一个方法调用,根据对象的实际类型执行不同的代码。
2.1 方法多态
public class Animal {
public void makeSound() {
System.out.println("...");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("汪汪汪!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵喵!");
}
}
public class PolymorphismDemo {
public static void main(String[] args) {
// 多态:父类引用指向子类对象
Animal animal1 = new Dog();
Animal animal2 = new Cat();
// 同一个方法调用,不同的行为
animal1.makeSound(); // 汪汪汪!
animal2.makeSound(); // 喵喵喵!
// 多态数组
Animal[] animals = {new Dog(), new Cat()};
for (Animal animal : animals) {
animal.makeSound();
}
}
}
2.2 向上转型与向下转型
public class CastingDemo {
public static void main(String[] args) {
// 向上转型(自动):子类 → 父类
Animal animal = new Dog("旺财", 3, "金毛");
animal.eat(); // 可以调用父类方法
animal.sleep(); // 可以调用父类方法
// animal.bark(); // 编译错误!不能调用子类特有方法
// 向下转型(强制):父类 → 子类
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // 强制转换
dog.bark(); // 可以调用子类方法
dog.fetch();
}
// Java 16+模式匹配
if (animal instanceof Dog dog) {
dog.bark(); // 直接使用,无需手动转换
}
}
}
3. 抽象类
抽象类是不能被实例化的类,用于定义通用模板。
3.1 抽象类和抽象方法
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 抽象方法:只有声明,没有实现
public abstract double area();
public abstract double perimeter();
// 普通方法:有实现
public void display() {
System.out.println("颜色:" + color);
System.out.println("面积:" + String.format("%.2f", area()));
System.out.println("周长:" + String.format("%.2f", perimeter()));
}
}
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public double perimeter() {
return 2 * Math.PI * radius;
}
}
public class AbstractDemo {
public static void main(String[] args) {
// Shape shape = new Shape("红色"); // 编译错误!抽象类不能实例化
Shape circle = new Circle("红色", 5);
circle.display();
}
}
4. 接口
接口是完全抽象的类型,定义了一组方法签名,但不提供实现。
4.1 定义接口
// 接口定义
public interface Drawable {
// 常量(默认public static final)
int MAX_SIZE = 100;
// 抽象方法(默认public abstract)
void draw();
void resize(double factor);
// 默认方法(Java 8+)
default void drawWithBorder() {
System.out.println("绘制边框");
draw();
}
// 静态方法(Java 8+)
static boolean isValidSize(int size) {
return size > 0 && size <= MAX_SIZE;
}
}
4.2 实现接口
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("绘制圆形,半径:" + radius);
}
@Override
public void resize(double factor) {
radius *= factor;
}
}
4.3 接口 vs 抽象类
| 特性 | 接口 | 抽象类 |
|---|---|---|
| 实例化 | 不能 | 不能 |
| 继承 | 多实现 | 单继承 |
| 构造函数 | 没有 | 有 |
| 成员变量 | 只能是常量 | 可以有变量 |
| 方法 | 抽象方法、默认方法、静态方法 | 抽象方法、普通方法 |
| 设计目的 | 定义"能做什么" | 定义"是什么" |
5. 实战案例
5.1 设计一个图形计算器
public abstract class Shape2D {
protected String name;
protected String color;
public Shape2D(String name, String color) {
this.name = name;
this.color = color;
}
public abstract double area();
public abstract double perimeter();
public void display() {
System.out.println("【" + name + "】颜色:" + color);
System.out.println("面积:" + String.format("%.2f", area()));
System.out.println("周长:" + String.format("%.2f", perimeter()));
}
}
public class Circle2D extends Shape2D {
private double radius;
public Circle2D(String color, double radius) {
super("圆形", color);
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public double perimeter() {
return 2 * Math.PI * radius;
}
}
public class ShapeCalculator {
private List<Shape2D> shapes = new ArrayList<>();
public void addShape(Shape2D shape) {
shapes.add(shape);
}
public void displayAll() {
System.out.println("=== 图形列表 ===");
for (Shape2D shape : shapes) {
shape.display();
System.out.println();
}
}
public double getTotalArea() {
return shapes.stream()
.mapToDouble(Shape2D::area)
.sum();
}
}
6. 总结
本篇我们学习了:
✅ 继承:代码复用,extends关键字
✅ 多态:同一方法,不同行为
✅ 抽象类:模板方法,不能实例化
✅ 接口:完全抽象,多实现
✅ 类型转换:向上转型、向下转型
核心要点:
- 继承实现代码复用,多态实现灵活扩展
- 抽象类定义"是什么",接口定义"能做什么"
- 使用instanceof进行安全的向下转型
- 重写equals和hashCode时要成对重写
下一篇预告: 《Java从零到熟练(六):集合框架》
- 学习List、Set、Map三大集合
- 掌握集合的常用操作
- 理解集合的选择策略
参考资源
下一篇: Java从零到熟练(六):集合框架
更多推荐

所有评论(0)