Java三大特性(封裝,繼承,多態)

来源:https://www.cnblogs.com/yuhailong/archive/2018/03/03/8497032.html
-Advertisement-
Play Games

Java中有三大特性,分別是封裝繼承多態,其理念十分抽象,並且是層層深入式的. 一.封裝 概念:封裝,即隱藏對象的屬性和實現細節,僅對外公開介面,控制在程式中屬性的讀和修改的訪問級別;將抽象得到的數據和行為(或功能)相結合,形成一個有機的整體,也就是將數據與操作數據的源代碼進行有機的結合,形成“類” ...


Java中有三大特性,分別是封裝繼承多態,其理念十分抽象,並且是層層深入式的.

一.封裝

概念:封裝,即隱藏對象的屬性和實現細節,僅對外公開介面,控制在程式中屬性的讀和修改的訪問級別;將抽象得到的數據和行為(或功能)相結合,形成一個有機的整體,也就是將數據與操作數據的源代碼進行有機的結合,形成“類”,其中數據和函數都是類的成員。在電子方面,封裝是指把矽片上的電路管腳,用導線接引到外部接頭處,以便與其它器件連接。(來自百度)

在將成員屬性封裝之後,我們應該提供相應的get/set方法進行訪問此成員屬性.

封裝的好處是:屬性進行了隱藏,不再是暴露在外的數據,使數據更加的安全可靠.

 1 class A{
 2     private int a;//此變數進行了封裝
 3     //提供給外部訪問的介面,實現了只讀和只寫
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8         this.a=a;
 9     }
10 }

提到封裝就必須要提到private關鍵字,如上代碼,private是一個許可權修飾符,它可以將成員方法和成員屬性私有化,使其只有類內部能夠訪問到.

許可權修飾符有4種,分別是public->protected->default->private 其中private許可權最嚴格

public:可以在全工程訪問到      protected:只有這個類的子類可以訪問     defaule:為預設,無須寫出,類所在包下可以訪問     private:僅僅只有本省類可以訪問

 

提到了封裝就不得不提到this關鍵字

概念:this關鍵字指這個當前對象的引用

this關鍵字有三種用法:

  1.this.成員方法,這種方法用於給成員變數的賦值.

 1 class A{
 2     private int a;//此變數進行了封裝
 3     //提供給外部訪問的介面,實現了只讀和只寫
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8         this.a=a;
 9     }
10 }

  因為就近原則,所以直接a=a;實際上並沒有對成員屬性進行賦值,所以需要使用this關鍵字對其進行訪問.

  2.調用構造方法,如:可以在空參構造方法中調用有參構造方法

 1 class A{
 2     private int a;//此變數進行了封裝
 3     //提供給外部訪問的介面,實現了只讀和只寫
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8         this.a=a;
 9     }
10     //空參構造
11     public A(){
12         this(1);
13     }
14     //全參構造
15     public A(int a){
16         this.a=a;
17     }
18 }

  這個例子使用this在空參構造中調用了全參構造

  使用this調用構造方法時需要註意:

    1.this()必須在構造方法中的第一行,且只能夠使用一次

    2.this()不能夠互相調用,因為會陷入死迴圈,如下:

 1 class A{
 2     private int a;//此變數進行了封裝
 3     //提供給外部訪問的介面,實現了只讀和只寫
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8        this.a=a;
 9     }
10     //空參構造
11     public A(){
12         this(1);
13         //this();錯誤
14     }
15     //全參構造
16     public A(int a){
17         //this();錯誤
18         this.a=a;
19     }
20 }

  3.this可以當作返回值使用,this是當前對象的引用,所以返回的同樣是一個A類型,可以使用一個新的A類型對象b進行接受,b會繼承所有a的屬性值,使用方法如下:

class A{
    private int a;//此變數進行了封裝
    //提供給外部訪問的介面,實現了只讀和只寫
    public int getA(){
        return a;
    }
    public void setA(int a){
        this.a=a;
    }
    //使用this當作返回值
    A b(){
        return this;
    }
    //空參構造
    public A(){
        this(1);
    }
    //全參構造
    public A(int a){
        this.a=a;
    }
}

 

二.繼承

 概念:繼承即從已有的類中派生一個新的類,已有的類成為父類(基類,超類),而派生的類成為子類(派生類).若類B繼承了類A,則我們把類A稱為類B的子類,反之同理,子類可以擁有自己本身的特有方法以及特有屬性,而父類則必須是子類的共性抽取.如動物都有顏色,年齡,其顏色和年齡就是其共性

1 class A{
2     int a;
3     void a(){}
4 }
5 class B extends A{
6     //子類特有方法
7     void b(){
8     }
9 }

 

1. 繼承需要註意的點

  (1)繼承是類在繼承,而不是對象在繼承

  (2)子類無條件繼承父類的所有成員屬性及成員方法

  (3)若方法出現重寫,屬性出現重覆,則優先使用子類的方法和屬性(就近原則).

  (4)繼承不繼承父類的構造方法

