首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >多态(全)

多态(全)

作者头像
寻星探路
发布2025-12-17 19:52:06
发布2025-12-17 19:52:06
120
举报
文章被收录于专栏:CSDN博客CSDN博客

一、多态

1.什么是多态

通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产⽣出不同的状态,有不同的结果。

2.多态是如何实现的

多态的实现需要满足以下的条件:

(1)必须在继承体系下

(2)子类必须要对父类中方法进行重写

(3)通过父类的引用调用重写的方法

代码语言:javascript
复制
public class Animal {
    String name;
    int age;
    public Animal(String name, int age){
        this.name = name;
        this.age = age;
    }
    public void eat(){
        System.out.println(name + " 吃饭 ");
    }
}

public class Cat extends Animal{
    public Cat(String name, int age){
        super(name, age);
    }
    @Override
    public void eat(){
        System.out.println(name+" 吃⻥ ~~~");
    }
}

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

    @Override
    public void eat() {
        System.out.println(name + " 吃⻣头 ~~~");
    }
}

public class TestAnimal {
    public static void eat(Animal a){
        a.eat();
    }
    public static void main(String[] args) {
        Cat cat = new Cat(" 元宝 ",2);
        Dog dog = new Dog("⼩七 ", 1);
        eat(cat);
        eat(dog);
    }
}

运⾏结果:
元宝吃⻥~~~
元宝正在睡觉
⼩七吃⻣头~~~
⼩七正在睡觉

当类的调用者在编写 eat 这个方法的时候,参数类型为Animal(⽗类),此时在该方法内部并不知道, 也不关注当前的a引用指向的是哪个类型(哪个⼦类)的实例.此时a这个引用调用eat方法可能会有多种 不同的表现(和a引用的实例相关),这种行为就称为多态.

二、重写(覆盖/覆写)

1.方法重写的规则

(1)子类在重写父类的方法时,⼀般必须与⽗类方法原型⼀致:返回值类型方法名 (参数列表) 要完全⼀致

(2)被重写的方法返回值类型可以不同,但是必须是具有父子关系的

(3)访问权限不能比父类中被重写的方法的访问权限更低。(public>protected>   >private)

例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为protected

(4)父类被final、static、private修饰的方法、构造方法都不能被重写。

(5)重写的方法,可以使⽤ @Override 注解来显式指定.有了这个注解能帮我们进行⼀些合法性校验. 例如不小心将方法名字拼写错了(比如写成aet),那么此时编译器就会发现⽗类中没有aet⽅法,就 会编译报错,提示无法构成重写.

代码语言:javascript
复制
public 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 +" 正在吃饭....");
    }
}

public class Bird extends Animal{

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

    @Override
    public void eat() {
        System.out.println(this.name +" 正在吃鸟粮....");
    }

    public void fly() {
        System.out.println(this.name+" 正在飞....");
    }
}

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

    @Override
    public void eat() {
        System.out.println(this.name +" 正在吃狗粮....");
    }

    public void bark() {
        System.out.println(this.name+" 正在汪汪叫....");
    }
}

2.动态绑定

也称为后期绑定(晚绑定),即在编译时,不能确定⽅法的⾏为,需要等到程序运行时,才能够确定具体调用那个类的方法。

代码语言:javascript
复制
public 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 +" 正在吃饭....");
    }
}

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

    @Override
    public void eat() {//子类重写父类的方法
        System.out.println(this.name +" 正在吃狗粮....");
    }

    public void bark() {
        System.out.println(this.name+" 正在汪汪叫....");
    }
}

    public static void main(String[] args) {
        /*Dog dog = new Dog("旺财",10);
        Animal animal = dog;*/

        Animal animal = new Dog("旺财",10);//向上转型
        animal.eat();//这里调用了父类自己的方法,但是发生了动态绑定,结果是子类自己的方法
    }
}

动态绑定发生的条件:

(1)发生了向上转型

(2)子类进行了重写父类的方法

(3)通过父类引用调用了这个重写的方法

三、向上转型

向上转型:实际就是创建⼀个子类对象,将其当成父类对象来使用

代码语言:javascript
复制
 Animal animal = new Cat("元宝",2);

1.直接赋值

代码语言:javascript
复制
 Animal animal = new Cat("元宝",2);

2.参数传递

代码语言:javascript
复制
public static void func(Animal animal){
    animal.eat();
}

pcblic static void main(String[] args){
    Dog dog = new Dog("旺财",10);
    Bird bird = new Bird("啾啾",2);
    func(dog);
    func(bird);
}

3.返回值传递

代码语言:javascript
复制
public static Animal func2(int a) {
        if(a == 1) {
            return new Dog("旺财",10);
        }else {
            return new Bird("啾啾",19);
        }
}

向上转型的优点:让代码实现更简单灵活。

向上转型的缺陷:不能调用到子类特有的方法。

四、向下转型

将⽗类引用再还原为子类对象即可,即向下转换。

代码语言:javascript
复制
public static void main(String[] args) {
        Animal animal = new Dog("旺财",10);

        if(animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.bark();
            System.out.println("animal 引用的是 Dog这样的对象");//111
        }else {
            System.out.println("animal 引用的不是 Dog这样的对象");
        }

        if(animal instanceof Bird) {
            Bird bird = (Bird) animal;
            bird.fly();
            System.out.println("animal 引用的是 Bird这样的对象");
        }else {
            System.out.println("animal 引用的不是 Bird这样的对象");//22222
}

#注:

(1)由于这里的父类不一定是子类,所以要强转

(2)向下转型不安全,为了安全,引入了instanceof,如果该表达式为true,则可以安全转换。

五、多态的优缺点

1.降低了圈复杂度(减少了if语句、循环语句的使用)

代码语言:javascript
复制
 public static void drawShapes() {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();

        String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};

        for (int i = 0; i < shapes.length; i++) {
            String shape = shapes[i];
            if(shape.equals("cycle")) {
                cycle.draw();
            }else if(shape.equals("rect")) {
                rect.draw();
            }else {
                flower.draw();
            }
        }
    }
代码语言:javascript
复制
 public static void drawShapes2() {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();

        Shape[] shapes = {rect,cycle,rect,cycle,flower};
        //Shape[] shapes = {new Rect(),new Cycle(),new Rect(),new Cycle(),new Flower()};

        for(Shape shape : shapes) {
            shape.draw();
        }
    }

对比上面两串代码,我们不难发现,第二个代码明显更加的高级、易看懂

2.可扩展能⼒更强

如果要新增⼀种新的形状,使用多态的方式代码改动成本也比较低.

代码语言:javascript
复制
 class Triangle extends Shape {
     @Override
     public void draw() {
         System.out.println("△ ");
     }
 }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、多态
    • 1.什么是多态
    • 2.多态是如何实现的
  • 二、重写(覆盖/覆写)
    • 1.方法重写的规则
    • 2.动态绑定
  • 三、向上转型
    • 1.直接赋值
    • 2.参数传递
    • 3.返回值传递
  • 四、向下转型
  • 五、多态的优缺点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档