Java中的多态特性探究

2周前发布 gsjqwyl
14 0 0

文章标题:剖析Java中的多态特性

文章内容

文章目录

  • 多态
  • 向上转型与向下转型
    • 向上转型及重写
    • 重写与重载的差异
    • 动态绑定与静态绑定
    • 用代码阐释多态概念
    • 向下转型
  • 多态的优势
  • 总结

多态

  1. 多态的定义与意义:简单来讲,多态体现为“多种形态”,具体是指不同对象去完成同一任务时所展现出的不同结果或状态。举个例子,就如同一个人面对不同个体时会呈现出不一样的行为表现。
  2. 多态实现的三个条件
    在这里插入图片描述

向上转型与向下转型

在这里插入图片描述

向上转型及重写

  1. 向上转型的方式一:直接赋值
    将子类对象赋予父类类型的引用,格式为:父类类型 引用名 = new 子类类型()
class Animal {
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println(this.name + " 在进食 ");
    }
}

class Dog extends Animal {

    public Dog(String name, int age) {
        super(name, age);
    }

    public void back() {
        System.out.println(this.name + " 汪汪汪 ");
    }
}

public class test {
    public static void main(String[] args) {  
        // 向上转型
        Animal animal = new Dog("小白", 3);
        animal.eat(); // 调用父类的eat方法
    }
}
  1. 向上转型的方式二:传参
    在这里插入图片描述
  2. 向上转型的方式三:传返回值
    在这里插入图片描述
  3. 重写的条件:当父类实现的方法无法满足需求时可进行重写,重写需满足以下条件:
  4. 方法的返回值、方法名、参数列表均相同。
  5. 子类中被重写方法的访问修饰限定符要大于等于父类的(权限大小关系:private < 默认的 < protected < public)。
  6. 被private修饰的方法不能被重写。
  7. 被static修饰的方法不能被重写。
  8. 被final修饰的方法不可重写,因其具有恒定性。
  9. 构造方法也不能被重写。
public final void eat() {
    // ...
}

被重写方法的返回值类型需是父子关系。
在这里插入图片描述
重写指的是子类与父类中有同名方法,当子类对象赋予父类类型引用(向上转型)后,使用该对象调用方法时,调用的是子类的方法而非父类的方法,此过程称为动态绑定
如下是子类重写父类eat方法的示例:
在这里插入图片描述
@override注解可用于提示重写是否正确,避免语法错误。
在这里插入图片描述

重写与重载的差异

在这里插入图片描述
Object类是所有类的父类,若Dog类重写了自身的toString方法,则会使用重写后的toString方法;若未重写,则调用父类的toString方法。
在这里插入图片描述

动态绑定与静态绑定

  1. 静态绑定:在编译阶段就确定调用的方法,例如重载。
  2. 动态绑定:在编译阶段无法确定,在运行阶段才确定调用的方法,例如重写。
    在这里插入图片描述
    在这里插入图片描述

用代码阐释多态概念

在这里插入图片描述
无法调用子类特有的方法,只能调用父类的方法,只有重写后才会调用子类同名方法(例如eat())。
在这里插入图片描述

向下转型

  1. 将父类对象赋予子类类型的引用。
  2. 向下转型存在不安全因素。
    在这里插入图片描述
  3. 若animal引用的对象是Cat对象的实例,则转型成功;否则执行下方打印操作。
    在这里插入图片描述

多态的优势

  1. 能够降低代码的圈复杂度,避免大量使用if-else语句(圈复杂度指一段代码中条件语句和循环语句的个数)。
    不使用多态时,打印图形的代码示例:
class Shape {
    public void draw() {
        System.out.println("画图");
    }
}

class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("⬜");
    }
}

class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("⚪");
    }
}

class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("❀");
    }
}

class Test2 {
    public static void drawShapes() {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();
        String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};

        for (String shape : shapes) {
            if (shape.equals("cycle")) {
                cycle.draw();
            } else if (shape.equals("rect")) {
                rect.draw();
            } else {
                flower.draw();
            }
        }
    }

    public static void main(String[] args) {
        drawShapes();
    }
}

使用多态后的代码示例:

public static void main(String[] args) {
    Shape[] shapes = {new Cycle(), new Rect(), new Cycle(), new Rect(), new Flower()};
    // 向上转型
    for (Shape shape : shapes) {
        shape.draw();
    }
}
  1. 可扩展性强,新增一种新形状时,使用多态的代码成本较低。
class Flower extends Shape {
    public void draw() {
        System.out.println("花!");
    }
}
  1. 属性不存在多态性,当父类成员变量与子类成员变量同名时,通过父类引用只能访问父类的变量。
  2. 构造方法不存在多态性,因为不能重写,重写会导致构造逻辑混乱。
    在这里插入图片描述
    在这里插入图片描述

总结

  1. 多态主要包含以下三点内容:
    在这里插入图片描述
  2. 向上转型的作用:是实现重写的前提,即将子类对象赋予父类类型的引用。
  3. 动态绑定的作用:是实现多态的基础,在编译阶段无法确定调用的方法,在运行阶段才确定调用的方法。动态绑定在编译时看似调用父类方法,但运行时实际调用的是子类重写父类的方法
© 版权声明

相关文章

暂无评论

暂无评论...