Java的三大特性總結

来源:http://www.cnblogs.com/yang21/archive/2017/07/02/7105187.html
-Advertisement-
Play Games

在Java中,面向對象編程有三大特性:封裝、繼承、多態。 先來說說封裝。 封裝,顧名思義,就是通過抽象數據類型(即ADT,一種為了將數據類型和可能在該數據類型上進行操作而定義的)將數據以及基於數據的操作封裝在一起,使之成為獨立的“實體”。 首先先來看一個Person類: 對於封裝的思想,我們需要盡可 ...


在Java中,面向對象編程有三大特性:封裝繼承多態

先來說說封裝。

封裝,顧名思義,就是通過抽象數據類型(即ADT,一種為了將數據類型和可能在該數據類型上進行操作而定義的)將數據以及基於數據的操作封裝在一起,使之成為獨立的“實體”。

首先先來看一個Person類:

 1 public class Person implements Comparable<Person> {
 2     private String firstname;
 3     private String lastname;
 4 
 5     public String getFirstname() {
 6         return firstname;
 7     }
 8 
 9     public void setFirstname(String firstname) {
10         this.firstname = firstname;
11     }
12 
13     public String getLastname() {
14         return lastname;
15     }
16 
17     public void setLastname(String lastname) {
18         this.lastname = lastname;
19     }
20 
21     @Override
22     public int hashCode() {
23         int hash = 7;
24         hash = 83 * hash + Objects.hashCode(this.firstname);
25         hash = 83 * hash + Objects.hashCode(this.lastname);
26         return hash;
27     }
28 
29     @Override
30     public boolean equals(Object obj) {
31         //檢查參數是否是這個對象的引用
32         if (this == obj) {
33             return true;
34         }
35         //檢查參數是否是正確的類型
36         if (!(obj instanceof chapter5_reflect.Person)) {
37             return false;
38         }
39         //將參數轉換成正確的類型
40         Person person = (Person) obj;
41         //對實體域進行匹配
42         return Objects.equals(this.firstname, person.firstname)
43                 && Objects.equals(this.lastname, person.lastname);
44     }
45 
46     @Override
47     public int compareTo(Person o) {
48         if (this == o) {
49             return 0;
50         }
51         if (null == o) {
52             return 1;
53         }
54         //先判斷姓氏是否相同
55         int comparison = this.firstname.compareTo(o.firstname);
56         if (comparison != 0) {
57             return comparison;
58         }
59         //姓氏相同則比較名
60         comparison = this.lastname.compareTo(o.lastname);
61         return comparison;
62     }
63 }

對於封裝的思想,我們需要儘可能的隱藏內部細節,只保留一些對外操作

例如在Person類中,我簡單的定義了兩個成員變數firstname和lastname,在setter方法里我們可以設置姓和名的一些格式,如首字母大寫,其餘小寫來進行“格式化”,對外開放getter來獲取變數的值。

現來總結一下封裝的優點:

1.能夠更好的把控成員變數,甚至是管理類的內部結構;

2.良好的封裝能夠減少耦合,使得代碼更加健壯;

3.外部程式通過對外介面即可進行訪問,無需關註實現細節。

 

再談繼承

繼承描述的是is-a的關係,它是復用代碼的一種方式,思想就在於定義和實現了一個類的時候,可以在一個已存在的類上進行擴展,把已存在的類的內容作為自己的內容,同時可以加入新的內容或者修改原來的方法來適應不同的需求。

下麵來看兩個例子:

 1 public class Person {
 2 
 3     private String name;
 4     private String sex;
 5     private int age;
 6 
 7     Person(String name, String sex, int age) {
 8         this.name = name;
 9         this.sex = sex;
10         this.age = age;
11     }
12 
13     //省略setter和getter方法...
14  37 }
 1 public class Yang extends Person {
 2 
 3     Yang(String name, String sex, int age) {
 4         super(name, sex, age);
 5     }
 6 
 7     public String getName() {
 8         return super.getName() + " is " + "genius";
 9     }
10 
11 }
1   public static void main(String... argc) {
2 //        Yang yang = new Yang("yang", "male", 23);
3         Person person = new Yang("yang", "male", 23);
4         out.print(person.getName());
5     }

輸出: yang is genius 

註意,如果父類沒有預設的構造器,子類構造函數中需要指定父類的構造器,否則編譯將會失敗!

從上面的代碼中不得不引出關於繼承的三大重要的東西,即構造器protected關鍵字以及向上轉型

我們知道,構造器是不能被繼承的,只許被調用!需要註意的是,子類是依賴於父類的(這也說明瞭一個弊端,即繼承是一種強耦合關係),子類擁有父類的非private屬性和方法(弊端二:破壞了封裝),所以父類應先於子類被創建。

所以當父類沒有預設構造器時,子類需要指定一個父類的構造器,並且寫於子類構造器的第一行!當然父類有預設構造器,子類就無需super了,Java會自動調用。

再說protected關鍵字。插一句,只有合理使用訪問修飾符,程式才能更好的為我們服務!!

對於子類,為了使用父類的方法,我們可以修改它的訪問修飾符為protected,而不是一股腦兒的寫上public!一勞永逸的做法可能會帶來更大的危害!

而對於類的成員變數,保持它的private!

最後是向上轉型了,它是一個重要的方面。從上面的的代碼中,我寫上了Person person = new Yang("yang", "male", 23); 這樣結果是將Yang向上轉型為Person,帶來的影響可能就是屬性和方法的丟失,但是它將是安全的。

同時它最大的作用是.....子類能夠提供父類更加強大的功能以適用於不同的場合,完成不同的操作。

