# JAVA之旅(六)——單例設計模式,繼承extends,聚集關系,子父類變量關系,super,覆蓋
* * *
> java也越來越深入了,大家加油吧!咱們一步步來
## 一.單例設計模式
* 什么是設計模式?
> JAVA當中有23種設計模式,解決某一問題最有效的方法
* 單例設計模式
> 解決一個類在內存中只存在一個對象
> 想要保證對象唯一該怎么做》
* 1.為了避免其他程序過多建立該類對象,先禁止其他程序建立該類對象
* 2.還為了讓其他程序訪問到該類對象,只好在本類中自定義一個對象
* 3.為了方便其他程序對自定義對象的訪問,可以對外提供一些訪問方式
> 這三步怎么怎么實現呢?
* 1.將構造函數私有化
* 2.在類中創建一個本類對象
* 3.提供一個方法可以獲取到該對象
> 然后我們的代碼就出來了
~~~
/**
* 單例模式
*
* @author LGL
*
*/
public class Single {
// 將構造函數私有化
private Single() {
}
// 在類中創建一個本類對象
private static Single s = new Single();
// 提供一個方法可以獲取到該對象
public static Single getInstance() {
return s;
}
}
~~~
> 當然,我們還有一種寫法——懶漢式
~~~
/**
* 單例模式
* 懶漢式
* @author LGL
*
*/
public class Single {
private static Single s = null;
public Single() {
// TODO Auto-generated constructor stub
}
public static Single getInstance() {
if (s == null)
s = new Single();
return s;
}
}
~~~
> 也有這么一種寫法
~~~
/**
* 單例模式
* 餓漢式
*
* @author LGL
*
*/
public class Single {
private static Single s = new Single();
public Single() {
// TODO Auto-generated constructor stub
}
public static Single getInstance() {
return s;
}
}
~~~
> 單例模式的寫法多種多樣,只要掌握這個思想就可以了
>
> 餓漢式的特點:single類一進內存就已經創建好了對象?
> 懶漢式的特點:對象是方法被調用時才初始化,也叫作對象的延遲加載
>
> Single類進內存還沒有存在,只有調用了getInstance()方法時才建立對象,這就叫做延遲加載
>
> 我們一般用餓漢式,因為他安全,簡單
## 二.繼承
> 面向對象的思想中的一個思想,繼承,我們可以這樣去理解,我們可以定義一個學生類,他有名字和年齡,還有一個學習的方法
~~~
/**
* 學生
* @author LGL
*
*/
class Student {
String name;
int age;
void study() {
System.out.println("學習");
}
}
~~~
> 然后我們可以再定義一個工人類
~~~
/**
* 工人
* @author LGL
*
*/
class Worker {
String name;
int age;
void work() {
System.out.println("工作");
}
}
~~~
> 他同樣有名字和年齡還有一個工作的方法
>
> 這個時候我們可以發現,他們都存在相同的關系,他們都是人,人都具備年齡和姓名,所以我們可以將學生和工人的共性提取出來描述,只要讓學生和工人與單獨描述的類有關系就行,也就是繼承
~~~
/**
* 人
*
* @author LGL
*
*/
class Person {
String name;
int age;
}
~~~
> 這個Person就叫做父類,超類,基類
>
> 然后我們的工人和學生就可以這樣去寫
~~~
/**
* 學生
*
* @author LGL
*
*/
class Student extends Person {
void study() {
System.out.println("學習");
}
}
/**
* 工人
*
* @author LGL
*
*/
class Worker extends Person {
void work() {
System.out.println("工作");
}
}
~~~
> 他們是Person的子類,繼承是源于生活,所以工人不能繼承學生,沒有倫理性,千萬不要為了獲取其他類的功能,簡化代碼而繼承,必須是類與類之間有所屬關系才可以繼承,is a 的關系?
> 繼承的優點
* 1.提高代碼的復用性
* 2.讓類與類之間產生關系,有了這層關系才有了多態的特性
> JAVA語言中,java只支持單繼承,不支持多繼承
* 為什么不能多繼承??
> 因為多繼承容易帶來安全隱患,當多個父類中定義了相同的功能,當功能內容不同時,子類對象不確定運行哪一個,但是JAVA保留了這種機制,并用另一種體現形式來表示,多實現。
JAVA支持多層繼承,也就是一個繼承體系
如何使用一個繼承體系的功能?
* 想要使用體系,先查閱體系中父類的描述,因為父類中定義的是該體系中的共性內容,通過了解共性功能就可以知道該體系的基本功能,那么,這么體系已經可以基本使用了。
* 那么集體調用時,要創建最子類的對象,為什么?一是因為有可能父類不能創建對象,二是創建子類對象可能使用更多的功能,包括基本的也包括特有的
> 簡單的說一句:查閱父類功能,創建子類對象使用功能
## 三.聚集關系
> 這個概念可能很多人不是很熟悉,確實我們實際開發當中很少提到,我們對象和對象之間,不光有繼承關系,還有組合關系,
* 聚合
> 球員是球隊中的一個,球隊中有球員,這就是聚合關系
* 組合
> 手是人身體的一部分,腿是身體的一部分,這就是組合關系,你說這和聚合沒什么不同,那你就錯了,要知道,球隊少了個球員沒事,人少胳膊少腿就有事哦,所以組合關系更加緊密一點
> 都是吧對象撮合在一起,像我們繼承是秉承一個is a的關系,而聚集是has a的關系,誰里面有誰
>
> 這個關系我們就不多做贅述了
>
> 我們關系講完了,現在應該可以用代碼去表示表示了,這里我就用當繼承關系時,子類和父類之間的變量關系來舉例
## 四.子父類變量關系
> 我們來探索一下子父類出現后,類成員的特點
* 1. 變量
* 2.函數
* 3.構造函數
> 我們一步步來分析
### 1.變量
> 我們擼一串代碼
~~~
//公共的 類 類名
public class HelloJJAVA {
// 公共的 靜態 無返回值 main方法 數組
public static void main(String[] str) {
/**
* 子父類出現后,類成員的特點
*/
Zi z = new Zi();
System.out.println("num1 = " + z.num1 + "\n" + "num2 = " + z.num2);
}
}
/**
* 父類
*
* @author LGL
*
*/
class Fu {
int num1 = 4;
}
/**
* 子類
*
* @author LGL
*
*/
class Zi extends Fu {
int num2 = 5;
}
~~~
> 這樣,是不是很容易知道輸出的結果

