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、多态参数
方法定义的形参类型为父类类型,实参类型为子类类型。

相关推荐
青云交7 分钟前
Java 大视界 -- 基于 Java 的大数据可视化在城市空气质量监测与污染溯源中的应用
java·spark·lstm·可视化·java 大数据·空气质量监测·污染溯源
森语林溪21 分钟前
大数据环境搭建从零开始(十七):JDK 17 安装与配置完整指南
java·大数据·开发语言·centos·vmware·软件需求·虚拟机
郝开1 小时前
Spring Boot 2.7.18(最终 2.x 系列版本)1 - 技术选型:连接池技术选型对比;接口文档技术选型对比
java·spring boot·spring
小猪咪piggy2 小时前
【项目】小型支付商城 MVC/DDD
java·jvm·数据库
知兀2 小时前
【Spring/SpringBoot】SSM(Spring+Spring MVC+Mybatis)方案、各部分职责、与Springboot关系
java·spring boot·spring
向葭奔赴♡2 小时前
Spring IOC/DI 与 MVC 从入门到实战
java·开发语言
早退的程序员2 小时前
记一次 Maven 3.8.3 无法下载 HTTP 仓库依赖的排查历程
java·http·maven
向阳而生,一路生花2 小时前
redis离线安装
java·数据库·redis
Tigshop开源商城系统2 小时前
Tigshop 开源商城系统 php v5.1.9.1版本正式发布
java·大数据·开源·php·开源软件
2401_841495642 小时前
【数据结构】基于BF算法的树种病毒检测
java·数据结构·c++·python·算法·字符串·模式匹配