深入解析Java多態(tài)進(jìn)階學(xué)習(xí)
1.動態(tài)綁定機(jī)制
java的動態(tài)綁定機(jī)制非常重要
實(shí)例A
我們來看一個實(shí)例:

閱讀上面的代碼,請說明下面的程序?qū)⑤敵鍪裁唇Y(jié)果:

程序?qū)敵?0和30,這個實(shí)例很簡單,直接看運(yùn)行類型即可,該代碼的運(yùn)行類型為B,所以會調(diào)用B類的方法
實(shí)例B
我們將上面的代碼變通一下,將子類中的如下代碼塊注銷:

隨后繼承機(jī)制會訪問父類的sum方法:

那么這里有一個問題,此處的getI(),會執(zhí)行子類的還是父類的呢?
當(dāng)調(diào)用對象方法的時候,該方法會和該對象的內(nèi)存地址/運(yùn)行類型綁定
代碼的運(yùn)行類型依然是B,所以此處會執(zhí)行子類的getI()方法,結(jié)果輸出為30
實(shí)例C
現(xiàn)在我們再變通以下上面的代碼
再將子類中如下的代碼塊注銷:

繼承機(jī)制會執(zhí)行父類的sum1方法:

那么這里有一個問題,此處的i,會使用子類的還是父類的呢?
屬性沒有動態(tài)綁定機(jī)制,哪里聲明,哪里使用(使用當(dāng)前類的)
此處的i在父類進(jìn)行聲明,所以會選用父類的i屬性,結(jié)果為20
2.多態(tài)數(shù)組
定義:
數(shù)組的定義類型為父類類型,但是保存的實(shí)際元素類型為子類類型
Person父類:
/**
* 多態(tài)數(shù)組父類
*/
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String say() {
return name + '\t' + age;
}
}
Student子類:
/**
* 多態(tài)數(shù)組學(xué)生子類
*/
public class Student extends Person{
private double score;
public Student(String name, int age, double score) {
super(name, age);
this.score = score;
}
// 重寫父類的say方法
public String say() {
return super.say() + '\t' + score;
}
}
Teacher子類:
/**
* 多態(tài)數(shù)組教師子類
*/
public class Teacher extends Person {
private double sal;
public Teacher(String name, int age, double sal) {
super(name, age);
this.sal = sal;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public String say() {
return super.say() + '\t' + sal;
}
}
測試多態(tài)數(shù)組的使用:
public class Test {
public static void main(String[] args) {
// 多態(tài)數(shù)組的使用
Person[] persons = new Person[5];
persons[0] = new Person("dahe",20);
persons[1] = new Student("wangwei",11,100);
persons[2] = new Student("zhangsan",12,60);
persons[3] = new Teacher("wang",33,15000);
persons[4] = new Teacher("li",55,25000);
// 循環(huán)遍歷多態(tài)數(shù)組,調(diào)用say方法
for (int i = 0; i < persons.length; i++) {
String out = persons[i].say(); // 動態(tài)綁定機(jī)制,編譯類型永遠(yuǎn)都是Person
// 運(yùn)行類型是根據(jù)實(shí)際情況由JVM機(jī)決定
System.out.println(out);
}
}
}
輸出:
dahe 20
wangwei 11 100.0
zhangsan 12 60.0
wang 33 15000.0
li 55 25000.0
3.多態(tài)數(shù)組的高階用法
現(xiàn)在,教師子類新增了教學(xué)方法:
public void teach() {
System.out.println("老師:" + getName() + "正在講課!");
}
學(xué)生子類新增了學(xué)習(xí)方法:
public void study() {
System.out.println("學(xué)生:" + getName() + "正在學(xué)習(xí)!");
}
那么,有沒有辦法通過多態(tài)數(shù)組來訪問他們子類對應(yīng)的獨(dú)有的方法呢?事實(shí)上,可以通過巧妙使用instanceof來解決:
變通一下,改變多態(tài)數(shù)組的循環(huán)操作:
// 循環(huán)遍歷多態(tài)數(shù)組,調(diào)用say方法
for (int i = 0; i < persons.length; i++) {
String out = persons[i].say(); // 動態(tài)綁定機(jī)制,編譯類型永遠(yuǎn)都是Person
// 運(yùn)行類型是根據(jù)實(shí)際情況由JVM機(jī)決定
System.out.println(out);
if (persons[i] instanceof Student) {
// 向下轉(zhuǎn)型
Student student = (Student) persons[i];
student.study();
} else if (persons[i] instanceof Teacher) {
Teacher teacher = (Teacher) persons[i];
teacher.teach();
}
}
輸出:
dahe 20
wangwei 11 100.0
學(xué)生:wangwei正在學(xué)習(xí)!
zhangsan 12 60.0
學(xué)生:zhangsan正在學(xué)習(xí)!
wang 33 15000.0
老師:wang正在講課!
li 55 25000.0
老師:li正在講課!
大功告成!多態(tài)數(shù)組即強(qiáng)大又完美!
4.多態(tài)參數(shù)
方法定義的形參類型為父類類型,實(shí)參類型允許為子類類型
接下來我們來演示以下多態(tài)參數(shù)的使用:
父類:
/**
* 多態(tài)參數(shù) - 父類
*/
public class Employee {
private String name;
private double sal;
public Employee(String name, double sal) {
this.name = name;
this.sal = sal;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
// 得到年工資的方法
public double getAnnual() {
return 12 * sal;
}
}
員工子類:
/**
* 多態(tài)參數(shù) - 子類員工
*/
public class Worker extends Employee{
public Worker(String name, double sal) {
super(name, sal);
}
public void work() {
System.out.println("普通員工:" + getName() + "正在工作!");
}
public double getAnnual() {
return super.getAnnual();
}
}
經(jīng)理子類:
/**
* 多態(tài)參數(shù) - 經(jīng)理子類
*/
public class Manager extends Employee{
private double bonus; // 獎金
public Manager(String name, double sal, double bonus) {
super(name, sal);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public void manage() {
System.out.println("經(jīng)理:" + getName() + "正在管理!");
}
@Override
public double getAnnual() {
return super.getAnnual() + bonus;
}
}
我們來測試一下,求不同崗位的雇員的年薪:
/**
* 多態(tài)參數(shù)測試類
*/
public class Test {
public static void main(String[] args) {
Worker zhang = new Worker("張工",1000);
Manager milan = new Manager("milan", 5000, 2000);
Test test = new Test();
test.showEmpAnnual(zhang);
test.showEmpAnnual(milan);
}
// 獲取員工的年薪,采用多態(tài)參數(shù)
public void showEmpAnnual(Employee e) {
System.out.println(e.getAnnual());
}
}
輸出:
12000.0
62000.0
5.多態(tài)參數(shù)的高階用法
我們來對上面的多態(tài)參數(shù)代碼做一個完善,如果傳入的是員工,則調(diào)用自己的work方法,如果傳入的是經(jīng)理,則調(diào)用自己的manage方法
增加一個下面的方法:
public void testWork(Employee e) {
if (e instanceof Worker) {
((Worker) e).work(); // 向下轉(zhuǎn)型
} else if (e instanceof Manager) {
((Manager) e).manage();
}
}
測試:
test.testWork(zhang); test.testWork(milan);
輸出:
普通員工:張工正在工作!
經(jīng)理:milan正在管理!
到此這篇關(guān)于深入解析Java多態(tài)進(jìn)階學(xué)習(xí)的文章就介紹到這了,更多相關(guān)Java多態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)現(xiàn)微信企業(yè)付款到個人功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信企業(yè)付款到個人功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09
SpringBoot?Knife4j框架&Knife4j的顯示內(nèi)容的配置方式
Knife4j框架是基于Swagger2開發(fā)的在線API文檔生成工具,主要功能包括自動生成API文檔、接口文檔展示、接口測試工具、接口權(quán)限控制和在線調(diào)試,該框架支持通過注解自動生成詳細(xì)的接口文檔,開發(fā)者可以直接在文檔界面進(jìn)行接口測試和調(diào)試2024-09-09
Java中數(shù)組和String相互轉(zhuǎn)換的幾種常見方法
這篇文章主要介紹了Java中數(shù)組和String相互轉(zhuǎn)換的幾種常見方法,每種類型都有相應(yīng)的轉(zhuǎn)換方法,如使用String類的構(gòu)造函數(shù)、toCharArray()、String.join()、Arrays.toString()、StringBuilder等,這些方法能幫助開發(fā)者高效地進(jìn)行數(shù)據(jù)類型之間的轉(zhuǎn)換,需要的朋友可以參考下2025-04-04
Spring Boot Starter 的應(yīng)用場景與自動配置方式
本文介紹了Spring Boot Starter的使用場景,如何自定義Starter以及Spring Boot自動配置原理,Spring Boot Starter解決了依賴導(dǎo)入和配置繁瑣的問題,通過自動配置類和xxxProperties類實(shí)現(xiàn)組件的自動注入和配置,感興趣的朋友一起看看吧2025-03-03
SpringBoot定時任務(wù)實(shí)現(xiàn)數(shù)據(jù)同步的方法
業(yè)務(wù)需求是,通過中臺調(diào)用api接口獲得,設(shè)備數(shù)據(jù),要求現(xiàn)實(shí)設(shè)備數(shù)據(jù)的同步,這篇文章主要介紹了SpringBoot定時任務(wù)實(shí)現(xiàn)數(shù)據(jù)同步的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08
基于SpringBoot?使用?Flink?收發(fā)Kafka消息的示例詳解
這篇文章主要介紹了基于SpringBoot?使用?Flink?收發(fā)Kafka消息,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01

