# 概念

在 java 中,多态的含义是:一种定义,多种实现,

多态是同一个行为具有多个不同表现形式或形态的能力。就比如:

同是打印的行为,但是结果不一样

多态就是同一个接口,使用不同的实例而执行不同操作

多态性是对象多种表现形式的体现。


# 多态的优缺点

  1. 消除类型之间的耦合关系

  2. 可替换性

  3. 可扩充性

  4. 接口性

  5. 灵活性

  6. 简化性


# 多态的定义和使用

存在必备的三个条件:

  • 继承
  • 重写
  • 父类引用指向子类对象 Patent p = new Child ();
说明
  • 普通类多态定义格式:父类 变量名 = new 子类();
class Patent {}    // 创建父类
class Child extends Patent {}    // 创建子类
Patent p = new Child();    // 类的多态使用
  • 抽象类定义多态格式: 抽象名 变量名 = new 抽象子类();
// 创建抽象父类
abstract class Patent{
    public abstract void fun();
}
// 创建子类重写父类抽象方法
class Child extends Patent{
    public void fun(){
        System.out.println("重写父类抽象方法");
    }
}
// 抽象类的多态使用
Patent p = new Child();
  • 接口多态定义的格式:接口 变量名 = new 接口实现类();
// 创建接口
interface Patent{
    public abstract void fun();
}
// 创建实现类
class Child implements Patent{
    public void fun(){
        System.out.println("重写接口抽象方法");
    }
}
// 接口的多态使用

在使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去检查子类是与否有同名方法,如果有则使用子类的

伪代码
使用多态调用方法
    if(父类是否有调用的方法){
        if(子类是否有被调用的方法){
            使用子类的方法
        }else{
            使用父类的
        }
    }else{
        报错
    }
// 成员方法编译时,参考引用变量所属的类(父类),如果类中没有调用的方法,编译失败
// 成员方法运行时,参考引用变量所指的对象所属的类(子类),并运行对象所属类中的方法
// 即:编译看父类,运行看子类

调用属性时:使用的都是父类的属性

  • 变量在编译时,参考的是引用类型所属的类(父类)中是否有被调用的变量。没有则编译失败。
  • 变量在运行时,参考的也是引用类型所属的类(父类)中是否有被调用的变量。没有则运行失败。

即:编译和运行都是看的父类


代码实例
// 创建父类
class Patent {
    public String str="HAHAHAHA"; // 定义变量
    public void sayHi(){// 定义方法
        System.out.println("Hi~");
    }
}
// 创建子类
class Child extends Patent {
    public String str="Noooooooo~";
    public void sayHi(){
        System.out.println("No Hi");
    }
}    
public class Run{
    public static void main(String[] args){
        Patent p = new Child();
        System.out.print(p.str);
        p.sayHi();
    }
}
// 运行的结果:
// HAHAHAHA
// No Hi

# 虚函数

虚函数的存在是为了多态。

Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是 Java 的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。


# 重写

重写
class Patent{
    public void sayHi(){
        System.out.println("Hi~");
    }
}
class Child extend Patent{
    // 这就是子类重写父类的方法
    // 当子类的实现的要求父类满足不了的时候,
    // 就可以通过重写来制定新的实现
    public void sayHi(){
        System.out.println("Hiiiiiiii~");
        // 如果想调用父类中被重写的方法,就必须使用关键字 super
        super.sayHi();
    } 
}
// 控制台输出:
// Hiiiiiiii~
// HI~

# instanceof 关键字

  • 作用:instanceof 关键字用来判断某个对象是否属于某种数据类型
  • 格式:boolean b = 对象 instanceof 数据类型;
判断
// 两个子类,使用两次多态调用
Patent a1 = new Child1();
Patent a2 = new Child2();
boolean flag = a1 instanceof Child1;    //flag 结果为 true
boolean flag2 = a2 instanceof Child1;    //flag2 结果为 false

# 多态转型

分为向上和向下转型,查看:详情