Java 多态

多态的实现条件、向上转型、动态绑定与虚函数机制。

Intermediate
Key Points多态三条件:继承、重写、父类引用指向子类对象;调用方法时看实际对象类型,访问字段时看引用类型。

多态的实现

One parent reference pointing at different subclass objects produces different results from the same call. Polymorphism lets code depend on abstractions, so adding a subclass needs no change at the call site.

Java
class Shape {
    double area() {
        return 0;
    }
}

class Circle extends Shape {
    double r = 2;

    @Override
    double area() {
        return 3.14 * r * r;
    }
}

class Square extends Shape {
    double side = 3;

    @Override
    double area() {
        return side * side;
    }
}

public class PolyDemo {
    public static void main(String[] args) {
        Shape[] shapes = {new Circle(), new Square()};

        for (Shape s : shapes) {
            System.out.println(s.area());
        }
    }
}
Output
12.56
9.0

向上转型

Assigning a subclass object to a parent reference is an upcast: automatic and always safe, but only parent-declared members are visible. To reach subclass-specific methods, downcast after an instanceof check.

Java
class Animal {
    void eat() {
        System.out.println("eating");
    }
}

class Cat extends Animal {
    void meow() {
        System.out.println("meow");
    }
}

public class Casting {
    public static void main(String[] args) {
        Animal a = new Cat();   // 向上转型,自动
        a.eat();

        if (a instanceof Cat c) {
            c.meow();
        }

        System.out.println(a.getClass().getSimpleName());
    }
}
Output
eating
meow
Cat

虚函数

Java has no virtual keyword: apart from final, static and private methods, every instance method is virtual and dispatched by the object's runtime type.

Java
class Base {
    void call() {
        System.out.println("Base.call");
    }
}

class Derived extends Base {
    @Override
    void call() {
        System.out.println("Derived.call");
    }

    void onlyInDerived() {
        System.out.println("Derived only");
    }
}

public class Virtual {
    public static void main(String[] args) {
        Base b = new Derived();
        b.call();

        Base plain = new Base();
        plain.call();
    }
}
Output
Derived.call
Base.call

字段不参与多态

Polymorphism applies to methods only. Field access is resolved from the reference type, not the object type, so a parent reference always reads the parent's copy — a common trap.

Java
class P {
    String name = "P";
}

class C extends P {
    String name = "C";
}

public class FieldPoly {
    public static void main(String[] args) {
        P p = new C();
        C c = new C();

        System.out.println(p.name);
        System.out.println(c.name);
        System.out.println(((C) p).name);
    }
}
Output
P
C
C

Friends & Partners