Java 面向对象 多态

Java 中的 多态(Polymorphism) 是面向对象编程(OOP)的一个核心概念,它可以不同的对象以相同的方式响应相同的方法调用。通过多态,程序可以在不修改代码的情况下,根据实际对象的类型来执行不同的行为。多态不仅简化了代码的管理和维护,还提高了代码的复用性和可扩展性。本文主要介绍Java 多态。

1、Java 多态

继承使我们可以从另一个类继承属性和方法。多态使用这些方法来执行不同的任务。这使我们能够以不同的方式执行单个方法。

1)引用的多态

父类的引用可以指向本类的对象,父类的引用可以指向子类的对象。

注意:子类的对象不可以指向父类的对象

2)方法的多态

创建本类对象时,调用的方法为本类的方法。创建子类对象时,调用的方法为子类重写的方法或者继承的方法。

注意:父类的引用调用的方法不能是子类独有的方法,必须是从父类继承的方法或重写父类的方法。

2、多态中的引用类型转换

1)向上类型转换(隐式/自动类型转换),是小类型到大类型的转换。不存在风险。

2)向下类型转换(强制类型转换),是大类型向小类型转换。有风险。

3)instanceof运算符,来解决引用对象的类型,避免类型转换的安全问题。(animal instanceof Cat)

3、多态实现方式

Java 的多态特性通过方法重载和方法重写的方式实现,它可以让程序更加灵活和可扩展。方法重载发生在编译时,而方法重写则通过动态绑定在运行时确定执行哪个方法。

1)方法重载

方法重载是指在同一个类中,允许存在多个方法名相同但参数不同的方法。方法的选择是在编译时确定的。

class Printer {
    // 打印整数
    public void print(int a) {
        System.out.println("Printing integer: " + a);
    }

    // 打印字符串
    public void print(String str) {
        System.out.println("Printing string: " + str);
    }

    // 打印浮点数
    public void print(double a) {
        System.out.println("Printing double: " + a);
    }
}

public class TestOverloading {
    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print(100);      // 调用 print(int)
        printer.print("Hello"); // 调用 print(String)
        printer.print(99.99);    // 调用 print(double)
    }
}

2)方法重写

方法重写是指子类重新实现父类已经定义的某个方法,从而改变该方法的行为。方法重写的实现是在运行时通过动态绑定来确定。

class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("Cat meows");
    }
}

public class TestPolymorphism {
    public static void main(String[] args) {
        Animal animal1 = new Dog();  // 父类引用指向子类对象
        Animal animal2 = new Cat();  // 父类引用指向子类对象

        animal1.sound();  // 输出:Dog barks
        animal2.sound();  // 输出:Cat meows
    }
}

4、多态实例代码

多态的体现是父类的引用指向了自己的子类对象,父类的引用也可以接收自己的对象。实现多态的前提是必须是类与类之间只有关系,要么继承或实现。通常还有一个前提,存在覆盖。多态的好处是多态的出现大大的提高了程序的扩展性。

例如:

public class Main {
  public static void main(String[] args) {
    Animal myAnimal = new Animal();  // 创建 Animal 对象
    Animal myCat = new Cat();  // 创建 Cat 对象
    Animal myDog = new Dog();  // 创建 Dog 对象
    myAnimal.eat();
    myCat.eat();
    myDog.eat();
  }
}
class Animal { public void eat() { System.out.println("吃饭"); } } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void catchMouse() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void kanJia() { System.out.println("看家"); } }

“继承”和“多态性”对于代码可重用性很有用:创建新类时,重用现有类的属性和方法。

5、多态的核心特性

1)父类引用指向子类对象

多态的实现依赖于父类引用指向子类对象。例如,在上面的例子中,Animal animal1 = new Dog();Animal animal2 = new Cat();,虽然 animal1animal2Animal 类型的引用,但它们指向的是 DogCat 类型的对象。

2)动态绑定

在方法调用时,Java 会根据对象的实际类型(而不是引用类型)来决定调用哪个方法,这一过程是在运行时发生的,称为动态绑定。

3)方法重写

子类必须使用 @Override 注解来标记重写父类的方法,这样可以确保子类正确地重写了父类的方法。方法签名(方法名、参数列表)必须与父类中的方法完全一致。父类的方法可以是 publicprotecteddefault,但不能是 private,否则子类无法重写该方法。

6、多态的好处

1)提高代码的灵活性和扩展性

使用多态,代码的实现可以更加通用和灵活。如通过父类引用来调用子类方法,可以使得代码在运行时根据具体的子类类型执行不同的行为。

2)减少代码的耦合度

多态使得代码更加松散耦合,父类可以定义标准接口,子类可以实现具体的行为。调用者不关心子类的具体类型,只需要关心父类定义的接口即可。

3)支持设计模式

多态是许多设计模式的基础,如策略模式(Strategy Pattern)、模板方法模式(Template Method Pattern)等。通过多态,策略或算法的切换可以不改变客户端代码的逻辑。

4)提高代码的可维护性

通过多态,代码变得更易于维护,因为新的子类可以通过继承或实现接口的方式添加到程序中,而不需要修改现有的代码。

推荐阅读
cjavapy编程之路首页