七、Java面向对象三大特征之一——多态

目录

1.多态的定义

2.多态存在的三个条件

3.多态的使用格式:左父右子

4.多态中成员的访问特点

5.对象的向下转型与 instanceof 关键字

6.使用多态的好处


1.多态的定义

(1)对于继承关系,多态是同一个行为具有多个不同表现形式或形态的能力。即同一个父类方法在不同子类中具有不同的表现形式。

(2)对于接口实现,多态就是同一个接口,使用不同的实例而执行不同操作。

(3)多态是方法的多态,不是属性的多态。

(4)多态体现为子类对象赋值给父类引用变量,然后在运行时才表现出具体的子类特征。例如所有动物都会吃东西,但是每种动物吃的东西不一样。当我们面前有一只小动物时,我们只是把它当做动物看待,知道他会叫,但是具体是什么动物,怎么叫,只有他叫了才知道。

(5)多态包括编译时多态(静态多态)和运行时多态(动态多态)。编译时多态主要是指方法的重载,是在编译时多态性的体现,但它在运行时谈不上多态;而运行时多态指在程序运行时方法调用上产生的多态性,它是通过动态绑定(在程序执行期间判断其引用对象的实际类型并调用相应的方法)实现的,即我们通常所说的多态。

2.多态存在的三个条件

(1)继承:继承是多态的前提,没有继承关系就体现不出多态。

(2)重写:子类必须重写父类的方法,而不是直接调用父类的方法。

(3)父类引用指向子类对象(向上转型):子类实例化时把子类看成是父类进行实例化。

3.多态的使用格式:左父右子

无论是继承关系还是接口实现,都应该遵循左父右子,即把子类当做父类来看待。其中继承关系中的父类一般为抽象类,强制重写父类抽象方法,以满足重写条件。

//父类:动物
public abstract class Animal {
    public abstract void eat();
}

//子类:狗
public class Dog extends Animal{

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

//子类:猫
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

//子类:鸡
public class Chicken extends Animal {
    @Override
    public void eat() {
        System.out.println("鸡吃米");
    }
}

下面我们用多态的实现方式和普通实现方式的写法作对比。

    public static void main(String[] args) {

        //普通的子类实例化
        Dog dog = new Dog();
        dog.eat();
        Cat cat = new Cat();
        cat.eat();
        Chicken chicken = new Chicken();
        chicken.eat();

        System.out.println("=========");
        
        //多态实现子类的实例化
        Animal animal1 = new Dog();
        animal1.eat();
        Animal animal2 = new Cat();
        animal2.eat();
        Animal animal3 = new Chicken();
        animal3.eat();
    }

    结果:

    狗吃骨头
    猫吃鱼
    鸡吃米
    =========
    狗吃骨头
    猫吃鱼
    鸡吃米

4.多态中成员的访问特点

(1)成员变量

①直接访问:等号左边是谁

②间接访问:方法属于谁(不重写属于父类,重写后属于子类)

public class Father {
    int age = 100;

    public void getAge(){
        System.out.println(age);
    }
}


public class Son extends Father {
    int age = 30;

    @Override
    public void getAge(){
        System.out.println(age);
    }
}
    public static void main(String[] args) {
        
        //多态的写法
        Father son1 = new Son();
        System.out.println(son1.age);
        son1.getAge();

        System.out.println("=====");

        //普通写法
        Son son2 = new Son();
        System.out.println(son2.age);
        son2.getAge();
    }

    结果:
    
    100//父类age
    30
    =====
    30//子类age
    30

(2)成员方法:编译看左边,运行看右边

①编译看左边:若需要调用的方法只存在于子类中,则用多态的方式调用会报错。

②运行看右边:对于子类重写父类的方法,运行时会自动加载重写后的方法。

public class Father {

    public void getAge(){
        System.out.println("父类方法");
    }
}

public class Son extends Father {

    @Override
    public void getAge(){
        System.out.println("重写过的方法");
    }

    public void particular(){
        System.out.println("子类特有的方法");
    }
}
    public static void main(String[] args) {
        
        Father father = new Son();
        //father.particular();//错误写法,父类中没有该方法,编译不通过
        father.getAge();//运行时看右边是Son,因此是Son的getAge方法

    }

5.对象的向下转型与 instanceof 关键字

针对上面的多态写法,如果我们定义了一个方法,此方法会接受参数为Father类,但是我们需要使用他子类中的特有方法该如何实现呢,此处就需要把Father向下转型为Son类。

    public static void funSon(Father father){
        //instanceof关键字:判断当前对象是否属于某个类,返回值为boolean类型
        if(father instanceof Son) {//只有原本就是Son才能转为Son
            Son son = (Son) father;//向下转型格式
            son.particular();
        }
    }

    //运行
    public static void main(String[] args) {
        Father father = new Son();
        funSon(father);//此时father为子类对象,可以使用子类特有的方法
    }

需要注意的是:

①必须保证创建对象的时候是要转型的子类,才能转型成该子类。

②如果转型对象原本不是该子类,就不能转为这个子类,否则运行时会报错。

6.使用多态的好处

(1)可替换性:多态对已存在代码具有可替换性。例如,多态对动物类适用,对其他任何动物,如猫,狗,也同样适用。

(2)可扩充性:多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。

(3)接口性:多态是父类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。

(4)灵活性:它在应用中体现了灵活多样的操作,提高了使用效率。

(5)简化性:多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值