> 但是我們那會這么簡單,我們還有特殊情況
~~~
//公共的 類 類名
public class HelloJJAVA {
// 公共的 靜態 無返回值 main方法 數組
public static void main(String[] str) {
/**
* 子父類出現后,類成員的特點
*/
Zi z = new Zi();
System.out.println("num1 = " + z.num + "\n" + "num2 = " + z.num);
}
}
/**
* 父類
*
* @author LGL
*
*/
class Fu {
int num = 4;
}
/**
* 子類
*
* @author LGL
*
*/
class Zi extends Fu {
int num = 5;
}
~~~
> 當子類和父類都有相同的變量的時候,現在該打印什么呢?

> 沒錯,打印了子類的值,為什么?因為輸出的num前面其實默認帶了一個this,如果我們要打印父類的值,需要加super,這是一個新的關鍵字了
~~~
void show(){
System.out.println(super.num);
}
~~~
> 結果顯而易見了

> 所以變量的特點:如果子類中出現非私有的同名成員變量時,子類要訪問本類中的成員變量,用this,子類訪問父類中的同名變量,用super,this和super的使用幾乎一致,this代表的是本類對象的引用,super代表父類對象的引用
>
> 不過我們也不會這么蛋疼在父類創建又在子類創建,我們來看第二個
### 2.函數
> 也就是方法,我們正常的應該是這樣寫的
~~~
//公共的 類 類名
public class HelloJJAVA {
// 公共的 靜態 無返回值 main方法 數組
public static void main(String[] str) {
/**
* 子父類出現后,類成員的特點
*/
Zi z = new Zi();
z.show1();
z.show2();
}
}
/**
* 父類
*
* @author LGL
*
*/
class Fu {
void show1() {
System.out.println("fu");
}
}
/**
* 子類
*
* @author LGL
*
*/
class Zi extends Fu {
void show2() {
System.out.println("zi");
}
}
~~~
> 這是很正常的實現

> 我們當然要說一種特殊情況,子父類方法同名我們該怎么辦?我們運行一下

