# 概念
在 java 中,多态的含义是:一种定义,多种实现,
多态是同一个行为具有多个不同表现形式或形态的能力。就比如:
多态就是同一个接口,使用不同的实例而执行不同操作
多态性是对象多种表现形式的体现。
# 多态的优缺点
消除类型之间的耦合关系
可替换性
可扩充性
接口性
灵活性
简化性
# 多态的定义和使用
存在必备的三个条件:
- 继承
- 重写
- 父类引用指向子类对象 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 |
# 多态转型
分为向上和向下转型,查看:详情