Java多态详细解析

1.多态基本介绍

首先我们要搞清楚几个基本问题,什么是多态?多态是用来干什么的?多态现实意义是什么?

(1)什么是多态?

同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。

(2)多态是用来干什么的?

封装、继承、多态是面向对象编程的三大特性。我们知道,封装可以隐藏实现细节,使得代码可以模块化;继承可以扩展已经编写好的代码类。他们的主要目的都是为了——代码重用。而多态除了解决代码复用性问题之外,还可以解决项目中紧耦合的问题(模块之间关系太紧密,存在相互调用。),提高程序的可扩展性。

(3)多态现实意义是什么?

现实里面,事物经常会出现多种形态。比如说,张三是学生,同时张三也是一个,即出现两种形态。

2.多态定义

  1. 多态是继封装、继承之后,面向对象的第三大特性。

  2. 实现多态的前提条件是,必须有父类子类关系

  3. 多态的定义和使用格式:

    定义格式:父类类型 变量名 = new 子类类型()

3.多态成员特点

等式左边是编译类型,等式右边是运行类型。

定义两个类AA和BB,用于展示多态成员特点。其中BB继承AA。

class AA{
    public int num = 10;
    public void say(){
        System.out.println("这是AA类的say方法");
    }
}

class BB extends AA{
    public int num = 20;
    public void say(){
        System.out.println("这是BB类的say方法");
    }
}

(1)多态成员变量

属性没有重写之说!属性的值看编译类型的属性值。

public class polymorphic {
    public static void main(String[] args) {
        AA aa = new BB();
        System.out.println(aa.num);//输出 10
    }
}

(2)多态成员方法

调用方法时,按照从子类(运行类型)开始查找方法,子类没有则逐级往上,然后调用。
注意:只能运行编译类型拥有的方法,如果运行类型没有对应的方法,则执行编译类型的方法。

public class polymorphic {
    public static void main(String[] args) {
        AA aa = new BB();
        //因为运行时,aa的运行类型是BB,所以执行BB的say方法
        aa.say();   //输出 这是BB类的say方法
    }
}

4.instance of 关键字

作用:返回类型为布尔类型,用于判断某个对象的运行类型是否为XX类型或者XX类型的子类型

public class polymorphic {
    public static void main(String[] args) {
        AA aa = new BB();
        System.out.println((aa instanceof BB));//输出true,说明aa的运行类型是BB
    }
}

5.多态的转型

(1)向上转型

多态本身就是一个向上转型的过程。

使用格式:父类类型 变量名 = new 子类类型();

AA aa = new BB();

适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作(需要遵守访问权限)。

(2)向下转型

使用格式:子类类型 引用名 = (子类类型) 父类引用;

AA aa = new BB();
BB bb = (BB) aa;//向下转型

注意:要求父类的引用必须指向的是当前目标类型的对象。 下面用一个例子来说明。

//新建了一个类CC来证明
class CC extends AA{}
AA aa = new BB();//向上转型
BB bb = (BB) aa;//向下转型
CC cc = (CC) aa;//此处不通过,报错。

此处,AA是BB和CC的父类,但是BB和CC之间没有直接联系,cc不能指向对象BB,就会报错。

在这里插入图片描述

适用场景:当需要使用子类特有功能的时候。

6.动态绑定机制

新建两个类来说明Java多态中的动态绑定机制。

class A{//父类
    public int i = 10;//动态绑定机制
    
    public int sum(){
        return getI() + 10;//20+10
    }
    public int sum1(){
        return i + 10;//10 + 10
    }
    public int getI(){
        return i;
    }
}
class B extends A{//子类
    public int i = 20;
    
//    public int sum(){
//        return i + 20;
//    }
    public int getI(){
        return i;
    }
//    public int sum1(){
//        return i + 10;
//    }
}

实例运行

public class DynamicBinding {
	public static void main(String[] args) {
        //a 的编译类型 A, 运行类型 B
        A a = new B();//向上转型
        System.out.println(a.sum());//? 30
        System.out.println(a.sum1());//? 20
	}
}
  1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定

    如上面的例子, 子类中没有 sum() 方法,因此调用父类的。父类的 sum() 方法中调用了 getI() 方法,因此从子类中查找 getI() 方法(因为a的运行类型是B)。由于子类中定义的 i 值为20,所以 sum() 方法得到的值为 20 + 10 = 30 。

  2. 当调用对象类型时,没有动态绑定机制,哪里声明,哪里使用(属性没有动态绑定机制)

    同理,在调用 sum1() 方法时,由于子类没有此方法,因此调用父类的方法。由于属性没有动态绑定机制,父类中声明的 i 值为10,因此 sum1() 方法得到的结果是10 + 10 = 20

7.多态的应用

具体多态的应用举例看多态的应用实际举例

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值