> 這是子運行了,這種情況叫做覆蓋(重寫),這個特性的特點
* 當子類出現和父類一模一樣的函數時,當子類對象被調用了該函數,會運行子類函數的內容,如同父類的函數被覆蓋一樣,這種情況就是覆蓋了
> 當子類繼承了父類,沿襲了父類的功能到子類中,到子類中,但是子類雖具備該功能,但是功能的內容卻和父類不一致,這時沒有必要定義新功能,而是使用覆蓋特性,保留父類的功能定義并重寫功能內容
* 覆蓋
> 1.子類覆蓋父類,必須保證子類權限大于等于父類權限才可以覆蓋,否則編譯失敗?
> 2.靜態只能覆蓋靜態(一般沒人用)
* 記住
> 重載:只看同名函數的參數列表?
> 重寫:字符類方法要一模一樣 ,包括返回值類型
### 3.構造函數
> 最后一個特點了
~~~
//公共的 類 類名
public class HelloJJAVA {
// 公共的 靜態 無返回值 main方法 數組
public static void main(String[] str) {
/**
* 子父類出現后,類成員的特點
*/
Zi z = new Zi();
}
}
/**
* 父類
*
* @author LGL
*
*/
class Fu {
public Fu() {
System.out.println("fu");
}
}
/**
* 子類
*
* @author LGL
*
*/
class Zi extends Fu {
public Zi() {
System.out.println("zi");
}
}
~~~
> 我們現在運行一下