不太清楚可以看看這兩個: List<String> arrayList = new ArrayList<>(); 和 List<String> linkedList = new LinkedList<>(); 

我們知道ArrayList是數組實現,查找更快;而LinkedList是鏈表實現,添加元素和刪除元素效率更好!

但是向上轉型有一個弊端,指向子類的父類引用因為向上轉型了,它將只擁有父類的屬性和方法,同時子類擁有而父類沒有的方法,是無法使用了的!

所以,繼承實現了軟體的可重用性可拓展性。但是Java是單繼承的,並且繼承也有多個弊端(上面有提),其實還有一個弊端是父類一旦改變,子類可能也得進行改變!所以慎用吧。

 

最後一個特性是多態了。多態性就是不同的子類型可以對同一個請求做出不同的操作。同時多態性分為編譯時多態性運行時多態性,對應著方法重載overload和方法重寫override

對於方法重寫,存在在繼承中。它作為運行時多態性的表現,首先需要子類繼承和實現父類的方法,然後向上轉型,父類引用子類對象,對同一件事作出不同的響應。

方法重寫時,需要註意的是子類的訪問修飾符的訪問範圍不能小於父類,如父類的一個方法修飾符為protected,那麼子類繼承時,只能選用public或者protected。除了訪問修飾符,其餘完全相同於父類!

對於方法重載,出現在同一個類中,它是編譯時多態性的表現。定義為:同名的方法如果有不同的參數列表便視為重載。

 

最後有一道經典的題目作為結尾,我也不知道出自哪....Look and think!

 1 public class A {
 2 
 3     public String show(D obj) {
 4         return ("Father and D");
 5     }
 6 
 7     public String show(A obj) {
 8         return ("Father and Father");
 9     }
10 }
11 
12 class B extends A {
13 
14     public String show(B obj) {
15         return ("Child and Child");
16     }
17 
18     public String show(A obj) {
19         return ("Child and Father");
20     }
21 }
22 
23 class C extends B {
24 }
25 
26 class D extends B {
27 }
28 
29 class Test {
30     public static void main(String[] args) {
31         A a1 = new A();
32         A a2 = new B();
33         B b = new B();
34         C c = new C();
35         D d = new D();
36 
37         System.out.println("1--" + a1.show(b));
38         System.out.println("2--" + a1.show(c));
39         System.out.println("3--" + a1.show(d));
40         System.out.println("4--" + a2.show(b));
41         System.out.println("5--" + a2.show(c));
42         System.out.println("6--" + a2.show(d));
43         System.out.println("7--" + b.show(b));
44         System.out.println("8--" + b.show(c));
45         System.out.println("9--" + b.show(d));
46     }
47 }

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

-Advertisement-
Play Games
更多相關文章
  • 之前公司下達了開發微信只一塊的任務,然後我就去網上取了一番經,可是感覺對於我這種微信開發的新手來說,所需要的東西太多,太凌亂了,然後整個人就懵逼了。 費了很長時間才將微信介面調用完成。所以吶,我整理了一下,調用微信介面前需要準備的內容。 1.微信公眾平臺的appid 2.微信公眾平臺的secret ...
  • 反射是.NET中的重要機制,通過反射,可以在運行時獲得程式或程式集中每一個類型(包括類、結構、委托、介面和枚舉等)的成員和成員的信息。有了反射,即可對每一個類型瞭如指掌。另外我還可以直接創建對象,即使這個對象的類型在編譯時還不知道。 Anker_張(博客園)http://www.cnblogs.co ...
  • 剛做了一個小改動,需要在微信端顯示另外一個網站中通過富文本編輯後的信息,當然其中包括一些圖片內容。 其他的顯示都沒有問題,唯獨照片無法正常顯示,一直都是破碎的圖片樣式。 經過調試發現,圖片的顯示地址一直為另外一個網站的hosturl+path,然後發現資料庫中富文本的內容只有path,也沒有註明ho ...
  • 期望: 1.球體接觸到框體後反彈 2.設置速度按鍵,按下後改變球體速度、顏色狀態 具體實現: ...
  • 大家都知道main方法的參數就是一個數組類型的,那麼它其實也是可以改成不定參數類型。我試了試,並調用了一些彈出來的方法。 嗯,我把Sting後面的“[ ]”換成了三個點(...),這三個點代表Java中的可變數組參數。可變的參數類型(variable argument type),也稱為不定參數類型 ...
  • 項目中需要對Excel進行操作,把數據中的數據寫入到Excel文件中。在數據量大的情況下,操作Excel是一件費時的操作。 但是執行到下列代碼時就會出現空指針的情況: 第四行返回的workbooks指針是一個空指針,無法進行向下的Excel操作。這是因為QAxObject對象是預設在單線程下使用, ...
  • 索引 簡述 準備 示例 效果圖 結語 簡述 我在使用opencv2或3的時候想要在圖片上添加中文文字,需要去下載Freetype庫,編譯好鏈接到opencv庫中才能中文的輸出。網上大部分在圖片中插入中文的教程還是win+vs的配置教程。像我這種win下有環境,linux下有環境的人來說,想要同步代碼 ...
  • 1.1 庫的概念 在我看來,庫是已經寫好的、成熟的、可復用的代碼。每個程式都需要依賴很多底層庫,不可能每個人的代碼從零開始編寫代碼,因此庫的存在具有非常重要的意義。 在我們的開發的應用中經常有一些公共代碼是需要反覆使用的,就把這些代碼編譯為庫文件。 庫可以簡單看成一組目標文件的集合,將這些目標文件經 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...