Java——多态

一、什么是多态

事物的多种展现形式。

二、多态的好处

提高程序中代码的复用性、扩展性

三、多态的前提

  1. 有继承关系、实现关系
  2. 子类重写父类/父接口中的方法

四、多态的书写格式

父类/父接口 父引用 = 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种

  1. 方法中参数多态
  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();
}

  

原文地址:https://www.cnblogs.com/xulinjun/p/14749567.html