2.java中繼承的特點

  (1).java不支持多繼承,但是可以通過介面實現多繼承        多繼承,即子類繼承自多個父類

  (2).java支持多重繼承        多重繼承,即子類繼承父類,父類繼承他的父類,即子類相當於其孫子輩

class A{
    int a;
    public A(){
        //super();這裡有一個預設的super()方法
    }
    public A(int a){
        //super();這裡有一個預設的super()方法
    }
    void a(){}
}
class B extends A{
    //子類的特有屬性
    int b;
    //子類特有方法
    void b(){
        //調用父類的成員屬性
        System.out.println(super.a);
        //調用父類的成員方法
        super.a();
    }
    public B(){
    //調用父類的有參構造
super(1); } }

 

提到繼承就必須提到super關鍵字,super關鍵字指父類的引用,super關鍵字最重要的是每個類的構造方法都有其預設的一個super()方法,我們知道所有的類都是繼承自Object類,而super()這個方法其實是調用到Object處進行空間的申請.

super關鍵字的使用

  1.訪問父類成員方法和成員屬性     super.成員方法()       super.成員屬性

  2.訪問父類的構造方法        super(參數)

 

 1 abstract class Animal{
 2     private String color;
 3     private int numOfLegs;
 4     abstract void eat();
 5     public String getColor() {
 6         return color;
 7     }
 8     public void setColor(String color) {
 9         this.color = color;
10     }
11     public int getNumOfLegs() {
12         return numOfLegs;
13     }
14     public void setNumOfLegs(int numOfLegs) {
15         this.numOfLegs = numOfLegs;
16     }
17     public Animal(String color, int numOfLegs) {
18         super();
19         this.color = color;
20         this.numOfLegs = numOfLegs;
21     }
22     public Animal() {
23         super();
24     }
25     
26 }
27 class Dog extends Animal{
28     Dog(){
29         super();
30     }
31     Dog(String color,int numOfLegs){
32         super(color,numOfLegs);
33     }
34     @Override
35     void eat(){
36         System.out.println(super.getNumOfLegs()+"條腿"+super.getColor()+"的狗在啃骨頭");
37     }
38     void lookHome(){
39         System.out.println(super.getNumOfLegs()+"條腿"+super.getColor()+"的狗在看家");
40     }
41 }
42 class Porrot extends Animal{
43     Porrot(){
44         super();
45     }
46     Porrot(String color,int numOfLegs){
47         super(color,numOfLegs);
48     }
49     @Override
50     void eat(){
51         System.out.println(super.getNumOfLegs()+"條腿的"+super.getColor()+"鸚鵡在吃小米");
52     }
53     void say(){
54         System.out.println(super.getNumOfLegs()+"條腿的"+super.getColor()+"鸚鵡在說你好,醜八怪");
55     }
56 }

提到繼承當然也不能不提到抽象類,定義一個抽象類使用是這樣的:public abstract class Animal(){}

當你想要創建一個動物類時,你知道動物都會吃,但是你不知道動物的子類吃是如何具體實現的,如:貓吃魚,但是狗吃的是骨頭同樣的子類,但是其方法的實現卻是不同的,這個時候就需要使用抽象類了.

抽象類的註意點:

  1.抽象類必須在類中使用abstract關鍵字進行修飾,

  2.抽象類中可以沒有抽象方法,

  3.抽象類不能夠實例化,如果想要實例化的話則需要子類將其所有的抽象方法重寫

 

 1 interface A{
 2     int b=0;//預設有public static final;
 3     void a(){}//預設有public abstract;
 4 }
 5 interface B{
 6 }
 7 class Father{
 8 }
 9 class Son extends Father implements A,B{
10     //方法的實現
11     public void a(){
12     }
13 }

 

提到抽象類就一定要提到介面

介面:介面其實相當於一個規範,當你定義一個介面時,實現介面的類必須實現介面中的所有的方法.舉個現實中的例子,比如我們的手機充電藉口,基本很少發生改變,因為他已經是規定死了的,使用介面等於制定一個規範,等於是所有的實現此介面的類都必須實現此規範,這樣就可以用介面來實現不同類的比較等操作.

介面的註意點:

  1.介面中的成員屬性必須都是public static final的,不修飾會自動加上,介面中的成員方法必須都是public static修飾的,且不可以使用其他的許可權修飾符

  2.介面不可以被實例化,必須使用子類 explements 介面,然後實現介面中的方法.

  3.一個類可以實現多個介面,可以在實現抽象類的同時實現多個介面或單個介面

 

三.多態

概念:同一個行為,對於傳入不同的對象,實現不同的動作              多態需要記住的一個概念:父類引用指向子類對象

多態的好處:提高了代碼的可復用性.

多態的壞處:無法使用子類所特有的方法.因為編譯時看的是右邊.

多態的實現必須有三要素  1.繼承(實現)  2.重寫  3.向上轉型(缺一不可!!!)

 1 public class Test{
 2     public static void main(String[] args){
 3         show(new Dog());
 4         show(new Cat());
 5     }
 6     public static void show(Animal a){
 7         a.eat();
 8     }
 9 }
