面向对象编程三大特征之一 多态

2022/2/14 14:11:36

本文主要是介绍面向对象编程三大特征之一 多态,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 多态
    • 简单理解
    • 多态的前提
    • 多态访问成员的特点
    • 多态的好处
    • 多态的弊端
    • 向下转型

多态

简单理解

某一事物,在不同时刻表现出来的不同状态
例如:

水:
固态、液态、气态
固态的水是水、液态的水也是水、气态的水也是水
水果:
波罗蜜、香蕉、榴莲
波罗蜜是水果、香蕉是水果、榴莲是水果
水果是波罗蜜,这么说是不可以的。
动物:
狗、虎、猫、大象
狗是动物,这么说是没问题的
动物是狗,这么说是不可以的。

多态的前提

        1、要有继承关系
        2、要有方法的重写。
            其实没有重写也是可以的,但是不重写就没有意义
            动物都有吃这个方法,但是每个具体的动物吃的实现不一样,变现出不同动物的特有属性
        3、要有父类的引用指向子类对象

格式

父类名 f = new 子类名(…);

多态访问成员的特点

1、成员变量
编译看左,运行看左
2、构造方法(初始化作用)
创建子类对象的时候,先访问父类中的构造方法,对父类的数据先进行初始化
3、成员方法
编译看左,运行看右。
因为成员方法存在重写,所以访问看右边
4、静态成员方法
编译看左,运行也看左。
(由于被static修饰的成员都是与类相关的,这里不是重写,所以运行的时候,访问的还是左边的)

代码示例:

package com.shujia.wyh.day11;

class Fu3{
    int num = 100;
    public void show(){
        System.out.println("这是父类中show()方法");
    }

    public static void fun(){
        System.out.println("这是父类中的静态fun方法");
    }
}

class Zi3 extends Fu3{
    int num = 1000;

    @Override
    public void show(){
        System.out.println("这是子类中的show()方法");
    }

    public void show2(){
        System.out.println("这是子类特有的方法1");
    }
    public static void fun(){
        System.out.println("这是子类中的静态fun方法");
    }
}

public class PolymorphicDemo1 {
    public static void main(String[] args) {
        //多态创建了一个对象
        Fu3 f = new Zi3();//父类指向子类对象
        System.out.println(f.num);//100

        f.show(); // 这是子类中的show()方法
        f.fun();//这是父类中的静态fun方法
    }
}

多态的好处

1、多态可以使代码的扩展性很好(这是由继承所保证的)
2、多态可以使代码的维护性很好(这是由多态保证的)

代码示例:

package com.shujia.rx.day12;

class Animal{
    String name;
    int age;

    public Animal() {
    }

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

    public void sleep(){
        System.out.println("睡觉");
    }
    public void eat(){
        System.out.println("吃");
    }
}

class Dog extends Animal{
    public Dog() {
    }

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

    @Override
    public void sleep() {
        System.out.println("狗侧着睡");
    }

    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

}

class Cat extends Animal{
    public Cat() {
    }

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

    @Override
    public void sleep() {
        System.out.println("猫趴着睡");
    }

    @Override
    public void eat() {
        System.out.println("????吃鱼");
    }
}
//用工具类改进
class AnimalTool{
    public static void useAnimal(Animal animal){ //Animal animal=new Cat("小白",9);
        //利用了多态访问成员方法的特点,编译看左,运行看右,实际调用的是子类对象中的方法。
        animal.sleep();
        animal.eat();
    }
}

public class CatDogDemo {
    public static void main(String[] args) {
        //养一只狗
        Dog d1 = new Dog("小黄",7);
        d1.sleep();
        d1.eat();
        useDog(d1);
        //养一只猫
        Cat c1 = new Cat("小白",9);
        c1.sleep();
        c1.eat();
        AnimalTool.useAnimal(c1);

    }
    
    //用方法改进
    public static void useDog(Dog dog){
        dog.sleep();
        dog.eat();
    }
}

多态的弊端

多态无法访问父类中方法名一样的方法

如果我想使用子类中的特有方法,还必须使用多态,怎么办呢?
1)就不使用多态,创建子类对象然后调用方法,但是再次创建对象,还会在堆内存中开辟空间,很有可能会造成资源浪费。
2)java考虑到这样的问题,提供了一个技术给我们使用:向下转型

向下转型

将父类的引用强制转换成子类的引用
格式:

子类类名 变量名 = (子类类名)父类的引用;

注意:
要求转型的类与父类引用存在继承关系,并且一开始创建多态的时候,使用的是该类。

代码示例:
向下转型猫狗案例

class Animal2{
    public void eat(){
        System.out.println("吃");
    }
}

class Dog2 extends Animal2{
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

    public void lookDoor(){
        System.out.println("看门");
    }
}

class Cat2 extends Animal2{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse(){
        System.out.println("猫捉老鼠");
    }
}

public class PolymorphicDemo4 {
    public static void main(String[] args) {
        //以多态的形式创建一个对象
        Animal2 a = new Dog2();
        a.eat();
//        a.lookDoor();

        //向下转型访问子类中特有的方法
        Dog2 d = (Dog2) a;
        d.eat();
        d.lookDoor();

        //ClassCastException类转换异常
        Cat2 c = (Cat2) a; // 此刻内存中还是一个Dog2的对象,内存图解如下:
        c.catchMouse();
    }
}

在这里插入图片描述
代码示例:
不同地方饮食文化不同的案例

package com.shujia.wyh.day11;

/*
        不同地方饮食文化不同的案例
            Person
                eat()
            SouthPerson
                eat()
            NorthPerson
                eat()

 */
class Person{
    public void eat(){
        System.out.println("吃");
    }
}

class SouthPerson extends Person{
    @Override
    public void eat() {
        System.out.println("南方人吃米饭");
    }

    public void playMaJiang(){
        System.out.println("南方人打麻将");
    }
}

class NorthPerson extends Person{
    @Override
    public void eat() {
        System.out.println("北方人吃面食");
    }

    public void bath(){
        System.out.println("北方人搓澡");
    }
}

public class PolymorphicDemo5 {
    public static void main(String[] args) {
        //多态创建南方人对象
        Person p = new SouthPerson();
        p.eat();
//        p.playMaJiang();
        //向下转型
        SouthPerson sp = (SouthPerson) p;
        sp.eat();
        sp.playMaJiang();

        //多态创建北方人对象
        Person p2 = new NorthPerson();
        p2.eat();
//        p2.bath();
        //向下转型
        NorthPerson np = (NorthPerson) p2;
        np.eat();
        np.bath();
    }
}


这篇关于面向对象编程三大特征之一 多态的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程