Java提高篇 —— Java三大特性之繼承

一、前言

?

? ? ? ?在《Think in java》中有這樣一句話:復用代碼是Java眾多引人注目的功能之一。但要想成為極具革命性的語言,僅僅能夠復制代碼并對加以改變是不夠的,它還必須能夠做更多的事情。在這句話中最引人注目的是“復用代碼”,盡可能的復用代碼使我們程序員一直在追求的,現在我來介紹一種復用代碼的方式,也是java三大特性之一——繼承。

?

二、繼承

?

? ? ? ?在講解之前我們先看一個例子,該例子是前篇博文(Java提高篇 —— Java三大特性之封裝)。

? ? ? ?從這里我們可以看出,Wife、Husband兩個類除了各自的husband、wife外其余部分全部相同,作為一個想最大限度實現復用代碼的我們是不能夠忍受這樣的重復代碼,如果再來一個小三、小四……我們是不是也要這樣寫呢?那么我們如何來實現這些類的可復用呢?利用繼承!!

? ? ? ?首先我們先離開軟件編程的世界,從常識中我們知道丈夫、妻子、小三、小四…,他們都是人,而且都有一些共性,有名字、年齡、性別、頭等等,而且他們都能夠吃東西、走路、說話等等共同的行為,所以從這里我們可以發現他們都擁有人的屬性和行為,同時也是從人那里繼承來的這些屬性和行為的。

? ? ? ?從上面我們就可以基本了解了繼承的概念了,繼承是使用已存在的類的定義作為基礎建立新類的技術,新類的定義可以增加新的數據或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。通過使用繼承我們能夠非常方便地復用以前的代碼,能夠大大的提高開發的效率。

? ? ? ?對于Wife、Husband使用繼承后,除了代碼量的減少我們還能夠非常明顯的看到他們的關系。

? ? ? ?繼承所描述的是“is-a”的關系,如果有兩個對象A和B,若可以描述為“A是B”,則可以表示A繼承B,其中B是被繼承者稱之為父類或者超類,A是繼承者稱之為子類或者派生類。

? ? ? ?實際上繼承者是被繼承者的特殊化,它除了擁有被繼承者的特性外,還擁有自己獨有得特性。例如貓有抓老鼠、爬樹等其他動物沒有的特性。同時在繼承關系中,繼承者完全可以替換被繼承者,反之則不可以,例如我們可以說貓是動物,但不能說動物是貓就是這個道理,其實對于這個我們將其稱之為“向上轉型”,下面介紹。

? ? ? ?誠然,繼承定義了類如何相互關聯,共享特性。對于若干個相同或者相識的類,我們可以抽象出他們共有的行為或者屬相并將其定義成一個父類或者超類,然后用這些類繼承該父類,他們不僅可以擁有父類的屬性、方法還可以定義自己獨有的屬性或者方法。

同時在使用繼承時需要記住三句話:

? ? ? ?1、子類擁有父類非private的屬性和方法。

???????2、子類可以擁有自己屬性和方法,即子類可以對父類進行擴展。

???????3、子類可以用自己的方式實現父類的方法。

? ? ? ?綜上所述,使用繼承確實有許多的優點,除了將所有子類的共同屬性放入父類,實現代碼共享,避免重復外,還可以使得修改擴展繼承而來的實現比較簡單。

? ? ? ?誠然,講到繼承一定少不了這三個東西:構造器、protected關鍵字、向上轉型。

?

三、構造器

?

? ? ? ?通過前面我們知道子類可以繼承父類的屬性和方法,除了那些private的外還有一樣是子類繼承不了的---構造器。對于構造器而言,它只能夠被調用,而不能被繼承。 調用父類的構造方法我們使用super()即可。

? ? ? ?對于子類而已,其構造器的正確初始化是非常重要的,而且當且僅當只有一個方法可以保證這點:在構造器中調用父類構造器來完成初始化,而父類構造器具有執行父類初始化所需要的所有知識和能力。

public class Person {protected String name;protected int age;protected String sex;Person(){System.out.println("Person Constrctor...");}
}public class Husband extends Person{private Wife wife;Husband(){System.out.println("Husband Constructor...");}public static void main(String[] args) {Husband husband  = new Husband();}
}Output:
Person Constrctor...
Husband Constructor...

? ? ? ?通過這個示例可以看出,構建過程是從父類“向外”擴散的,也就是從父類開始向子類一級一級地完成構建。而且我們并沒有顯示的引用父類的構造器,這就是java的聰明之處:編譯器會默認給子類調用父類的構造器。

? ? ? ?但是,這個默認調用父類的構造器是有前提的:父類有默認構造器。如果父類沒有默認構造器,我們就要必須顯示的使用super()來調用父類構造器,否則編譯器會報錯:無法找到符合父類形式的構造器。

public class Person {protected String name;protected int age;protected String sex;Person(String name){System.out.println("Person Constrctor-----" + name);}
}public class Husband extends Person{private Wife wife;Husband(){super("chenssy");System.out.println("Husband Constructor...");}public static void main(String[] args) {Husband husband  = new Husband();}
}Output:
Person Constrctor-----chenssy
Husband Constructor...

