Java多态⭐

方法或对象具有多种形态,是面向对象的第三大特征。
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是 同一个接口,使用不同的实例而执行不同操作。
多态是建立在封装和继承之上的。
一、具体体现:
1、方法多态:
通过方法重写(覆盖)和方法重载体现多态。
2、对象多态(核心):
(1) 一个对象的编译类型和运行类型可以不一样。
(2) 编译类型在定义对象时就确定了,不能改变。
(3) 运行类型是可以变化的。
(4) 编译类型看定义时 = 的左边,运行类型看 = 的右边。
例:
Animal animal = new Dog(); //animal 编译类型为Animal ,运行类型为Dog,即父类对象引用可以指向子类对象。
animal = new Cat(); //anomal 运行类型又变成了Cat,编译类型依旧是Animal。
二、细节:
1、多态的前提:两个类存在继承关系 和 多态的向上转型。
向上转型:
本质:父类的引用指向子类的对象。 父类可以不是直接父类。(把子类对象升级到父类,向上转)
语法:父类类型 引用名 = new 子类类型();
特点:可以根据访问权限调用父类的所有成员;
不能调用子类特有成员;
因为在编译阶段,可以调用哪些成员是由编译类型决定的。
最终运行效果看子类的具体实现。
因为运行时,只看运行时类型,不能使用特有成员是因为编译类型限制。
而运行时看实际运行类型,此时肯定时子类,那么就看子类的具体实现。
运行时若属性同名,则优先使用父类属性,方法则优先使用子类方法:

2、多态的向下转型
语法:子类类型 引用名 = (子类类型) 父类引用;
只能强转父类引用,不能强转父类对象。
要求父类的引用必须指向的是当前目标类型的对象。
可以调用子类类型中所有的成员。
通俗来说:
就是父类引用本来指向的就是子类对象,堆中的对应空间本就是子类对象。
然后才能将这个堆空间中原来就是子类对象的父类引用强转成子类对象。
若父类引用本来就指向父类对象,那不能强转成子类对象。强转时,编译不报错,但是运行可能出错。
3、属性重写 (解释1、中为何重名时会使用子类重写方法,不会使用子类同名属性。)
因为属性没有重写概念,所以不会像方法一样,子类重写了父类的方法,
因此访问时,属性只看编译类型,而方法看运行类型。
4、instanceof :用来判断是否是某一类型或该类型的子类
语法: A instanceof B
A为对象引用,B为某种类型
这里 看的是A的运行类型,而不是引用类型。

java 复制代码
class AA{}
class BB extends AA{}
public static void main(String[] args){
    // aa 编译类型为AA,运行类型是 BB
    AA aa = new BB();
    System.out.println(aa instanceof AA);//true
    System.out.println(aa instanceof BB);//true,因为运行类型是BB,所以才为true,若判断编译类型,很显然AA不是BB自身或子类
}

三、动态绑定机制⭐
1、当调用对象方法时,该 方法会和该对象的内存地址(运行类型)绑定。
2、当调用对象属性时,没有动态绑定机制,哪里声明,那里使用。
原理应该在jvm中会有
例:

java 复制代码
class A{
    int i = 10;
    int getI(){
        return i;
    }
    int sum(){
        return getI() + 10;
    }
    int sum1(){
        return i + 10;
    }
}

class B extends A{
   int i = 20;
   int getI(){
        return i;
    }  
}
public static void main(String[] args){
    A a = new B();
    //调用a.sum(),发现B类中没有sum()函数
    //调用A类中sum()
    //A类sum()函数中有getI()函数,动态绑定机制,因为实际对象时B类对象,
    //因此调用B类里的getI()
    //B类getI()里需要返回变量i,
    //属性没有动态绑定,在哪使用就返回哪里的
    //所以返回B里的i,即20
    //最后返回值为20+10=30

    system.out.print(a.sum());//30

    //B里没有sum1(),调用A里的sum1()
    //用到属性i,那里调用使用哪里的,
    //最后返回10 + 10 =20

    system.out.print(a.sum1());//20
}

四、多态应用
1、多态数组
可以将数组声明成父类类型,然后接收不同的子类类型对象。
使用时可以直接循环使用共有方法和属性。
想要使用子类特有的方法时,可以先instanceof判断类型,然后向下转型,再调用特有方法。
2、多态参数
方法定义的形参类型为父类类型,实参类型为子类类型。

相关推荐
守护者1705 分钟前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
源码哥_博纳软云6 分钟前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络8 分钟前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
学会沉淀。14 分钟前
Docker学习
java·开发语言·学习
如若12315 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
初晴~1 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
黑胡子大叔的小屋2 小时前
基于springboot的海洋知识服务平台的设计与实现
java·spring boot·毕业设计
ThisIsClark2 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
雷神乐乐2 小时前
Spring学习(一)——Sping-XML
java·学习·spring
小林coding3 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云