> 你會疑問,我明明實例化的是子類,怎么父類也實例化了,因為子類構造函數的第一行默認有一個方法
~~~
super();
~~~
> 在對子類對象進行初始化時,父類的構造函數也會執行,那就是因為子類的構造函數默認第一行有一條隱式的語句super();他會訪問父類中空參數的構造函數,而且子類中所有的構造函數默認第一行都是super()
* 為什么子類一定要訪問父類中的構造函數?
> 因為父類中的數據子類可以直接獲取,所有子類建立對象的時候,需要先查看父類如何對這些數據進行初始化的,所有子類對這些對象初始化時,要先訪問父類中的構造函數,如果要訪問父類中指定的構造函數,可以手動定義super(xx,xx)的方式。
* 注意
> super語句一定定義在子類構造函數的第一行
* 結論:
> 子類的所有的構造函數,默認都會訪問父類中空參數的構造函數,因為子類每一個構造函數內的第一行都有一句隱式的super,當父類中沒有空參數的構造函數時,子類必須手動通過super或者this語句的形式指定要訪問父類中的構造函數
> 當然,子類的構造函數也可以指定this來訪問本類中的構造函數,子類中至少會有一個構造函數會訪問父類中的構造函數,這個結論就是子類的實例化過程,逐級向上查找
>
> 父類也向上查找,他找的是JAVA中所有類的老爹——Object
>
> 行,我們本篇幅就閑到這里吧,概念多了,反而難以消化,我們要一點點的來
## 如果有興趣可以加群:555974449,這可能是迄今為止最和諧的IT群了
版權聲明:本文為博主原創文章,博客地址:http://blog.csdn.net/qq_26787115,未經博主允許不得轉載。
- 0-發現
- AndroidInterview-Q-A
- Android能讓你少走彎路的干貨整理
- LearningNotes
- temp
- temp11
- 部分地址
- 0-待辦任務
- 待補充列表
- 0-未分類
- AndroidView事件分發與滑動沖突處理
- Spannable
- 事件分發機制詳解
- 1-Java
- 1-Java-01基礎
- 未歸檔
- 你應該知道的JDK知識
- 集合框架
- 1-Java-04合集
- Java之旅0
- Java之旅
- JAVA之旅01
- JAVA之旅02
- JAVA之旅03
- JAVA之旅04
- JAVA之旅05
- JAVA之旅06
- JAVA之旅07
- JAVA之旅08
- JAVA之旅09
- java之旅1
- JAVA之旅10
- JAVA之旅11
- JAVA之旅12
- JAVA之旅13
- JAVA之旅14
- JAVA之旅15
- JAVA之旅16
- JAVA之旅17
- JAVA之旅18
- JAVA之旅19
- java之旅2
- JAVA之旅20
- JAVA之旅21
- JAVA之旅22
- JAVA之旅23
- JAVA之旅24
- JAVA之旅25
- JAVA之旅26
- JAVA之旅27
- JAVA之旅28
- JAVA之旅29
- java之旅3
- JAVA之旅30
- JAVA之旅31
- JAVA之旅32
- JAVA之旅33
- JAVA之旅34
- JAVA之旅35
- 1-Java-05辨析
- HashMapArrayMap
- Java8新特性
- Java8接口默認方法
- 圖解HashMap(1)
- 圖解HashMap(2)
- 2-Android
- 2-Android-1-基礎
- View繪制流程
- 事件分發
- AndroidView的事件分發機制和滑動沖突解決
- 自定義View基礎
- 1-安卓自定義View基礎-坐標系
- 2-安卓自定義View基礎-角度弧度
- 3-安卓自定義View基礎-顏色
- 自定義View進階
- 1-安卓自定義View進階-分類和流程
- 10-安卓自定義View進階-Matrix詳解
- 11-安卓自定義View進階-MatrixCamera
- 12-安卓自定義View進階-事件分發機制原理
- 13-安卓自定義View進階-事件分發機制詳解
- 14-安卓自定義View進階-MotionEvent詳解
- 15-安卓自定義View進階-特殊形狀控件事件處理方案
- 16-安卓自定義View進階-多點觸控詳解
- 17-安卓自定義View進階-手勢檢測GestureDetector
- 2-安卓自定義View進階-繪制基本圖形
- 3-安卓自定義View進階-畫布操作
- 4-安卓自定義View進階-圖片文字
- 5-安卓自定義View進階-Path基本操作
- 6-安卓自定義View進階-貝塞爾曲線
- 7-安卓自定義View進階-Path完結篇偽
- 8-安卓自定義View進階-Path玩出花樣PathMeasure
- 9-安卓自定義View進階-Matrix原理
- 通用類介紹
- Application
- 2-Android-2-使用
- 2-Android-02控件
- ViewGroup
- ConstraintLayout
- CoordinatorLayout
- 2-Android-03三方使用
- Dagger2
- Dagger2圖文完全教程
- Dagger2最清晰的使用教程
- Dagger2讓你愛不釋手-終結篇
- Dagger2讓你愛不釋手-重點概念講解、融合篇
- dagger2讓你愛不釋手:基礎依賴注入框架篇
- 閱讀筆記
- Glide
- Google推薦的圖片加載庫Glide:最新版使用指南(含新特性)
- rxjava
- 這可能是最好的RxJava2.x入門教程完結版
- 這可能是最好的RxJava2.x入門教程(一)
- 這可能是最好的RxJava2.x入門教程(三)
- 這可能是最好的RxJava2.x入門教程(二)
- 這可能是最好的RxJava2.x入門教程(五)
- 這可能是最好的RxJava2.x入門教程(四)
- 2-Android-3-優化
- 優化概況
- 各種優化
- Android端秒開優化
- apk大小優化
- 內存分析
- 混淆
- 2-Android-4-工具
- adb命令
- 一鍵分析Android的BugReport
- 版本控制
- git
- git章節簡述
- 2-Android-5-源碼
- HandlerThread 源碼分析
- IntentService的使用和源碼分析
- 2-Android-9-辨析
- LRU算法
- 什么是Bitmap
- 常見圖片壓縮方式
- 3-Kotlin
- Kotlin使用筆記1-草稿
- Kotlin使用筆記2
- kotlin特性草稿
- Kotlin草稿-Delegation
- Kotlin草稿-Field
- Kotlin草稿-object
- 4-JavaScript
- 5-Python
- 6-Other
- Git
- Gradle
- Android中ProGuard配置和總結
- gradle使用筆記
- Nexus私服搭建
- 編譯提速最佳實踐
- 7-設計模式與架構
- 組件化
- 組件化探索(OKR)
- 1-參考列表
- 2-1-組件化概述
- 2-2-gradle配置
- 2-3-代碼編寫
- 2-4-常見問題
- 2-9-值得一讀
- 8-數據結構與算法
- 0臨時文件
- 漢諾塔
- 8-數據-1數據結構
- HashMap
- HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比較
- 遲到一年HashMap解讀
- 8-數據-2算法
- 1個就夠了
- Java常用排序算法(必須掌握的8大排序算法)
- 常用排序算法總結(性能+代碼)
- 必須知道的八大種排序算法(java實現)
- 9-職業
- 閱讀
- 書單
- 面試
- 面試-01-java
- Java面試題全集駱昊(上)
- Java面試題全集駱昊(下)
- Java面試題全集駱昊(中)
- 面試-02-android
- 40道Android面試題
- 面試-03-開源源碼
- Android圖片加載框架最全解析(二),從源碼的角度理解Glide的執行流程
- 面試-07-設計模式
- 面試-08-算法
- 面試-09-其他
- SUMMARY
- 版權說明
- temp111