Java OOP三大特征之封裝繼承與多態(tài)詳解
OOP語言的三大特征即:面向?qū)ο蟮娜齻€比較重要的思想
封裝
官話:將數(shù)據(jù)和操作數(shù)據(jù)的方法進行有機結(jié)合,隱藏對象的屬性和實現(xiàn)細節(jié),僅對外公開接口進行交互
通俗講,不讓類外看到實現(xiàn)的細節(jié),通過技術(shù)手段對這些細節(jié)包裝一個外殼,同時提供幾個公開的接口,讓你進行交互即可(例如:手機,內(nèi)部的具體零件,不會讓你觀察到,使用者只能看到外殼,通過外殼的顯示屏,充電口進行交互)簡而言之——套殼屏蔽細節(jié)
實際上通過private來實現(xiàn)
例如:

繼承
面向?qū)ο蟮乃枷胫刑岢隽死^承的概念,專門用來進行共性抽取,實現(xiàn)代碼復用。
通俗來講,就是將兩個或多個類(“子類”或者叫“派生類”)的共同的特點抽取出來,放在一個類(“父類”或叫“基類”或叫“超類”)里面,對具有共同特點的代碼實現(xiàn)重復利用,大大的減少了代碼量。
例如:人與人之間具有相同的屬性(都有名字,年齡...),但同時也有不一樣的地方(每個人具體的特點,有人會彈鋼琴...)



父與子的繼承順序:
故名思意,肯定是先有父后有子,所以在子類構(gòu)造對象時,他們的初始化順序是先完成父類的初始化,再調(diào)用子類的構(gòu)造方法,{ super()將父類初始化好的內(nèi)存地址傳入 },最后完成子類初始化。
super關(guān)鍵字:
1.super.data訪問父類中的屬性
2.super.func() 訪問父類的方法
3.super() 訪問父類的構(gòu)造方法
注意:
this()用來調(diào)用本類的構(gòu)造方法,super()用于調(diào)用父類的構(gòu)造方法,這兩不能同時出現(xiàn)!
父類與子類同名時,在子類調(diào)用同名變量時采用就近原則(調(diào)用子類)
當你未給子類提供構(gòu)造方法時(或者是父類有不帶參數(shù)的構(gòu)造方法,子類也有構(gòu)造方法,會自動給子類補上super),編譯器會自動補上一個不帶參數(shù)的構(gòu)造方法(前提是,父類的構(gòu)造方法中不帶參數(shù),因為編譯器只會自動不上不帶參數(shù)的構(gòu)造方法),如下:
class A{
A(){
System.out.println("A");
}
}
class B extends A{
B(){
super();//如果程序原沒寫構(gòu)造方法,編譯器會自己提供一個這樣的不帶參數(shù)的構(gòu)造方法
}
}
public class Test{
public static void main(String[] args){
new B();
}
}class A{
A(){
System.out.print("A");
}
}
class B extends A{
B(){ //程序會自動補上super,最終打印AB
System.out.print("B");
}
}
public class Test{
public static void main(String[] args){
new B();
}
}class A{
A(int a){
System.out.println("A");
}
}
class B extends A{
//若父類構(gòu)造方法帶參數(shù),子類不會自動補構(gòu)造方法
//程序編譯失敗
}
public class Test{
public static void main(String[] args){
new B();
}
}經(jīng)典筆試題:以下代碼會打印什么?(初始化順序是什么?)
class Character{
public int data1;
public int data2;
static{
System.out.println("父類的靜態(tài)內(nèi)部類初始化完成!");
}
{
System.out.println("父類的實例內(nèi)部類初始化完成!");
}
public Character(){
System.out.println("父類的構(gòu)造方法初始化完成!");
}
}
class Art extends Character{
public int data3;
public int data4;
static{
System.out.println("子類的靜態(tài)內(nèi)部類初始化完成!");
}
{
System.out.println("子類的實例內(nèi)部類初始化完成!");
}
public Art(){
super();
System.out.println("子類的構(gòu)造方法初始化完成!");
}
}
public class Test{
public static void main(String[] args){
Art art = new Art();
}
}運行結(jié)果:

分析:

多態(tài)
通俗來講就是:不同人的通過同一種工具可以做出不同的事情
例如:一個音樂生和一個美術(shù)生看到一架鋼琴的反應是不同的,音樂生可能會上去彈鋼琴,而美術(shù)生則可能將他畫下來...
實現(xiàn)多態(tài)的條件:
- 在父子的繼承關(guān)系下;
- 子對父進行重寫;
- 用一個方法調(diào)用父類被重寫的方法;
代碼如下:
//人類
class Human{
private String name;
Human(String name){
setName(name);
}
public void action(){
System.out.println(name + "看到一架鋼琴~");
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
//美術(shù)生
class Art extends Human{
Art(String name){
super(name);
}
public void action(){
System.out.println(getName() + "開始繪畫鋼琴~");
}
}
//音樂生
class Music extends Human{
Music(String name){
super(name);
}
public void action(){
System.out.println(getName() + "開始彈鋼琴~");
}
}
public class Test{
public static void function(Human human){
human.action();
}
public static void main(String[] args){
Human human1 = new Art("美術(shù)生");
Human human2 = new Music("音樂生");
function(human1);
function(human2);
}
}分析:

發(fā)生重寫的條件:
- 方法名相同;
- 返回類型相同;
- 形參類列表相同(個數(shù)、順序、類型都要一致?。?/li>
- static 和 private 修飾的方法不能重寫;
- 子類訪問修飾符必須大于等于父類訪問修飾符(后面會出文章專門討論);
此時會發(fā)生動態(tài)綁定(運行時綁定),其實此過程編譯的時候還是調(diào)用父類的,但運行時發(fā)生動態(tài)綁定,運行子類的;也就是說,父類引用了子類的對象,調(diào)用了這個重寫的方法,如下圖:


拓展:
向下轉(zhuǎn)型,也有,也就是子類當父類用也可,但是比較危險,如下代碼:
public class Test{
public static void function(Human human){
human.action();
}
public static void main(String[] args){
Human human = new Human("音樂生");
Music music = (Music)human;
}
}運行結(jié)果:

可以這樣理解,不是所有人都是音樂生,所以需要如下改法:(有的人是音樂生)
public class Test{
public static void function(Human human){
human.action();
}
public static void main(String[] args){
Human human = new Music("音樂生");//這樣寫便是有些人是音樂生
if(human instanceof Music) {//保證安全性,向下轉(zhuǎn)型
Music music = (Music) human;
};
}
}到此這篇關(guān)于Java OOP三大特征之封裝繼承與多態(tài)詳解的文章就介紹到這了,更多相關(guān)Java 封裝 繼承 多態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java虛擬機內(nèi)存結(jié)構(gòu)及編碼實戰(zhàn)分享
這篇文章主要介紹了Java虛擬機內(nèi)存結(jié)構(gòu)及編碼實戰(zhàn)分享,文章圍繞詳細主題展開相關(guān)資料具有一定的參考價值,需要的小伙伴可以參考一下2022-04-04
java并發(fā)數(shù)據(jù)包Exchanger線程間的數(shù)據(jù)交換器
這篇文章主要為大家介紹了java并發(fā)數(shù)據(jù)包使用數(shù)據(jù)交換器Exchanger來進行線程之間的數(shù)據(jù)交換。有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03
詳解Java并發(fā)編程中的優(yōu)先級隊列PriorityBlockingQueue
PriorityBlockingQueue是Java中實現(xiàn)了堆數(shù)據(jù)結(jié)構(gòu)的線程安全的有界阻塞隊列。本文將會深入解讀PriorityBlockingQueue的源碼實現(xiàn),感興趣的可以了解一下2023-05-05
Java LinkedHashMap 底層實現(xiàn)原理分析
LinkedHashMap繼承自HashMap實現(xiàn)了Map接口。基本實現(xiàn)同HashMap一樣,不同之處在于LinkedHashMap保證了迭代的有序性。其內(nèi)部維護了一個雙向鏈表,解決了 HashMap不能隨時保持遍歷順序和插入順序一致的問題。2021-05-05

