一:多态的基本介绍
方法或者属性具有多种形态,是面向对象的第三大特征,多态是寄哪里在封装和继承基础之上的。
二:多态的具体体现
1:方法的多态
重写和重载就体现多态
package Data0801.Test0802;/*** 作者:sakura* 日期:2022年08月02日 00:05*/public class test02 {public static void main(String[] args) {A a = new A();a.sum(3,4);a.sum(3,4,6);B b = new B();b.sum(2,4);}}class A{//重载public double sum(int a, int b){return a+b;}public double sum(int a, int b,int c){return a+b+c;}}class B extends A{@Overridepublic double sum(int a, int b) {System.out.println("方法重写完毕");return super.sum(a, b);}}
2:对象的多态(重点,难点!!!)
:::danger
- 一个对象的编译类型和运行类型可以不一致
- 编译类型在定义对象是,就确定了,不能改变
- 运行类型是可以变化的
编译类型看定义是 = 好的左边,运行类型看 = 右边 :::
Animal animal = new Dog(); //编译类型是Animal,运行类型是Doganimal = new cat(); //换了一个引用对象,运行类型变成了Cat
三:代码案例
1:多态基本体现
public class test03 {public static void main(String[] args) {//编译类型和运行类型Animal animal = new Dog();animal.cry();Animal animal1 = new Cat();animal1.cry();}}public class Animal {public void cry(){System.out.println("动物在叫");}}public class Cat extends Animal{@Overridepublic void cry() {System.out.println("猫在叫");}}public class Dog extends Animal{@Overridepublic void cry() {System.out.println("狗在叫");}}
2:解决主人给动物喂食的问题
public class test04 {public static void main(String[] args) {Master sakura = new Master("sakura");Animal animal = new Cat("L");Food food = new fish("鱼");sakura.feed(animal,food);}}public class Master {private String name;public Master(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}public void feed(Animal animal , Food food){System.out.println("主人:" + this.name + "给 " + animal.getName() + "喂食:" + food.getName());}}public class Food {private String name;public Food(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}}public class fish extends Food{public fish(String name) {super(name);}}public class Animal {private String name;public Animal(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}}public class Cat extends Animal{public Cat(String name) {super(name);}}
四:多态细节注意事项和细节讨论
-
1:多态的向上转型
本质:父类的引用指向子类的对象
- 语法:父类类型 引用名 = new 子类类型( );
- 特点:编译类型看左边,运行类型看右边
- 可以调用父类的所有成员
- 不能调用子类的特有成员
- 最终运行效果看子类的具体实现 ```java Animal animal = new cat(); Objectobj = new cat(); //Object 也是cat的父类
//向上转型调用方法的规则如下: //(1)可以调用父类中的所有成员(需遵守访问权限) //(2)但是不能调用子类的特有的成员 //(3)因为在编译阶段,能调用哪些成员,是由编译类型来决定的 //animal.catchMouse();错误 // //(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法 //,然后调用,规则我前面我们讲的方法调用规则一致。
animal.eat(); //如果想调用子类中的特有方法只能,向下转型
<a name="QlIMJ"></a>#### 2:多态的向下转型- **_语法:子类类型 __引用名 = (子类类型) 父类引用_**- **_只能强转父类的引用,不能强转父类的对象_**- **_要求父类的引用必须指向的时当前目标类型的对象_**- **_当向下转型后,可以调用子类类型中的所有的成员_**```javaAnimal animal = new cat();Cat cat = (Cat)animal;
3:属性的值没有重写之说看编译类型
public class PolyDetail02 {public static void main(String[] args) {//属性没有重写之说!属性的值看编译类型Base base = new Sub();//向上转型System.out.println(base.count);// ? 看编译类型 10Sub sub = new Sub();System.out.println(sub.count);//? 20}}class Base {//父类int count = 10;//属性}class Sub extends Base {//子类int count = 20;//属性}
五:instanceOF比较操作符
:::danger 用于判断对象的运行类型是否为XX类型或XX类型的子类型 :::
public class PolyDetail03 {public static void main(String[] args) {BB bb = new BB();System.out.println(bb instanceof BB);// trueSystem.out.println(bb instanceof AA);// true//aa 编译类型 AA, 运行类型是 BB //BB 是AA子类AA aa = new BB();System.out.println(aa instanceofAA); //trueSystem.out.println(aa instanceofBB); //trueObject obj = new Object();System.out.println(obj instanceofAA);//falseString str = "hello";//System.out.println(str instanceof AA); //faseSystem.out.println(str instanceofObject);//true}}
六:Java动态绑定机制
- 当调用方法时,该方法会和该对象的内存地址/运行类型绑定
- 当调用对象的属性时,没有动态绑定机制,哪里调用哪里使用

public static void main(String[] args) {A a = new B()System.out.println(a.sum()); //40System.out.println(a.sum(1); //30}class A {public int i= 10;public int sum() {return getl()+ 10;}public int sum1(){returni+ 10;}public int getl() {return i;}}class B extends A { // 子类public int i = 20;/*public int sum(){return i+ 20;}*/public int getl() {return i;}public int sum10 {returni+ 10;}}
