- 面向對象的特征之一封裝
- 面向對象的特征之二繼承
- 方法重寫(override/overWrite)
- 方法的重載(overload)和重寫(override)的區別:
- 面向對象特征之三:多態
- Instanceof關鍵字的使用
- JAVA中的JUnit單元測試
- 包裝類(WrApper)的使用
- 類的成員之四:代碼塊(初始化塊)
- 模板方法設計模式(TemplateMethod)
- Java8中關于接口的改進
- 類的內部成員之五:內部類
- 3. 抽象類和接口有哪些共同點和區別?
Java的面向對象
1.java類及類的成員:屬性,方法,構造器; 代碼塊,內部類
2.面向對象的三大特征:封裝性,繼承性,多態性
3.其他關鍵字:this,super,static,final,abstract,interface,package,import等
類 = 屬性 + 方法
1.屬性 = 成員變量 = field = 域,字段
2.行為 = 方法 = 成員方法 = 函數 = method
3.創建類的對象 = 類的實例化 = 實例化對象
類和對象的使用(面向對象思想的落地實現)
1.創建類,設計類的成員
2.創建類的對象
3.通過“對象.屬性”或“對象.方法”調用對象的結構
對象的內存分析
類的成員之一屬性
類中屬性的使用
屬性(成員變量) vs 局部變量
1.相同點:
1.1 定義變量的格式:數據類型 變量名 = 變量值
1.2 先聲明,后使用
1.3 變量都有其對應的作用域
2.不同點:
2.1 在類中聲明的位置的不同
屬性:直接定義在類的一對{}內
局部變量:聲明在方法內、方法形參、代碼塊內、構造器形參、構造器內部的變量
2.2 關于 權限修飾符 的不同
屬性:可以在聲明屬性時,指明其權限,使用權限修飾符。
常用的權限修飾符:private、public、缺省、protected —>封裝性
目前,大家聲明屬性時,都使用缺省就可以了。
局部變量:不可以使用權限修飾符。
2.3 默認初始化值的情況:
屬性:類的屬性,根據其類型,都有默認初始化值。
整型(byte、short、int、long):0
浮點型(float、double):0.0
字符型(char):0 (或’u0000’)
布爾型(boolean):false
引用數據類型(類、數組、接口):null
局部變量: 沒有默認初始化值。
意味著,我們在調用局部變量之前,一定要顯式賦值。
特別地:形參在調用時,我們賦值即可。
2.4 在內存中加載的位置:
屬性:加載到堆空間中 (非static)
局部變量:加載到棧空間
return關鍵字的作用
1.結束方法
2.(返回數據)針對返回值類型的方法,使用“return 數據”方法返回數據
一,談談你對面向對象中類和對象的理解,并指出二者的關系?
類:對一類事務的描述,是抽象的,概念上的定義
對象:是實際存在的,該類事物的每個個體,因而稱為實例(instance)
面向對象程序設計的重點是類的設計,,設計類,就是設計類的成員
二者的關系:對象是類派生(new)出來的
在開發中,我們跟客戶查詢進行交互,需要提供一個類,這個API給我們提供好了叫Scanner類,這就是類的概念
我們真正執行的時候,我需要創建Scanner的對象,通過這個對象來操作它的功能方法,去完成我們和客戶的交互。
二,面向對象思想的體現一:類和對象的創建和執行操作有哪三步?
①創建類
②類的實例化
③調用對象的結構:“對象.屬性”,“對象.方法”
三,面向對象與面向過程(理解)
1.面向過程:強調的是功能行為,以函數為最小單位,考慮 怎么做
2.面向對象:強調具備了功能的對象,以類/對象為最小單位,考慮 誰來做
四,萬事萬物皆對象
1.在java語言范疇中,我們都將功能,結構等封裝到類中,通過類的實例化,來調用具體的功能結構
2.涉及到java語言與前端html,后端數據庫交互時,前后端的結構在java層面交互時,都體現為類,對象
五,方法 重載 (Overload)
判斷條件:同類同方法名參數列表不同
參數列表值得是(參數的個數/種類 參數的順序)
六,方法的形參的傳遞機制
形參:方法定義時,聲明的小括號內的參數
實參:方法調用時,實際傳遞給形參的數據
值傳遞機制:
如果參數是 基本數據類型 ,此時實參賦給形參的是實參真是存儲的 數據值
如果參數是 引用數據類型 ,此時實參給形參的是實參存儲數據的 地址值
面向對象的特征之一封裝
封裝:
程序設計追求“高內聚,低耦合”
高內聚:類的內部數據操作細節自己完成,不允許外部干涉
低耦合:僅對外暴露少量的方法用于使用
把該隱藏的隱藏起來,該暴露的暴露出來。這就是封裝性的設計思想
封裝性
1.私有的 屬性 ,提供公共的(public)方法來獲取get和設置set
2.不對外暴露的私有 方法
3.單例模式。。。(構造器私有化)
4.如果不希望 類 在包外被調用,可以將類設置為缺省的
封裝性的體現,需要權限修飾符來配合
1.Java規定的4中權限(從小到大排序):private,缺省(default),protected,public
2.4種權限可以用來修飾類及類的內部結構:屬性,方法,構造器,內部類
修飾類的話,只能使用缺省,public
總結:Java提供了4種權限修飾符來修飾類及類的內部結構,體現類及類的內部結構在被調用時的可見性的大小
類的成員之三 構造器
一,構造器(構造方法constructor)的使用: 創建對象,給對象進行初始化
構造器不是方法,它就是創建對象的,獨立的
constructor:建造。construction:CCB constructor:建設者
//創建類的對象: new+構造器
Person p = new Person();
二,說明:
1.如果沒有顯式的定義類的改造器的話,則系統默認提供一個空參的構造器
2.定義構造器的格式:權限修飾符 類型(【參數列表】){}
public Person(){
}
public Person(String name){
}
3一個類中可以有多個構造器,一個類中定義多個構造器,彼此構成重載
4.我們顯式的定義了類的構造器之后,系統就不再提供默認的空構造器
5.一個類中,至少會有一個構造器(擁有創建對象的能力)
總結:屬性賦值的先后順序
- 默認初始化
- 顯式初始化(在屬性的類中)
- 構造器中賦值(有參構造器)
- 通過“對象.方法”或“對象.屬性”的方式,賦值(set方法。。。。)
JavaBean
JavaBean是一種Java語言寫成的可重用的組件
所謂的JavaBean,是指符合以下標準的Java類:
- 類是公共的
- 有一個無慘的公共的構造器
- 有屬性,且有對應的get,set方法
用戶可以使用JavaBean將功能、處理、值、數據庫訪問和其他任何可以用Java代碼創造的對象進行打包,并且其他的開發者可以通過內部的JSP頁面、Servlet、其他JavaBean、applet程序或者應用來使用這些對象。用戶可以認為JavaBean提供了一種隨時隨地的復制和粘貼的功能,而不用關心任何改變。
關鍵字this
1.this可以用來修飾、調用: 屬性、方法、構造器
2.this修飾屬性和方法:
this理解為: 當前對象或當前正在創建的對象
3.this調用構造器
- 我們在類的構造器中,可以顯式的使用"this(形參列表)"方式,調用本類中指定的其他構造器
- 構造器中不能通過"this(形參列表)"方式調用自己
public Person(int age){ this(); //必須放在當前構造器的首行 this.age = age; }
package關鍵字的使用
1.為了更好的實現項目中類的管理,提供包的概念
2.使用package聲明類或接口所屬的包,聲明在原文件的首行
3.包,屬于標識符,遵循標識符的命名規范
注意:同一個包下,不能命名同名的接口,類。
import關鍵字的使用
import:導入
1.在源文件中顯示的使用import結構導入指定包下的類,接口
2.聲明在包的聲明和類的聲明之間
3.同一個包下的類或接口不用import
4.import static :導入指定類或接口中的靜態結構:屬性或方法
MVC設計模式
面向對象的特征之二繼承
一,繼承性的好處
- 減少了代碼的冗余,提高了代碼的復用性
- 便于功能的擴展
- 為之后多態性的使用,提供了前提
二,繼承的格式:class A extends B{}
- A:子類,派生類,subclass
- B:父類,超類,基類,subperclass
體現:子類A繼承父類B,子類A中就獲取了父類B中聲明所有的屬性和方法
私有也會被子類繼承,只是因為權限,子類無法直接訪問。
(兒子繼承了父親的銀行卡,銀行卡是私有屬性,兒子不知道密碼,需要通過父類中的public get()方法獲取,,獲取了父類的所有屬性(包括私有屬性),只是不能直接調用)
一個子類只能有一個父類(java中類的單繼承性),一個父類可以有多個子類
所有的java類(除java.lang.Object類之外)都直接或間接繼承于java.lang.Object類
方法重寫(override/overWrite)
1.重寫:子類繼承父類以后,可以對父類中同名同參數的方法,進行覆蓋操作
2.應用:重寫以后,當創建子類對象以后,通過子類對象調用父類的同名同參的方法時,實際上執行的是子類重寫父類的方法
3.重寫的規定:
- 子類重寫的方法的方法名和形參列表與父類的被重寫的方法名和參數列表相同
- 子類重寫的方法的權限修飾符不小于父類的被重寫的方法的權限修飾符特殊情況:子類不能重寫父類中聲明為private權限的方法(私有方法不能被重寫)
- 返回值類型如果父類是void則子類也要是void;父類是A類型,則子類返回值類型可以是A類型或A的子類
- 子類重寫的方法拋出的異常類型不大于父類被重寫的方法拋出的異常類型
子類和父類的同名同參的方法要么都聲明為非static的(考慮重寫),要么都聲明為static的(不重寫)
方法的重載(overload)和重寫(override)的區別:
在開發中只需要注意:
重載:同一類中同名不同參
重寫:父子類中同名同參
重載參數列表必須不同,重寫參數列表必須相同
關鍵字:super
- super理解為:父類的
- super可以用來調用:屬性,方法,構造器
- super的使用:
3.1 我們可以在子類的方法或構造器中。通過使用"super.屬性或"super.方法"的方式,顯式的調用父類中聲明的屬性或方法。但是,通常情況下,我們習慣省略"super." 3.2特殊情況:當子類和父類中定義了同名的屬性時,我們要想在子類中調用父類中聲明的屬性,則必須顯式的使用"super.屬性"的方式,表明調用的是父類中聲明的屬性。 3.3特殊情況:當子類重寫了父類中的方法以后,我們想在子類的方法中調用父類中被重寫的方法時,則必須顯式的使用"super.方法"的方式,表明調用的是父類中被重寫的方法。 - super調用構造器
4.1我們可以在子類的構造器中顯式的使用"super(形參列表)"的方式,調用父類中聲明的指定的構造器 4.2 "super(形參列表)“的使用,必須聲明在子類構造器的首行! 4.3我們在類的構造器中,針對于”“this(形參列表)“或"super(形參列表)“只能二選一,不能同時出現 4.4在構造器的首行,沒有顯式的聲明"this(形參列表)“或"super(形參列表)””,則默認調用的是父類中空參的構造器:super() 4.5 在類的多個構造器中,至少有一個類的構造器中使用了"super(形參列表)”,調用父類中的構造器
this(形參列表):本類重載的其它的構造器(首行)
super(形參列表):調用父類中指定的構造器(首行 ,默認是super)
子類對象的實例化過程
1.從結果上看:(繼承性)
子類繼承父類后,就獲取了父類中聲明的屬性或方法
創建子類的對象,在堆空間中,就會加載所有父類中聲明的屬性
2.從過程上來看
當我們通過子類的構造器創建子類對象時,我們一定會直接或間接的調用其父類的構造器,進而調用父類的構造器,直到調用了java.lang.Object類中空參的構造器為止,正因為加載過所有的父類的結構,所以才可以看到內存中有父類中的結構,子類對象才可以考慮進行調用。
明確,雖然創建子類對象時,調用了父類的構造器,但是自始至終就創建了一個對象,即為new的子類對象
面向對象特征之三:多態
理解多態性:可以理解為一個事物的多種形態
父類的引用指向子類的對象
多態的使用:當調用子父類同名同參數的方法時,實際執行的是子類重寫父類的方法————虛擬方法調用
虛擬方法調用(多態情況下)
子類中定義了與父類同名同參數的方法,在多態情況下,將此時 父類的方法 稱為 虛擬方法 ,父類根據賦給它的不同子類對象,動態調用屬于子類的該方法。這樣的方法調用在編譯期是無法確定的。(編譯看左,運行看右)
多態是編譯時行為還是運行時行為?
運行時行為
- 有了對象的多態性以后,我們在編譯期,只能調用父類中聲明的方法,但在運行期,我們實際執行的是子類重寫父類的方法
- 總結:編譯看左,運行看右,new誰執行誰
- 多態性使用前提:類的繼承關系,方法的重寫
- 為什么要有多態性?:
- 對象的多態性,只適用于方法,不適用于屬性屬性的值(編譯和運行都看左邊)
談談你對多態性的理解:
1.實現代碼的通用性
2.Object類中定義的public boolean equals(object obj){ }
JDBC:使用java程序操作(獲取數據庫連接、CRUD)數據庫(MySQL、oracle、DB2、sQL Server)
3.抽象類、接口的使用肯定體現了多態性。(抽象類、接口不能實例化)
向上轉型:(引用是父類,對象是子類)-- 多態;
向下轉型:(引用 子類,對象 子類) – 本態,
多態性只針對虛擬方法調用(普通方法)
為什么使用向下轉型:
- 有了對象的多態性以后,內存中實際上是加載了子類特有的屬性和方法,但是由于變量聲明為父類類型,導致編譯時,只能調用父類中聲明的屬性和方法。子類特有的屬性和方法不能調用
- 如何才能調用子類特有的屬性和方法?
- 向下轉型:使用強制類型轉換符
Person p2 = new Man(); //使用強轉時,有可能出現類型轉換異常 Man m1 = (Man)p2;
使用時的注意點:
使用強轉時,可能出現classCastException的異常。
為了避免在向下轉型時出現ClassCastException的異常,我們在向下轉型之前,先進行instanceof的判斷,一旦返回true,就進行向下轉型。如果返回false,不進行向下轉型。
Instanceof關鍵字的使用
a instanceof A:判斷 對象a 是否是 類A 的實例。如果是,返回true;如果不是,返回false。
使用情景:為了避免在向下轉型時出現類型轉換異常,我們在向下轉型之前,先進行instanceof的判斷,一旦返回true,就進行向下轉型。如果返回false,不進行向下轉型。
如果a instanceof A 返回true, 則a instanceof B 也返回true。其只,類B是類A的父類
要求a所屬的類與類A必須是子類和父類的關系,否則編譯錯誤。
1.多態練習——重寫方法
java.lang.object類
1.object類是所有Java類的根父類
2.如果在類的聲明中未使用extends關鍵字指明其父類,則默認父類為java.lang.object類
3.object類中的功能(屬性、方法)就具有通用性。
屬性:無
方法: equals() / tostring() / getclass() /hashcode() / clone() / finalize()
wait() 、 notify( )、notifyAll()
- Object類只聲明了一個空參的構造器
JDK API 1.6
垃圾回收
- 垃圾回收機制只回收VM堆內存里的對象空間。
- 對其他物理連接,比如數據庫連接、輸入流輸出流、Socket連接無能為力
- 現在的JVM有多種垃圾回收實現算法,表現各異。
- 垃圾回收發生具有不可預知性,程序無法精確控制垃圾回收機制執行。
- 可以將對象的引用變量設置為null,暗示垃圾回收機制可以回收該對象。
- 程序員可以通過System.gc()或者Runtime.getRuntime().gc()來通知系統進行垃圾回收,會有一些效果,但是系統是否進行垃圾回收依然不確定。
- 垃圾回收機制回收任何對象 之前 ,總會先調用它的finalize方法(如果覆蓋該方法,讓一個新的引用變量重新引用該對象,則會重新激活對象)。|
- 永遠不要主動調用某個對象的finalize方法,應該交給垃圾回收機制調用。
equals()方法
==與equals()區別?
==運算符
- 可以使用在 基本數據類型 變量和 引用數據類型 變量中
- 如果比較的是基本數據類型變量:比較兩個變量保存的數據是否相等(不一定類型相同)
如果比較的是引用數據類型變量:比較兩個對象的地址值是否相同,即兩個引用是否指向同一個對象實體
equals()方法
- 是一個方法,而非運算符
- 只使用于引用數據類型
- object類中equals()的定義
public boolean equals (Object obi){
return (this == obj);
}
說明: Object類中定義的equals()和==的作用是相同的:比較兩個對象的地址值是否相同.即兩個引用是否指向同一個對象實體
- 像String,Data,File,包裝類等都重寫了Object類中的equals()方法。重寫后,比較的不是兩個引用的地址是否相同,而是比較兩個對象的“實體內容”是否相同
public static void main(String[] args) {
Date data1 = new Date(32432525324L);
Date data2 = new Date(32432525324L);
System.out.println(data1.equals(data2));//true
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2));//true
System.out.println(str1 == str2); //false
}
- 通常情況下,我們自定義的類如果使用equals()的話,也通常是比較兩個對象的“實體內容”是否相同。那么我們就需要對Object類中的equals()方法重寫.重寫的原則:比較兩個對象的實體內容是否相同
toString()
- 當我們輸出一個對象的應用時,實際上就是調用當前對象的toString()方法
- 像String,Date,File,包裝類等都重寫了Object類中的toString()方法使得在調用對象的toString()時,返回“實體內容”信息
- 自定義類也可以重寫toString()方法,當調用此方法時,返回對象的“實體內容”
Java中的JUnit單元測試
步驟;
1.創建Java類,進行單元測試。
此時的Java類要求:
①此類是public的 ②此類提供公共的無參的構造器
2.此類中聲明單元測試方法。
此時的單元測試方法: 方法的權限是public,沒有返回值,沒有形參
3.此單元測試方法上需要聲明注解:@Test,并在單元測試類中導入:import org.junit.Test;
4.聲明好單元測試方法以后,就可以在方法體內測試相關的代碼。
包裝類(Wrapper)的使用
1.java提供了8種基本數據類型對應的包裝類,使得基本數據類型的變量具有類的特征
2.掌握的:基本數據類型、包裝類、String三者之間的相互轉換
基本數據類型—>包裝類:調用包裝類的構造器 (對象參數)
包裝類—>基本數據類型:調用包裝類x×x的x×xValue() (方便做±*/運算)
JDK 5.0新特性:自動裝箱與自動拆箱
基本數據類型、包裝類—>String類型調用String重載的valueOf(Xxx Xxx)
String類型—>基本數據類型、包裝類:調用包裝類的parseXxx(String s)
測試:
三元式中 表達式1和表達式2類型不同時
1.一種類型為char,short,byte,另一種為int常量,而且該常量能被前三種類型表示,則返回的是前三種的類型;
2.若int類型是變量,則會將操作數類型提升,返回類型為類型提升后的類型。
System.out.println(true ? 97 : 'a'); //a
System.out.println(true ? 1 : 2.0); //1.0
System.out.println(true ? 2.0 : 1); //2.0
- Integer內部定義了IntegerCache結構,IntegerCache中定義了Integer[],保存了從-128 ~127 范圍的整數。
- 如果我們使用自動裝箱的方式,給Integer賦值的范圍在 -128~127范圍內時,可以直接使用數組中的元素,不用再去new了。目的:提高效率
1.為什么要有包裝類(封裝類)
為了使基本數據類型的變量具有類的特征,引入包裝類。
static關鍵字的使用
1.static:靜態的
2.static可以來修飾:屬性,方法,代碼塊,內部類
3.使用static修飾屬性:靜態變量
3.1屬性,按是否使用static修飾,又分為:靜態屬性vs非靜態屬性(實例變量)
- 實例變量:我們創建了類的多個對象,每個對象都獨立的擁有一套類中的非靜態屬性。當修改其中一個對象中的非靜態屬性時,不會導致其他對象中同樣的屬性值的修改。
- 靜態變量:我們創建了類的多個對象,多個對象共享同一個靜態變量。當通過某一個對象修改靜態變量時,會導致其他對象調用此靜態變量時,是修改過了的。3.2 static修飾屬性的其他說明:
- 靜態變量隨著類的加載而加載。可以通過"類.靜態變量"的方式進行調用
- 靜態變量的加載要早于對象的創建。
- 由于類只會加載一次,則靜態變量在內存中也只會存在一份: 存在方法區的靜態域中
3.3 靜態屬性舉例:System.out; Math.PI;
4.使用static修飾方法:靜態方法
① 隨著類的加載而加載,可以通過"類.靜態方法"的方式進行調用
②
調用 方法 |
靜態方法 |
非靜態方法 |
類 |
yes |
no |
對象 |
yes |
yes |
③ 靜態方法中,只能調用靜態的方法或屬性
非靜態方法中,既可以調用非靜態的方法或屬性,也可以調用靜態的方法或屬性
- static注意點:5.1 在靜態的方法內,不能使用this關鍵字、super關鍵字5.2 關于靜態屬性和靜態方法的使用,大家都從生命周期的角度去理解。
- 開發中,如何確定一個 屬性 是否要聲明為static的?屬性是可以被多個對象所共享的,不會隨著對象的不同而不同的。類中的常量也常常聲明為static開發中,如何確定一個 方法 是否要聲明為static的?操作靜態屬性的方法,通常設置為static的工具類中的方法,習慣上聲明為static的。 比如:Math、Arrays、Collections
靜態的方法屬性在類加載的時候被創建,靜態的方法可以調用靜態的屬性,
非靜態的方法屬性在對象實例化的時候被創建,可以調用靜態的方法和屬性
設計模式
設計模式是在大量的實踐中總結和理論化之后優選的代碼結構,編碼風格,以及解決問題的思考方式(套路)
單例(Singleton)設計模式
所謂類的單例設計模式,就是采取一定的方法保證在整個的軟件系統中,對 某個類只能存在一個對象實例 。
單例模式的優點:由于單例模式只生成一個實例, 減少了系統性能開銷 。
實現步驟:
1.私有化類的構造器
2.內部創建類的對象,要求此對象也必須聲明為靜態的
3.提供公共的靜態的方法,返回類的對象
根據實例化對象的時刻不同分為:餓漢式和懶漢式
餓漢式:初始化的時候實例化對象
懶漢式:第一次調用的時候創建,((每次被調用先判斷是否nul,如果對象已經被實例化,直接用l))
餓漢式:
好處:線程安全的
壞處:對象加載時間長
懶漢式:
好處:延遲對象的創建
壞處:目前是線程不安全的 ------>到多線程內容,
懶漢式相對好一點,用的時候才被創建,餓漢式不管用不用都在類加載時候創建對象
單例模式設計模式----應用場景
類的成員之四:代碼塊(初始化塊)
- 代碼塊的作用:用來初始化類、對象
- 代碼塊如果有修飾的話,只能使用static.
- 分類:靜態代碼塊 vs 非靜態代碼塊
- 靜態代碼塊內部可以有輸出語句隨著類的加載而 執行 ,而且只執行一次作用:初始化類的信息如果一個類中定義了多個靜態代碼塊,則按照聲明的先后順序執行靜態代碼塊的執行要優先于非靜態代碼塊的執行靜態代碼塊內只能調用靜態的屬性、靜態的方法,不能調用非靜態的結構
- 非靜態代碼塊內部可以有輸出語句隨著對象的創建而 執行
每創建一個對象,就執行一次非靜態代碼塊作用:可以在創建對象時,對對象的屬性等進行初始化如果一個類中定義了多個非靜態代碼塊,則按照聲明的先后順序執行非靜態代碼塊內可以調用靜態的屬性、靜態的方法,或非靜態的屬性,非靜態的方法
總結:有父及子,靜態先行
先執行父類的靜態代碼塊–>直接父類的靜態代碼塊—>本類的靜態代碼塊,然后父類的代碼塊–>父類的無參構造器–>直接父類的代碼塊–>無慘構造器—>本類的代碼塊–>無慘構造器
對屬性可以賦值的位置:
①默認初始化
②顯式初始化
③構造器中初始化
④有了對象以后,可以通過"對象.屬性"或"對象.方法"的方式,進行賦值
⑤在代碼塊中賦值
先后順序:①→②/⑤→③→④
關鍵字:final
final:最終的
- final可以用來修飾的結構:類、方法、變量(屬性,局部變量)
- final 用來修飾一個類:此類不能被其他類所繼承。比如:String類、System類、StringBuffer類(該有的功能都有了,無需擴展功能,不用去繼承,想用就用,不用拉到)
- final 用來修飾方法:表明此方法不可以被 重寫
比如:Object類中getClass(); - final 用來修飾變量:此時的"變量"就稱為是一個常量4.1 final修飾屬性:可以考慮賦值的位置有:顯式初始化、代碼塊中初始化、構造器中初始化4.2 final修飾局部變量:尤其是使用final修飾形參時,表明此形參是一個常量。當我們調用此方法時,給常量形參賦一個實參。一旦賦值以后,就只能在方法體內使用此形參,但不能進行重新賦值。
static final 用來修飾屬性:全局常量
用來修飾方法:直接通過類來調用這個方法不能被重寫
總結:
1.static 修飾的屬性,相較于實例變量,有哪些特別之處(創建,調用,存儲)
- 隨著類的加載而加載;早于對象的創建;
- 只要權限允許,可以通過”對象.static屬性”的方式進行調用;
- 存在于方法區的靜態域
abstract關鍵字的使用
1.abstract:抽象的
2.abstract可以用來修飾的結構:類、方法
3. abstract修飾類: 抽象類
此類不能實例化
抽象類中一定有 構造器 ,便于子類實例化時調用(涉及:子類對象實例化的全過程)
開發中,都會提供抽象類的子類,讓子類對象實例化,完成相關的操作
- abstract修飾方法: 抽象方法
抽象方法只能有方法的聲明,沒有方法體
包含抽象方法的類,一定是一個抽象類。反之,抽象類中可以沒有抽象的方法。
若子類重寫了父類中的所有的抽象方法后,此子類方可實例化
若子類沒有重寫了父類中的所有的抽象方法后,此子類也是抽象類不能被實例化
abstract使用上的 注意點 :
1.abstract不能用來修飾:屬性,構造器等結構
2.abstract不能用來修飾私有方法,靜態方法 ,final的方法,final的類
舉例:父類中有寫功能實在沒有辦法指明,子類反正又要重寫了,就給該功能抽象成抽象方法,把該類設置成抽象類
總結:
抽樣類不能被實例化(只能被繼承),抽樣方法所屬的類一定是抽樣類
繼承抽樣類的子類要不把每個抽樣方法重寫,要不也是一個抽樣類
匿名子類的對象
創建匿名子類的匿名對象
匿名的意義就是只用一次
模板方法設計模式(TemplateMethod)
抽象類體現的就是一種模板模式的設計,抽象類作為多個子類的通用模板,子類在抽象類的基礎上進行擴展、改造,但子類總體上會保留抽象類的行為方式。
- 解決的問題:
當功能內部一部分實現是確定的,一部分實現是不確定的。這時可以
把不確定的部分暴露出去,讓子類去實現。
換句話說,在軟件開發中實現一個算法時,整體步驟很固定、通用,這些步驟已經在父類中寫好了。但是某些部分易變,易變部分可以 抽象 出來,供不同子類實現。這就是一種模板模式。
- 舉例:
/**
* 抽象類的應用,模板方法的設計模式
*/
class templateTest{
public static void main(String[] args) {
SubTemplate subTemplate = new SubTemplate();
subTemplate.spendTime();
}
}
public abstract class Template {
//計算某代碼執行所需要花費的時間
public void spendTime(){
long start = System.currentTimeMillis();
this.code();//不確定的部分,易變得部分
long end = System.currentTimeMillis();
System.out.println();
System.out.println("程序運行花費的時間為:"+(end-start)+"毫秒");
}
public abstract void code();
}
class SubTemplate extends Template{
@Override
public void code() {
for (int i = 2; i < 1000; i++) {
int flag = 0;
for (int j=2;j<=Math.sqrt(i);j++){
if (i%j==0){
flag = 1;
}
}
if (flag==0){
System.out.print(i+" ");
}
}
}
}
接口interface
- 一方面,有時必須從幾個類中派生出一個子類,繼承它們所有的屬性和方法。但是,Java不支持多重繼承。有了接口,就可以得到多重繼承的效果
- 另一方面,有時必須從幾個類中抽取出一些共同的行為特征,而它們之間又沒有is-a的關系,僅僅是具有相同的行為特征而已。例如:鼠標、鍵盤、打印機、掃描儀、攝像頭、充電器、MP3機、手機、數碼相機、移動硬盤等都支持USB連接。
- 接口就是規范,定義的是一組規則,體現了現實世界中“如果你是/要…則必須能…”的思想。繼承是一個"是不是"的關系,而接口實現則是"能不能"的關系。
- 接口的本質是契約,標準,規范,就像我們的法律一樣。制定好后大家都要遵守。
接口的使用:
1.接口使用interface來定義
2.Java中,接口和類是并列的兩個結構
3.如何定義接口:定義接口中的成員
3.1JDK7及以前:只能定義 全局常量 和 抽象方法
>全局常量:public static final的)(可以省略不寫)
>抽象方法:public abstract的
3.2JDK8:除了定義 全局常量 和 抽象方法 之外,還可以定義 靜態方法 、 默認方法(略)
4.接口中不能定義構造器的。意味著接口不可以實例化
5.Java開發中,接口通過讓類去實現(implements)的方法來使用。
如果實現類覆蓋了接口中的所有抽樣方法,則此實現類就可以實例化
如果實現類沒有覆蓋接口中所有的抽象方法,則此實現類仍為一個抽象類
6.Java類可以實現多個接口---->彌補了Java單繼承性的局限性
格式: class AA extends BB implements CC,DD,EE{}
7.接口與接口之間可以繼承,而且可以 多繼承
8.接口的具體使用,體現了 多態性
9.接口,實際上就可以看做一種 規范
10.開發中,體會 面向接口編程 !
接口定義的一種規范,面向接口編程,使得代碼更具有 通用性 或 可移植性
代理模式
代理模式是Java開發中使用較多的一種設計模式。代理設計就是為其他對象提供一種代理以控制對這個對象的訪問。
代理類和被代理類都需要實現這個接口,通過代理類的對象調用實現接口中的抽象方法時,里面包含了被代理對象同名的方法的調用。
工廠模式
1.解決的問題
實現了創建者與調用者的分離,即將創建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。
2.具體模式
簡單工廠模式。用來生產同一等級結構中的任意產品。(對于增加新的產品,需要修改已有代碼)工廠方法模式:用來生產同一等級結構中的固定產品。(支持增加任意產品)
抽象工廠模式。用來生產不同產品族的全部產品。(對于增加新的產品,無能為力﹔支持增加產品族)
3.核心本質:
實例化對象,用工廠方法代替new操作。
將選擇實現類、創建對象統一管理和控制。從而將調用者跟我們的實現類解耦。
Java8中關于接口的改進
Java8新特性
知識點1:接口中定義的靜態方法,只能通過接口來調用
知識點2:通過實現類的對象,可以調用接口中的默認方法
如果實現類重寫了接口中的默認方法,調用時,任然調用的是重寫以后的方法
知識點3:如果子類(或實現類)繼承的父類和實現的接口中聲明了同名同參數的方法,那么子類在沒有重寫此方法的情況下,默認調用的是父類中的同名同參數的方法。------>類優先原則
知識點4:如果實現類實現了多個接口,而這多個接口中定義了同名同參的默認方法,那么在實現類沒有重寫此方法的情況下,報錯。------>接口沖突
這就需要我們必須在實現類中重寫此方法
知識點5:如何在子類(或實現類)的方法中調用父類,接口中被重寫的方法
類的內部成員之五:內部類
- Java中允許將一個類A聲明在另一個類B中,則類A就是內部類,類B就是外部類
- 內部類的分類:成員內部類(靜態,非靜態) 和局部內部類(方法內,代碼塊內,構造器內)
- 成員內部類:一方面,作為外部類的成員;調用外部類的結構可以被static修飾可以被4種不同的權限修飾另一方面,作為一個類:類內可以定義屬性、方法、構造器等可以被final修飾,表示此類不能被繼承。言外之意,不使用final,就可以被繼承可以被abstract修飾關注如下的3個問題4.1 如何實例化成員內部類的對象4.2如何在成員內部類中區分調用外部類的結構4.3 開發中局部內部類的使用
總結
- abstract能修飾哪些結構? 修飾以后,有什么特點?,
類、方法。
類不能實例化,提供子類
抽象方法,只定義了一種功能的標準。具體的執行,需要子類去實現。
- 接口是否能繼承接口?抽象類是否能實現(implements)接口?抽象類是否能繼承非抽象的類?,能,能,能
3. 抽象類和接口有哪些共同點和區別?
抽象類:類中的有的東西它都可以有,還可以有抽象方法
接口:JDK7及以前只能有:全局變量和抽樣方法 JDK8以后可以添加靜態靜態方法和默認方法,JDK9可以定義私有方法。
相同點:不能實例化(都可以包含抽樣方法的),都可以被繼承
不同點:抽象類:有構造器。接口:不能聲明構造器
類:單繼承 接口:多繼承
類與接口:多實現
抽象類和接口 都不能夠實例化 ,但可以定義抽象類和接口類型的 引用 。一個類如果繼承了某個抽象類或者實現了某個接口都需要對其中的抽象方法全部進行實現,否則該類仍然需要被聲明為抽象類。 接口比抽象類更加抽象 ,因為抽象類中可以定義構造器,可以有抽象方法和具體方法,而接口中不能定義構造器而且其中的方法全部都是抽象方法。抽象類中的成員可以是private、默認、protected、public的,而接口中的成員全都是public的。抽象類中可以定義成員變量,而接口中定義的成員變量實際上都是常量。有抽象方法的類必須被聲明為抽象類,而抽象類未必要有抽象方法。