Skip to content

面向对象进阶

继承

基本语法

java
// 父类
public class Animal {
    protected String name;
    protected 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 {
    private String breed;
    
    public Dog(String name, int age, String breed) {
        super(name, age);  // 调用父类构造方法
        this.breed = breed;
    }
    
    public void bark() {
        System.out.println(name + "正在汪汪叫");
    }
}

// 使用
Dog dog = new Dog("旺财", 3, "金毛");
dog.eat();   // 继承自父类
dog.bark();  // 子类特有方法

继承特点

  • Java单继承(一个类只能有一个直接父类)
  • 可以多层继承
  • 子类继承父类的非私有成员
  • 构造方法不能继承

super关键字

调用父类构造方法

java
public class Cat extends Animal {
    private String color;
    
    public Cat(String name, int age, String color) {
        super(name, age);  // 必须在第一行
        this.color = color;
    }
}

访问父类成员

java
public class Bird extends Animal {
    public Bird(String name, int age) {
        super(name, age);
    }
    
    @Override
    public void eat() {
        super.eat();  // 调用父类方法
        System.out.println(name + "喜欢吃虫子");
    }
    
    public void showParent() {
        System.out.println(super.name);  // 访问父类变量
        System.out.println(super.age);
    }
}

方法重写

重写规则

  • 方法名、参数列表必须相同
  • 返回类型可以相同或是父类返回类型的子类
  • 访问权限不能更严格
  • 不能重写private、static、final方法
java
public class Shape {
    public double getArea() {
        return 0;
    }
    
    public void draw() {
        System.out.println("绘制图形");
    }
}

public class Circle extends Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

@Override注解

java
@Override  // 编译器检查是否正确重写
public double getArea() {
    return Math.PI * radius * radius;
}

多态

多态概念

同一个方法调用,不同对象有不同的行为。

java
public class PolymorphismDemo {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        Animal animal1 = new Dog("旺财", 3);
        Animal animal2 = new Cat("咪咪", 2);
        
        // 同样的方法调用,不同的行为
        animal1.eat();  // 旺财正在吃东西
        animal2.eat();  // 咪咪正在吃东西
        
        // 类型检查
        if (animal1 instanceof Dog) {
            Dog dog = (Dog) animal1;  // 向下转型
            dog.bark();
        }
    }
}

向上转型与向下转型

java
// 向上转型(自动)
Dog dog = new Dog("旺财", 3);
Animal animal = dog;  // 向上转型

// 向下转型(需要强制转换)
Animal a = new Dog("旺财", 3);
if (a instanceof Dog) {
    Dog d = (Dog) a;  // 向下转型
    d.bark();
}

// Java 16+ 模式匹配
if (a instanceof Dog d) {
    d.bark();  // 直接使用d
}

抽象类

定义抽象类

java
// 抽象类
public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // 抽象方法(没有实现)
    public abstract double getArea();
    public abstract double getPerimeter();
    
    // 具体方法
    public void display() {
        System.out.println("颜色: " + color);
        System.out.println("面积: " + getArea());
        System.out.println("周长: " + getPerimeter());
    }
}

// 具体子类
public class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
    
    @Override
    public double getPerimeter() {
        return 2 * (width + height);
    }
}

抽象类特点

  • 不能实例化
  • 可以有抽象方法和具体方法
  • 子类必须实现所有抽象方法(除非子类也是抽象类)
  • 可以有构造方法

接口

定义接口

java
// 定义接口
public interface Drawable {
    void draw();  // 默认public abstract
    
    // 默认方法(Java 8+)
    default void printInfo() {
        System.out.println("这是一个可绘制的对象");
    }
    
    // 静态方法(Java 8+)
    static void staticMethod() {
        System.out.println("接口静态方法");
    }
}

// 实现接口
public class Circle implements Drawable {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

多实现

java
public interface Flyable {
    void fly();
}

public interface Swimmable {
    void swim();
}

// 实现多个接口
public class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("鸭子飞翔");
    }
    
    @Override
    public void swim() {
        System.out.println("鸭子游泳");
    }
}

接口继承

java
public interface A {
    void methodA();
}

public interface B {
    void methodB();
}

// 接口多继承
public interface C extends A, B {
    void methodC();
}

// 实现类需要实现所有方法
public class Impl implements C {
    @Override
    public void methodA() { }
    
    @Override
    public void methodB() { }
    
    @Override
    public void methodC() { }
}

内部类

成员内部类

java
public class Outer {
    private int outerVar = 10;
    
    // 成员内部类
    public class Inner {
        private int innerVar = 20;
        
        public void show() {
            System.out.println("外部变量: " + outerVar);
            System.out.println("内部变量: " + innerVar);
        }
    }
    
    public void useInner() {
        Inner inner = new Inner();
        inner.show();
    }
}

// 使用
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();

静态内部类

java
public class Outer {
    private static int staticVar = 10;
    
    // 静态内部类
    public static class StaticInner {
        public void show() {
            System.out.println("静态变量: " + staticVar);
        }
    }
}

// 使用
Outer.StaticInner inner = new Outer.StaticInner();
inner.show();

局部内部类

java
public class Outer {
    public void method() {
        final int localVar = 10;
        
        // 局部内部类
        class LocalInner {
            public void show() {
                System.out.println("局部变量: " + localVar);
            }
        }
        
        LocalInner inner = new LocalInner();
        inner.show();
    }
}

匿名内部类

java
public interface Greeting {
    void greet();
}

public class AnonymousDemo {
    public static void main(String[] args) {
        // 匿名内部类
        Greeting greeting = new Greeting() {
            @Override
            public void greet() {
                System.out.println("Hello!");
            }
        };
        greeting.greet();
        
        // Lambda表达式(Java 8+)
        Greeting greeting2 = () -> System.out.println("Hello Lambda!");
        greeting2.greet();
    }
}

抽象类 vs 接口

特性抽象类接口
继承单继承多实现
成员变量可以有各种类型只能是public static final
构造方法可以有不能有
方法可以有抽象和具体方法Java 8前只有抽象方法,之后可以有默认和静态方法
设计理念is-a关系has-a能力