Java——多态
一、什么是多态
事物的多种展现形式。
二、多态的好处
提高程序中代码的复用性、扩展性
三、多态的前提
- 有继承关系、实现关系
- 子类重写父类/父接口中的方法
四、多态的书写格式
父类/父接口 父引用 = new 子类(); // 父引用指向子类对象 JavaStudent javaStu = new JavaStudent(); // 使用事物的本身类型来定义 Student javaStu = new JavaStudent(); // 使用事务的父类型来定义
五、静态多态
- 也称为编译期多态
- 概念就是同一个对象的不同行为体现
- 代码体现为方法的重载
举例
同一个对象进行登录,可以有不同的登录方式,(用户名/密码、手机验证码、人脸识别);
举例代码如下
// Student.java
public class JavaStudent extends Student{
@Override
public boolean login(String name, String pwd) {
if(name.equals("张三") && pwd.equals("123456")){
return true;
}else{
return false;
}
}
@Override
public boolean login(int phoneCode) {
if(phoneCode == 1234){
return true;
}else{
return false;
}
}
@Override
public boolean login(String face) {
if(face.equals("张三的人脸信息")){
return true;
}else{
return false;
}
}
}
// ExamSys.java
public class ExamSys {
public static void main(String[] args) {
init();
}
public static void init(){
System.out.println("*******************黑马考试系统***********************");
System.out.println("请选择学科 1、Java 2、UI");
int num = new Scanner(System.in).nextInt();
switch(num){
case 1:
JavaStudent javaStu = new JavaStudent();
if(selectLogin(javaStu)){
System.out.println("登录成功");
}
break;
case 2:
UIStudent uiStu = new UIStudent();
if(selectLogin(uiStu)){
System.out.println("登录成功");
}
break;
default:
System.out.println("选择错误,退出系统");
System.exit(0);
break;
}
}
public static boolean selectLogin(Student stu){
System.out.println("*************************************************");
System.out.println("请选择登录方式:");
System.out.println("1、用户名密码登录");
System.out.println("2、手机验证码登录");
System.out.println("3、人脸识别登录");
System.out.println("*************************************************");
int num = new Scanner(System.in).nextInt();
boolean result = false;
switch(num){
case 1:
result = stu.login("用户名", "密码");
break;
case 2:
result = stu.login(123);
break;
case 3:
result = stu.login("人脸信息");
break;
}
return result;
}
}
上述学生类登录功能分别有三种:用户名密码登录、手机验证码登录、人脸识别登录,就是静态多态。
六、动态多态
- 也称为运行期多态
- 不同对象的相同行为体现
- 代码的体现为方法的重写
- 有继承关系、实现关系
- 子类重写父类/父接口中的方法
举例
不同对象进行考试,对象都有考试功能(Java学生 =》考试 UI学生=》考试);
举例代码如下
// ExamSys.java
public class ExamSys {
public static void main(String[] args) {
init();
}
public static void init(){
System.out.println("*******************黑马考试系统***********************");
System.out.println("请选择学科 1、Java 2、UI");
int num = new Scanner(System.in).nextInt();
switch(num){
case 1:
JavaStudent javaStu = new JavaStudent();
if(selectLogin(javaStu)){
System.out.println("登录成功");
}
break;
case 2:
UIStudent uiStu = new UIStudent();
if(selectLogin(uiStu)){
System.out.println("登录成功");
}
break;
default:
System.out.println("选择错误,退出系统");
System.exit(0);
break;
}
}
public static boolean selectLogin(Student stu){
System.out.println("*************************************************");
System.out.println("请选择登录方式:");
System.out.println("1、用户名密码登录");
System.out.println("2、手机验证码登录");
System.out.println("3、人脸识别登录");
System.out.println("*************************************************");
int num = new Scanner(System.in).nextInt();
boolean result = false;
switch(num){
case 1:
result = stu.login("用户名", "密码");
break;
case 2:
result = stu.login(123);
break;
case 3:
result = stu.login("人脸信息");
break;
}
return result;
}
}
上述代码 selectLogin 方法接收参数类型为Student类型,然后调用的时候传的是 JavaStudent javaStu = new JavaStudent()和UIStudent uiStu = new UIStudent()都可以成功。
动态多态在开发中的应用场景有如下2种
- 方法中参数多态
- 方法返回值多态
上述代码就是方法中参数多态,下面代码就是返回值多态
public Student createStudnet(int flag, String name, int age){
if(flag == 1){
return new JavaStudent(name, age);
}else{
return new UIStudent(name, age);
}
}
七、多态中方法的执行特点
- 成员变量不参与多态 ,只有成员方法才有多态现象
- 多态的格式调用方法,指的是父类/父接口型调用方法,就是多所调用的方法必须在父类型/父接口中有存在,执行的时候,会执行子类重写的方法,如果子类没有重写方法,会向父类/接口找到方法执行
- 使用多态调用方法,不能调用子类特有的方法(多态的弊端)
八、多态的类型转换
有2种,就是向上转型和向下转型。
8.1、向上转型
在书写多态代码时,就已经实现向上转型
Student stu = new JavaStudent(); // JavaStudent类型转换为Student类型(类型提升)
注意,stu引用的是子类对象,虽然类型向上转型了,但底层实际还是子类。
8.2、向下转型
向下转型首先要了解动态多态的弊端,就是上面说的父引用无法调用子类特有的方法,这里使用多态的向下转型就可以解决这个问题。
向下转型的书写格式如下
子类 子类对象 = (子类) 父引用;
// 多态体现:向上转型
Student stu = new JavaStudent();
stu.project(""); // 父类对象无法调用子类特有方法
// 访问JavaStuent类中的特有方法
JavaStudent javaStu = (JavaStudent) stu; // 向下转型,把父类型转换为子类类型
javaStu.project("考试系统");
九、instanceof
使用instanceof关键字可以避免ClassCastException异常
书写格式
if(对象名 instanceof 数据类型){
// instanceof关键字的作用:判断指定的对象是否为某种类型
// 如果是返回true,不是返回false
}
举例代码如下
// 开始考试
public static void startExam(Student stu){
String str = "";
if(stu instanceof JavaStudent){ // 检查stu对象底层是否为JavaStudent类型
str = "Java";
}else if(stu instanceof UIStudent){
str = "UI";
}
System.out.println("************************" + str + "考试题**************************");
stu.exam();
}

浙公网安备 33010602011771号