Java中的多态究竟是什么?

发布于:2023-12-13 ⋅ 阅读:(76) ⋅ 点赞:(0)

一.概念

多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态

在这里插入图片描述

二.使用条件

1.必须是在继承情况下
2.子类方法必须重写
3.需由父类调用

```java
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+"正在吃饭");
//        return null;
    }
}
class Dog extends Animal{
    public Dog(String name,int age){
        super(name,age);
    }
    public String color;
    public void eat(){
        System.out.println(super.name+"正在吃狗粮");
//        return null;
    }
}
class Cat extends Animal{
    public Cat(String name,int age){
        super(name,age);
    }
    public String hair;
    public void eat(){
        System.out.println(super.name+"正在吃猫粮");
    }
}
public class test {
    public static void main(String[] args) {
        Animal animal = new Dog("小黄狗",1);
        animal.eat();

        Animal animal1 = new Cat("小白猫",1);
        animal1.eat();

    }
}

在这里插入图片描述
在这里插入图片描述

三.重写

1.概念

也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程
进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定
于自己的行为。 也就是说子类能够根据需要实现父类的方法。

2.使用条件

1.被final修饰的方法,不能被重写,这个方法叫做密封方法。
2.被static修饰方法,不能被重写。
3.子类重写方法时,子类方法的访问修饰限定符要大于等于父类方法的权限。
4.被private修饰的方法,不能被重写。因为被修饰说明是私有的,只能在当前类中使用。
5.重写方法返回值可以不相同(返回值类型构成父子类关系)

3.与重载对比

区别点 重写(override) 重载(overload)
参数列表 一定不能修改 可以修改
返回类型 一定不能修改(除非可以构成父子关系) 可以修改
访问限定符 限制只能降低不能提高 可以修改

在这里插入图片描述

参数列表是指参数的个数,位置,类型。
返回类型
在这里插入图片描述
访问限定符
在这里插入图片描述

4.举例

在这里插入图片描述

5.为什么需要重写

现在的科技发展飞速,产品迭代速度也非常快,在几年前我们的手机很多功能没有实现,以汽车的暖气来说,多年前可能只有车内显示屏暖气开关的功能,而现在增加了实时温度显示,有的车上并没有感温器,那我们在编写程序时,难道还需要对那些车上没有感温器装置的系统编写温度显示功能吗?这显然不现实。
在这里插入图片描述
在这里插入图片描述

1.重写规则

对于已经投入使用的类,尽量不要进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容,并且添加或者改动新的内容。

2.静态绑定–重载

重载就是一种静态绑定->编译期间绑定的
静态绑定在编译时,根据用户传参就可以确定调用的方法

3.动态绑定–重写

重写:用@Override修饰(编译器自动添加)

动态绑定在编译时并不能确定调用哪一个方法,只有当运行时才能确定。

四.向上转型

第一种传参方式:直接赋值

向上转型就是将子类对象赋给父类
语法格式:父类类型 对象名 = new 子类类型()

Animal animal = new Dog("小黄狗",1);
class Animal{
    public int age;
    public String name;
    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 String color;
    public void barks(){
        System.out.println(this.name+"汪汪汪");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog("小黄",1);
        Animal animal = dog;
        //这里就是向上转型
             Animal animal = new Dog("小黄",1);
    }
}

而向上转型后,还是只能访问自己特有的方法
发生重写(父类和子类拥有同样的方法)此时,就调用子类的。这叫做动态绑定

第二种传参方式:通过传参

在这里插入图片描述
在这里插入图片描述
这里同一个引用调用了同一个方法,引用不同对象,有不同的情况。就叫做多态。

优缺点

向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法。(只有重写时,才能访问)。

五.向下转型

举例

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+"正在吃饭");
//        return null;
    }
}
class Bird extends Animal{
    public int high;
    public  Bird(String name,int age){
        super(name,age);
    }
    public void fly(){
        System.out.println(super.name+"正在飞");
    }
}

用Animal调用子类飞的方法,编译错误,因为该方法是子类特有的,没有发生重写。此时向下转型应用而生。
在这里插入图片描述
向下转型强制类型转换
在这里插入图片描述
向下转型并不安全

缺点

在这里插入图片描述

六.多态的优缺点

优点

1.能够降低代码的 “圈复杂度”, 避免使用大量的 if - else
2. 可扩展能力更强
在下面的代码中可以体现

class ShowShape{
    public void draw(){
        System.out.println("打印图像!");
    }
}
class Cycle extends ShowShape{
    public void draw(){
        System.out.println("圆形⚪");
    }
}
class Square extends ShowShape{
    public void draw(){
        System.out.println("正方形");
    }
}

不使用多态

public class Test {
    public static void func(ShowShape showShape){
        showShape.draw();
    }
    public static void main(String[] args) {
        Cycle cycle = new Cycle();
        Square square = new Square();
        String[] shapes = {"cycle", "square"};
        for (String shape : shapes) {
            if (shape.equals("cycle")) {
                cycle.draw();
            } else if (shape.equals("square")) {
                square.draw();
            }
        }
    }
}

如果使用多态,代码完全可以不用如此复杂。

 public static void main(String[] args) {
        Cycle cycle = new Cycle();
        Square square = new Square();
        ShowShape[] shapes = {cycle,square};
        for (ShowShape showShape:shapes) {
            showShape.draw();
        }
    }
}

第二个优点体现
如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低.

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

对于类的调用者来说(drawShapes方法), 只要创建一个新类的实例就可以了, 改动成本很低.
而对于不用多态的情况, 就要把 drawShapes 中的 if - else 进行一定的修改, 改动成本更高.

缺点

多态缺陷:代码的运行效率降低。

  1. 属性没有多态性
    当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性
  2. 构造方法没有多态性

码字不易,感谢观看
如果对你有帮助的话,记得点赞👍评论+关注吧

本文含有隐藏内容,请 开通VIP 后查看