Java輕松掌握面向對象的三大特性封裝與繼承和多態(tài)
1.封裝
1.介紹
封裝是指把抽象出的屬性和方法封裝在一起,數據被保護在內部,程序的其他部分只能通過被授權的方法,才能對數據操作。
2.封裝的理解和好處
- 隱藏實現(xiàn)的細節(jié)
- 可以對數據驗證,保證安全合理
3.封裝的實現(xiàn)步驟
- 將屬性私有化(private)
- 提供一個公共的set方法,用于對屬性判斷并賦值
- 提供一個公共的get方法,用于獲取屬性的值
public class Student {
private Double score;
public void setScore(Double score) {
//還可以在這里進行屬性的判斷
this.score = score;
}
public Double getScore() {
return score;
}
2.繼承
1.介紹
繼承可以解決代碼的復用,當多個類具有相同的屬性和方法時,我們可以從中抽象出父類,然后再父類中定義這些相同的屬性和方法,這樣所有的子類就不需要再定義這些相同的屬性和方法,只需要使用extends關鍵字來繼承父類即可。
2.繼承的基本語法
public class Graduate extends Student{
}
- 子類會自動擁有父類定義的屬性和方法
- 父類又叫基類,超類
- 子類又稱派生類
3.繼承的使用細節(jié)
子類繼承了父類所有的屬性和方法,但是私有屬性和方法不能在子類直接訪問,要通過公共的方法去訪問。
package com.wang.extend;
public class Student {//父類
public int age;
public String name;
private Double score;
String hobby;
public Double getScore() {
return score;
}
package com.wang.extend;
public class Graduate extends Student {//子類
public void test() {
//子類不能直接訪問private屬性,要調用公共方法得到
System.out.println("大學生" + name + age + hobby + getScore());
}
}
子類必須調用父類構造器,完成父類的初始化,當創(chuàng)建子類對象時,不管使用子類的哪一個構造器,默認會先去調用父類的無參構造器,若父類沒有無參構造器,則必須在子類構造器中使用super()指定使用父類的哪個構造器完成父類初始化,否則編譯失敗。
package com.wang.extend;
public class Student {//父類
public int age;
public String name;
//public Student() {
//}
public Student(int age, String name) {
this.age = age;
this.name = name;
}package com.wang.extend;
public class Graduate extends Student {
public Graduate() {
// super();//默認會有一個調用父類無參構造的方法super()
//若父類沒有無參構造器,必須用super()指定使用哪個構造器
super(20,"小明");
}
}
super()在使用時,需要放在第一行。
super()和this()都只能放在構造器第一行,因此這兩個方法不能同時存在于同一個構造器。
Java所有的類都是Object的子類。查看類的層級Ctrl+H。

父類構造器的調用不限于直接父類!將一直向上追溯到Object類(頂級父類)。
子類最多繼承一個父類,java的單繼承機制。
不能濫用繼承,子類和父類要符合包含關系。比如,大學生包含在學生當中,這是學生就可以是父類,大學生為子類。
3.super關鍵字
1.基本介紹
super代表的是父類的引用,用于訪問父類的屬性,方法,構造器
2.基本語法
1.訪問父類的屬性/方法,但不能訪問父類的private屬性/方法
super.屬性名; super.方法名(形參列表);
2.訪問父類的構造器
super(形參列表);//只能放在構造器的第一句
3.細節(jié)與好處
1.父類屬性由父類初始化,子類的屬性子類初始化,分工明確。
2.當子類與父類的成員重名時,若要訪問父類的成員,必須通過super。
3.super的訪問不限于直接父類,當多個基類都有同名的成員,使用super訪問時遵循就近原則。
4.super與this的比較
| 區(qū)別點 | this | super |
|---|---|---|
| 訪問屬性 | 先訪問本類的屬性,若本類沒有再去父類 | 只訪問父類的屬性 |
| 調用方法 | 先訪問本類的方法,若本類沒有再去父類 | 直接訪問父類的方法 |
| 調用構造器 | 調用本類的構造器,必須放第一句 | 調用父類的構造器,必須放第一句 |
| 特殊 | 表示當前對象 | 表示子類訪問父類對象 |
4.方法重寫
1.基本介紹
子類的一個方法與父類的名稱,返回類型,形參列表都一樣,稱子類是父類方法的重寫。
2.注意事項與使用細節(jié)
1.子類方法的返回類型與父類方法的返回類型相同或者父類返回類型的子類。
//正確示例 public Object a() //父類返回類型為Object public String a() //子類返回類型為String或者Object //Object是String的父類
2.子類方法不能縮小父類方法的訪問權限。
//接下來是錯誤示例 void display() //這是子類 子類訪問權限為 默認的 public void display() //這是父類 父類訪問權限為public //public->默認的 訪問權限變小所以報錯
3.重載與重寫的比較
| 名稱 | 發(fā)生范圍 | 方法名 | 形參列表 | 返回類型 | 修飾符 |
|---|---|---|---|---|---|
| 重載 | 本類 | 必須相同 | 參數類型,個數或者順序中至少有一個不同 | 無要求 | 無要求 |
| 重寫 | 父子類 | 必須相同 | 必須相同 | 子類的返回類型相同或者是父類的返回類型的子類 | 不能縮小父類的訪問范圍 |
3.多態(tài)
1.基本介紹
方法或對象具有多種形態(tài)。是面向對象的第三大特征,多態(tài)是建立在封裝和繼承基礎之上的。
2.具體體現(xiàn)
1.方法的多態(tài)
重寫和重載體現(xiàn)多態(tài)。
//重載
public int sum(int a,int b);
public int sum(int a,int b,int c);
//重寫
class A{
public void say(){ System.out.printf("A是父類~");}
}
class B extends A{
public void say() { System.out.printf("B是子類~");}
}
2.對象的多態(tài)(重點)
- 一個對象的編譯類型和運行類型可以不一致。
- 編譯類型在定義對象時,就確定了,不能改變,運行類型可以變化。
- 定義時 = 的左邊是編譯類型,右邊是運行類型。
Animal animal = new Dog();//Animal是編譯類型,Dog是運行類型 animal = new cat();//編譯類型不能改變,運行類型可變
3.多態(tài)注意事項和細節(jié)討論
1.多態(tài)的前提
兩個對象(類)存在繼承關系。
2.屬性
沒有重寫,屬性的值是看編譯類型。
public class Tes {
public static void main(String[] args) {
A a = new B();
System.out.println(a.n);
//這里輸出的是10,因為屬性的值要看編譯類型,a的編譯類型為A,所以輸出的是A的屬性
}
}
class A {
public int n = 10;
}
class B extends A {
public int n = 20;
}3.instance of
比較操作符,是用來判斷對象的運行類型是否為某類型或者某類型的子類型。
4.多態(tài)的向上轉型
- 本質:父類的引用指向了子類的對象。
- 語法:父類類型 引用名 = new 子類類型();
- 特點:可以調用父類中的所有成員(遵守訪問權限),不能調用子類的特有成員,但最終的運行結果看運行類型的具體實現(xiàn),能調用那些成員看編譯類型,具體運行看運行類型。
5.多態(tài)的向下轉型
- 語法:子類類型 引用名 = (子類類型) 父類引用;
- 只能強轉父類的引用,不能強轉父類的對象。
- 要求父類的引用必須指向的是當前目標類型的對象。
- 可以調用子類類型中的所有成員。
public class Test {
public static void main(String[] args) {
//向上轉型
A a = new B();
a.say();
//a.abc(); 方法abc為運行類型B類特有的編譯類型A類不能調用
//調用那些成員看編譯類型,具體運行看運行類型
//向下轉型
B b = (B) a;
//父類的引用必須指向的是當前目標類型的對象
b.abc();
}
}
class A {
public void say (){
System.out.println("A類的say()被調用");
}
}
class B extends A {
public void abc(){
System.out.println("B類的abc()被調用");
}
public void say (){
System.out.println("B類的say()被調用");
}
}運行結果如下:

6.Java動態(tài)綁定機制
當調用對象的方法時,該方法會與該對象的內存地址/運行類型綁定。
當調用對象的屬性時,不存在動態(tài)綁定機制。
public class Test {
public static void main(String[] args) {
A a = new B();//A為編譯類型,B為運行類型
System.out.println(a.sum());
//B類中sum()沒注釋前 結果為 40 注釋后結果為 30
//注釋后會調用A類的sum方法但因為動態(tài)綁定機制sum中的getI方法調用的是B中的
System.out.println(a.sum1());
//B類中sum()沒注釋前 結果為 30 注釋后結果為 20
//調用A類的sum1,i由于是調用對象的屬性,不存在動態(tài)綁定機制,哪里聲明就調用哪的i=10
}
}
public class A {
public int i = 10;
public int sum() {
return getI() + 10;
}
public int sum1() {
return i + 10;
}
public int getI() {
return i;
}
}
public class B extends A {
public int i = 20;
// public int sum() {
// return i + 20;
// }
// public int sum1() {
// return i + 10;
// }
public int getI() {
return i;
}
}7.多態(tài)數組多態(tài)參數
多態(tài)數組
數組的定義類型為父類類型,里面保存的實際元素類型為子類類型和父類類型。
多態(tài)參數
方法定義的形參類型為父類類型,實際類型允許為子類類型。
示例:父類為Employee,子類為Worker和Manage
public class Test {
public static void main(String[] args) {
Test test = new Test();
Employee employee = new Employee("Bob",3000);
Employee[] employee1 = new Employee[5];//多態(tài)數組 父類定義
Worker worker = new Worker("Tom",5000);
Worker worker1 = new Worker("Kit",6000);
Manager manager = new Manager("Smith",12000,100000);
Manager manager1 = new Manager("Sab",15000,110000);
employee1[0]=worker;//可放子類
employee1[1]=worker1;
employee1[2]=manager;
employee1[3]=manager1;
employee1[4]=employee;//也可放本類
test.showEmpAnnal(worker);//多態(tài)參數 實參可為子類
test.showEmpAnnal(manager);
test.testwork(employee1);
}
public void showEmpAnnal(Employee e){//多態(tài)參數 形參為父類
System.out.println(e.getName()+" 的年薪為:"+e.getAnnual());
}
public void testwork(Employee e[]){
for (int i = 0; i <5 ; i++) {
if(e[i] instanceof Worker){
((Worker) e[i]).work();//向下轉型
}else if(e[i] instanceof Manager){
((Manager) e[i]).manage();
}else {
System.out.println("員工 "+e[i].getName()+" 正在摸魚!");
}
}
}
}
到此這篇關于Java輕松掌握面向對象的三大特性封裝與繼承和多態(tài)的文章就介紹到這了,更多相關Java封裝 繼承 多態(tài)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot 如何實現(xiàn)自定義Redis序列化
這篇文章主要介紹了SpringBoot 如何實現(xiàn)自定義Redis序列化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
基于Java快速實現(xiàn)一個簡單版的HashMap詳解
這篇文章主要為大家詳細介紹了如何利用Java簡單實現(xiàn)一個底層數據結構為數組?+?鏈表的HashMap,不考慮鏈表長度超過8個時變?yōu)榧t黑樹的情況,需要的可以參考一下2023-02-02
java文件刪除不了File類的delete方法刪不掉文件的原因以及分析
這篇文章主要介紹了java文件刪除不了File類的delete方法刪不掉文件的原因以及分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06