? ? ? ?所以綜上所述:對于繼承而已,子類會默認調用父類的構造器,但是如果沒有默認的父類構造器,子類必須要顯示的指定父類的構造器,而且必須是在子類構造器中做的第一件事(第一行代碼)。

?

四、protected關鍵字

?

? ? ? ?private訪問修飾符,對于封裝而言,是最好的選擇,但這個只是基于理想的世界,有時候我們需要這樣的需求:我們需要將某些事物盡可能地對這個世界隱藏,但是仍然允許子類的成員來訪問它們。這個時候就需要使用到protected。

? ? ? ?對于protected而言,它指明就類用戶而言,他是private,但是對于任何繼承與此類的子類而言或者其他任何位于同一個包的類而言,他卻是可以訪問的。

public class Person {private String name;private int age;private String sex;protected String getName() {return name;}protected void setName(String name) {this.name = name;}public String toString(){return "this name is " + name;}/** 省略其他setter、getter方法 **/
}public class Husband extends Person{private Wife wife;public  String toString(){setName("chenssy");    //調用父類的setName();return  super.toString();    //調用父類的toString()方法}public static void main(String[] args) {Husband husband = new Husband();System.out.println(husband.toString());}
}Output:
this name is chenssy

? ? ? ?從上面示例可以看書子類Husband可以明顯地調用父類Person的setName()。

? ? ? ?誠然盡管可以使用protected訪問修飾符來限制父類屬性和方法的訪問權限,但是最好的方式還是將屬性保持為private(我們應當一致保留更改底層實現),通過protected方法來控制類的繼承者的訪問權限。

?

五、向上轉型

?

? ? ? ?在上面的繼承中我們談到繼承是is-a的相互關系,貓繼承與動物,所以我們可以說貓是動物,或者說貓是動物的一種。這樣將貓看做動物就是向上轉型。如下:

public class Person {public void display(){System.out.println("Play Person...");}static void display(Person person){person.display();}
}public class Husband extends Person{public static void main(String[] args) {Husband husband = new Husband();Person.display(husband);      //向上轉型}
}

? ? ? ?在這我們通過Person.display(husband)。這句話可以看出husband是person類型。

? ? ? ?將子類轉換成父類,在繼承關系上面是向上移動的,所以一般稱之為向上轉型。由于向上轉型是從一個叫專用類型向較通用類型轉換,所以它總是安全的,唯一發生變化的可能就是屬性和方法的丟失。這就是為什么編譯器在“未曾明確表示轉型”活“未曾指定特殊標記”的情況下,仍然允許向上轉型的原因。

?

六、慎用繼承

?

? ? ? ?上面講了繼承所帶來的諸多好處,那我們是不是就可以大肆地使用繼承呢?送你一句話:慎用繼承。

首先我們需要明確,繼承存在如下缺陷:

? ? ? ?1、父類變,子類就必須變。

???????2、繼承破壞了封裝,對于父類而言,它的實現細節對與子類來說都是透明的。

???????3、繼承是一種強耦合關系。?????

? ? ? ?所以說當我們使用繼承的時候,我們需要確信使用繼承確實是有效可行的辦法。那么到底要不要使用繼承呢?《Think in java》中提供了解決辦法:問一問自己是否需要從子類向父類進行向上轉型。如果必須向上轉型,則繼承是必要的,但是如果不需要,則應當好好考慮自己是否需要繼承。

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446957.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446957.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446957.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java提高篇 —— Java三大特性之多態

一、前言 面向對象編程有三大特性:封裝、繼承、多態。 封裝:隱藏了類的內部實現機制,可以在不影響使用的情況下改變類的內部結構,同時也保護了數據。對外界而已它的內部細節是隱藏的,暴露給外界的只是它的訪問方法。 繼…

光盤刻錄制作Ubuntu等操作系統的啟動盤

前提條件 軟媒刻錄 空白光盤(至少4.7G)電腦(最好使用外置的光驅)系統鏡像(ISO格式) 具體操作 打開軟媒魔方選擇光盤刻錄按照標紅的進行選擇選擇鏡像->選擇或者拖拽都可以選擇刻錄機->如果使用外部刻…

Java提高篇 —— 抽象類與接口

一、前言 接口和內部類為我們提供了一種將接口與實現分離的更加結構化的方法。 抽象類與接口是java語言中對抽象概念進行定義的兩種機制,正是由于他們的存在才賦予java強大的面向對象的能力。他們兩者之間對抽象概念的支持有很大的相似,甚至可以互換&…

C++ const相關內容學習

const 作用 修飾變量,說明變量不可以被修改修飾指針,分為指向常量的指針(pointer to const)和自身是常量的指針(常量指針,const pointer)修飾引用,指向常量的引用(refe…

Java提高篇 —— Java淺拷貝和深拷貝

一、前言 我們知道在Java中存在這個接口Cloneable,實現該接口的類都會具備被拷貝的能力,同時拷貝是在內存中進行,在性能方面比我們直接通過new生成對象來的快,特別是在大對象的生成上,使得性能的提升非常明顯。然而我們…

openssl里面AES算法主要函數的參數的介紹

注意事項 使用API的時候,需要特別小心數據長度,一般沒有指定長度的參數,默認都是16(AES_BLOCK_SIZE)個字節。輸出數據的長度一般都是16字節的倍數,否則會出現數組越界訪問。以下API中,encrypt表…

Java提高篇 —— Java內部類詳解

一、簡介 內部類是一個非常有用的特性但又比較難理解使用的特性。 內部類我們從外面看是非常容易理解的,無非就是在一個類的內部在定義一個類。 public class OuterClass {private String name ;private int age;public String getName() {return name;}public voi…

Ubuntu修改界面的大小

命令 xrandr 就會顯示ubuntu支持的屏幕比例使用命令 xrandr --size 1680x1050 切換屏幕大小

Java提高篇 —— String緩沖池

一、String緩沖池 首先我們要明確,String并不是基本數據類型,而是一個對象,并且是不可變的對象。查看源碼就會發現String類為final型的(當然也不可被繼承),而且通過查看JDK文檔會發現幾乎每一個修改String對…

C++最新使用開源openssl實現輸入是文件,輸出是文件的AES加解密的代碼

AES.h頭文件 #include <cstring> #include <fstream> #include <iostream> #include <openssl/aes.h>//AES文件加密函數 int aes_encrypt_file(const std::string &original_backup_file_path,const std::string &encrypted_file_path,const …

Java基礎 —— JVM內存模型與垃圾回收

目錄一、概述二、運行時數據區方法區運行時常量池堆棧本地方法棧程序計數器三、對象訪問四、垃圾回收如何定義垃圾1、引用計數法2、可達性分析垃圾回收方法1、Mark-Sweep標記-清除算法2、Copying復制算法3、Mark-Compact標記-整理算法4、Generational Collection 分代收集垃圾收…

Report Design

ERP_ENT_STD-CSDN博客

規范化流程化提交自己代碼到遠程gitlab服務器

流程 進入到build目錄使用make命令進行編譯 make -j 6&#xff0c;前提是cmake命令已經執行../format.py rungit add .. 添加文件git checkout -b xxx 創建xxx分支&#xff0c;其中xxx是分支名字git branch 查看分支git commit -m "[chy/backup] modify parameters for…

Java提高篇 ——Java注解

目錄一、注解注解的定義注解的應用元注解RetentionDocumentedTargetInheritedRepeatable注解的屬性Java 預置的注解DeprecatedOverrideSuppressWarningsSafeVarargsFunctionalInterface二、注解的提取三、注解與反射四、注解的使用場景五、親手自定義注解完成某個目的六、注解應…

linux使用openssl查看文件的md5數值

代碼 #include <stdio.h> #include <openssl/md5.h>std::string get_file_md5(const char *path){unsigned char digest [MD5_DIGEST_LENGTH];std::ifstream file(path, std::ios::in | std::ios::binary); //打開文件MD5_CTX md5_ctx;MD5_Init(&md5_ctx);cha…

Android 性能優化四個方面總結

目錄一、四個方面二、卡頓優化1、Android系統顯示原理2、卡頓根本原因3、性能分析工具&#xff08;1&#xff09;Profile GPU Rendering&#xff08;2&#xff09;TraceView&#xff08;3&#xff09;Systrace UI 性能分析4、優化建議&#xff08;1&#xff09;布局優化&#x…

pycharm/clion/idea等產品多含代碼左移右移操作

左移 選中多行代碼后&#xff0c;按下Tab鍵&#xff0c;一次縮進四個字符 右移 鼠標選中多行代碼后&#xff0c;同時按住shiftTab鍵&#xff0c;一次左移四個字符

Android 開源框架選擇

目錄一、前言二、APP的整體架構三、技術選型的考量點四、日志記錄能力五、JSON解析能力1、gson2、jackson3、Fastjson4、LoganSquare六、數據庫操作能力1、ActiveAndroid2、ormlite3、greenDAO4、Realm七、網絡通信能力1、android-async-http2、OkHttp3、Volley4、Retrofit八、…

使用opensll的md5對于string進行加密

代碼 #include <openssl/md5.h>#include <sstream> #include <iomanip> #include <iostream>void get_string_md5(const std::string& await_md5_string) {unsigned char md5[MD5_DIGEST_LENGTH];MD5(reinterpret_cast<unsigned const char*&g…

Android Studio 自定義Gradle Plugin

一、簡介 之前公司的一個項目需要用到Gradle插件來修改編譯后的class文件&#xff0c;今天有時間就拿出來整理一下&#xff0c;學習一下Gradle插件的編寫還是一件十分有意義的事。 二、Gradle插件類型 一種是直接在項目中的gradle文件里編寫&#xff0c;這種方式的缺點是無法復…