10 abstract class Animal{
11     abstract void eat(){
12     }
13 }
14 class Dog extends Animal{
15     public void eat(){
16         System.out.println("在吃骨頭");
17     }
18 }
19 class Cat extends Animal{
20     public void eat(){
21         System.out.println("在吃魚");
22     }
23 }

多態基於繼承的實現如上.

public class Test01{
    public static void main(String[] args){
        show(new Dog());
        show(new Cat());
    }
    public static void show(Animal a){
        a.eat();
    }
}
interface Animal{
    abstract void eat();
}
class Dog implements Animal{
    public void eat(){
        System.out.println("在吃骨頭");
    }
}
class Cat implements Animal{
    public void eat(){
        System.out.println("在吃魚");
    }
}

介面的實現如上

 

提到多態就需要提到一個例子:

public class Test01{
    public static void main(String[] args){
        A a1=new A();
        A a2=new B();
        B b=new B();
        C c=new C();
        D d=new D();
        
        a1.show(b);// a and a
        a1.show(c);//a and a
        a1.show(d);//a and d
        a2.show(b);//b and a
        a2.show(c);//b and a
        a2.show(d);//a and d
    }
    /*public static void show(Animal a){
        a.eat();
    }*/
}
class A{
    void show(A a){
        System.out.println("a and a");
    }
    void show(D d){
        System.out.println("a and d");
    }
}
class B extends A{
    void show(A a){
        System.out.println("b and a");
    }
    void show(B b){
        System.out.println("b and b");
    }
}
class C extends B{
}
class D extends C{
}

我們先看a2.show(c),首先a2是一個a類型的引用類型,在a2種尋找show(c)參數為c類型的方法,沒有找到c類型的方法,於是到a2的超類尋找其方法,由於a類的超類是Object,也並沒有show(c)這個方法,於是將c類型進行了提升,變成了b類型,b類型在a中也不存在,於是便轉換成了a類型,a類型與A類中找到了方法,並由於A類型的show方法於B類型中進行了重寫,於是便輸出了b and a

其尋找的順序是:this.show(O)  super.show(O)  this.show(super(O))  super.show(super(O))

 

當使用了上述方法進行了多態的實現之後,其子類就會自動將其的特有方法給丟棄掉了,然而我們現在想調用這個對象的特有方法怎麼辦?

答案是使用使用強制類型轉換,而使用強制類型轉換則會有可能出現類型轉換異常,這個時候就需要使用instanceof運算符,使用方法:父類對象  instanceof  子類,若父類引用時子類類型時返回true,則可以使用強制類型轉換

這種實現過程叫做向下轉型


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 顏色的應用主要分為前景色、背景色和透明三個部分。 一、前景色 color color前景色 值: <color> | inherit 初始值: 用戶代理特定的值 應用於: 所有元素 繼承性: 有 一般來說,前景是元素的文本,不過前景還包括元素周圍的邊框。有兩種方式直接影響一個元素的前景色,可以使用c ...
  • :key是為vue的響應式渲染提供方法,在列表中單條數據改變的情況下,可以進行單獨渲染,減少頁面資源消耗。 當前頁面如果有列表渲染v-for,並且在v-for的迴圈標簽中沒有:key元素時,控制台會出現警告,我想對代碼有比較高追求的開發者都不會允許這一大片的黃色出現的吧,如下圖 在項目運行的時候也不 ...
  • 一、基本類型和引用類型的值 1.基本類型和引用類型的值 基本類型值:指那些保存在棧記憶體中的簡單數據,即這種值完全保存在記憶體中的一個位置,他們所占據的空間大小是固定的。 引用類型值:指那些保存在堆記憶體中的對象,這些類型的真正數據是保存在堆記憶體中的,而同時在棧記憶體中保存的只是一個指針,這個指針指向的是這 ...
  • ES5新增的常用數組方法 let arr = [1, 2, 3, 2, 1]; 一 forEach => 遍曆數組 arr.forEach((v, i) => { console.log(v, i); }); 二 map => 使用一個數組, 利用某規則映射得到一個新數組 let mapArr = ...
  • 一、函數的一些基礎概念: 1.js中的函數使用function來聲明。 2.關於return: 2.1 函數在執行到return語句後悔立即停止並退出,return後面的代碼永遠不會得到執行; 2.2 函數不必指定是否返回值,只要return語句後跟要返回的值即可實現返回值; 2.3 return語 ...
  • 現在,我們寫一個組件puppiesListCmp,用於顯示小狗狗的列表: //puppies list.component.ts @Component({ selector: 'puppies list', template: ` {{puppy.name}} {{puppy.age}} {{pup ...
  • 引用類型:引用類型是一種數據結構,用於將數據和功能組織在一起。引用類型的值是引用類型的一個實例。 一、Object ECMAScript中的對象其實就是一組數據和功能的結合。 Object類型其實是所有它的實例的基礎,換句話說,Object類型所有具有的任何屬性和方法也同樣存在於更具體的對象中。 c ...
  • 一、在HTML中使用javascript 1.直接是用<script></script>標簽。 2.外部引入 <script type="javascript" src="../app/js/test/test1.js"></script> 一般會放在瀏覽器的底部,讓頁面先載入出來,避免JS文件過多 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...