一闭树、abstract(抽象的)
1. abstract可以用于修飾類
被abstract修飾的類稱為<font color="red">抽象類
abstract class 類名{}
抽象類編譯之后會(huì)生成獨(dú)立的.class 文件
抽象類不能單獨(dú)創(chuàng)建對(duì)象(即不能 new 對(duì)象)耸棒,但是可以聲明抽象類類型的引用 (簡(jiǎn)稱:可以聲明引用)
抽象中可以定義成員變量和成員方法
抽象類中有構(gòu)造方法,但是抽象類中構(gòu)造方法不再是用于new 對(duì)象报辱,而是供子類創(chuàng)建對(duì)象時(shí)与殃,JVM默認(rèn)創(chuàng)建一個(gè)父類對(duì)象時(shí)應(yīng)用。
2. abstract可以用于修飾方法
被 abstract 修飾的方法稱為<font color="red">抽象方法
-
抽象方法只有聲明部分碍现,沒有方法實(shí)現(xiàn)部分(即沒有 { })幅疼,以英文分號(hào)結(jié)尾
語法:
訪問修飾符 abstract 返回值類型 方法名(形參列表);
注意:訪問修飾符和abstract沒有先后位置
抽象方法只能定義在抽象類中;但是抽象類中既可以定義抽象方法昼接,也可以定義非抽象方法爽篷。
3. 抽象類的子類
如果一個(gè)類繼承抽象類,此類為抽象類的子類;
如果子類不想定義為抽象類慢睡,必須覆蓋父類中所有的抽象方法狼忱,否則子類必須定義抽象類;
抽象類類名 引用名 = new 子類類名(形參)
public class TestAbstract{
public static void main(String[] args){
MyClassmc ;
mc=new Sub(); // 強(qiáng)制使用多態(tài)
mc.m1();
mc.m2();
mc.m3();
}
}
//抽象類
abstract class MyClass{
inta; // 屬性
public void m1(){
System.out.println("m1()...");
}
public abstract void m2();
abstract public void m3();
}
// 子類
class Sub extends MyClass{
public void m2(){
System.out.println("m2()實(shí)現(xiàn)內(nèi)容...");
}
public void m3(){
System.out.println("m3()...實(shí)現(xiàn)內(nèi)容.../");
}
}
4. 抽象類強(qiáng)制使用多態(tài)
5. 抽象類的應(yīng)用場(chǎng)景:【理解】
通常將一些父類定義為抽象類 具有某一類事物的特性和行為一睁,但是不具有具體的執(zhí)行功能(實(shí)現(xiàn))钻弄。例如:動(dòng)物類、圖形類等者吁。
-
依賴倒轉(zhuǎn)原則 當(dāng)一個(gè)類和另一類建立關(guān)聯(lián)時(shí)窘俺,盡可能避開直接和子類建立關(guān)系,而是與其父類建立聯(lián)系。
a. 降低程序之間的耦合度瘤泪,從而實(shí)現(xiàn)弱耦合灶泵。
b. 提高代碼的可維護(hù)性
二、static (靜態(tài)的)
1. static可以修飾屬性
被 static 修飾的屬性稱為<font color="red">靜態(tài)屬性对途、靜態(tài)變量赦邻、類變量
-
語法:
訪問修飾符 static 數(shù)據(jù)類型 變量名;
訪問修飾符 static 數(shù)據(jù)類型 變量名 = 值;
- 注意:訪問修飾符和static沒有位置先后实檀。
-
特點(diǎn) 靜態(tài)變量/靜態(tài)屬性/類變量是依賴于類的變量惶洲,和創(chuàng)建多少對(duì)象沒有關(guān)系,被每一個(gè)對(duì)象共享膳犹。
注意:實(shí)例變量(非靜態(tài)變量)每一個(gè)對(duì)象獨(dú)有一份靜態(tài)變量讓每一個(gè)對(duì)象共享
-
使用
a. 引用名.靜態(tài)屬性名
b. 類名.靜態(tài)屬性名
-
內(nèi)存分析如下: static內(nèi)存分析圖
案例
public class TestMyClass2{
public static void main(String[] args){
MyClassmc1=newMyClass();
MyClass mc2 = new MyClass();
mc1.value=20;
mc1.m=3;
System.out.println("mc1.value="+mc1.value)//20
System.out.println("mc1.m="+mc1.m);// 3
System.out.println("mc2.value="+mc2.value)//10
System.out.println("mc2.m="+mc2.m);// 3
MyClassmc3=newMyClass();
System.out.println("mc3.m="+mc3.m);
mc3.m=100;
System.out.println(mc2.m); // 100
System.out.println(MyClass.m);//100
}
}
class MyClass{
int value = 10;
static int m ;// 靜態(tài)屬性恬吕、靜態(tài)變量、類變量
static int n;
}
2. static 可以修飾成員方法
被 static 修飾的方法稱為<font color="red">靜態(tài)方法
-
語法:
訪問修飾符 static 返回值類型 方法名(形參列表){}
注意:訪問修飾符和 static 沒有位置的先后順序须床。
-
使用
a. 類名.靜態(tài)方法名(實(shí)參); --->建議
b.對(duì)象名.靜態(tài)方法名(實(shí)參);
-
注意事項(xiàng)
a. 靜態(tài)方法中不能直接訪問本類的非靜態(tài)成員(實(shí)例變量+成員方法)
b. 靜態(tài)方法中可以直接訪問本類的靜態(tài)成員(靜態(tài)變量+靜態(tài)方法)
c. 非靜態(tài)方法中既可以直接訪問本類非靜態(tài)的成員铐料,也可以直接訪問本類的靜態(tài)成員。
d. 靜態(tài)方法中不能使用 this 和super 關(guān)鍵字
e. 父類中的靜態(tài)方法可以被子類繼承子類類名.父類靜態(tài)方法名(實(shí)參);
f. 如果子類覆蓋父類中的靜態(tài)方法豺旬,則子類覆蓋的方法也必須是靜態(tài)的(靜態(tài)方法只能被靜態(tài)方法覆蓋)钠惩;以父類型的引用調(diào)用靜態(tài)方法,直接訪問父類中靜態(tài)方法族阅,沒有體現(xiàn)多態(tài)的覆蓋結(jié)果妻柒。
應(yīng)用場(chǎng)景 為了方便調(diào)用,通常將工具類中方法定義為靜態(tài)方法耘分。 例如:
java.util.Arrays.sort(數(shù)組名);
思考: System.out.println(); 實(shí)現(xiàn)原理举塔?
System : 類(位于 java.lang中的)
out: System類中被 static 修飾的靜態(tài)屬性,引用
println:out數(shù)據(jù)類型中方法求泰。
public class Test2{
public static void main(String[] args){
System.out.println("實(shí)現(xiàn)原理...");
A.b.method();
}
}
// 類
classA{
static Bb = newB();//自定義類型的關(guān)系屬性
}
// 類
classB{
public void method(){}
}
3. static 可以修飾初始化代碼塊
-
初始化代碼:也稱為動(dòng)態(tài)代碼塊【了解】
定義在類以內(nèi)央渣,方法以外的 {}
-
作用:創(chuàng)建對(duì)象時(shí),按照和屬性(實(shí)例變量)定義的先后順序完成對(duì)屬性初始化工作渴频。 在這里插入圖片描述
-
靜態(tài)初始化代碼塊【重點(diǎn)】
定義在類以內(nèi)芽丹,方法以外,被 static 修飾的 {}
static{}
作用 在類加載的時(shí)候卜朗,按照和靜態(tài)屬性定義的先后順序完成靜態(tài)屬性的初始化工作拔第。
-
類加載
概念 JVM第一次使用一個(gè)類的時(shí)候,通過classPath(類路徑)找到所需要的類對(duì)應(yīng)的 .class 文件场钉,讀取并獲取類對(duì)應(yīng)信息(包名蚊俺、類名、屬性逛万、構(gòu)造方法泳猬、成員方法、父類等信息),將類的信息保存到JVM內(nèi)存中得封,一個(gè)類類加載進(jìn)行一次埋心。
-
第一次使用一個(gè)類
a. 第一次調(diào)用類中靜態(tài)成員(靜態(tài)屬性和靜態(tài)方法)
b. 第一次創(chuàng)建一個(gè)類的對(duì)象:先進(jìn)行類加載,再完成對(duì)象的創(chuàng)建忙上;
c. 子類類加載會(huì)先導(dǎo)致其父類進(jìn)行類加載注意:只是聲明引用拷呆,不會(huì)導(dǎo)致類加載。
-
類加載的時(shí)機(jī)
創(chuàng)建對(duì)象
創(chuàng)建子類對(duì)象加載父類
訪問靜態(tài)屬性
訪問靜態(tài)方法
Class.forName("全限定名");
擴(kuò)充內(nèi)容
選擇性的理解
第一次使用子類的靜態(tài)成員(靜態(tài)屬性和靜態(tài)方法)
第一次創(chuàng)建子類對(duì)象時(shí): 先加載:先加載父類疫粥,再子類 再完成對(duì)象的創(chuàng)建: new --> 分配空間 執(zhí)行子類的構(gòu)造方法
-
帶有類加載創(chuàng)建對(duì)象的過程:
-
a. 先類加載
先加載父類父類靜態(tài)屬性完成初始化(父類的靜態(tài)代碼塊)
再加載子類 子類靜態(tài)屬性完成初始化(子類的靜態(tài)代碼塊)
-
b. 再創(chuàng)建對(duì)象: 執(zhí)行子類構(gòu)造方法第一行遇到super()茬斧,代表先完成父類對(duì)象的創(chuàng)建
-
先完成父類對(duì)象的創(chuàng)建:
執(zhí)行父類屬性初始化內(nèi)容(父類屬性賦值語句+動(dòng)態(tài)代碼塊)--
父類構(gòu)造方法中的內(nèi)容
-
再完成子類對(duì)象的創(chuàng)建:
-
執(zhí)行子類屬性初始化內(nèi)容(子類屬性賦值語句+動(dòng)態(tài)代碼塊)
- 子類構(gòu)造方法中內(nèi)容
-
-
-
三、final(最終的手形,最后的)
1.final可以修飾變量
成員變量、局部變量
final修飾的變量是作用范圍內(nèi)的常量悯恍,只允許一次賦值库糠,不允許修改
注意:final修飾的變量,通常以全大寫字母作為名
//局部變量
main(){
final int A=5;//局部變量
}
final修飾的實(shí)例變量涮毫,jvm虛擬機(jī)不再分配默認(rèn)值
-
final修飾的實(shí)例變量初始化的位置:
在聲明同時(shí)初始化
可以在構(gòu)造方法中對(duì)其初始化瞬欧,但是必須保證每一個(gè)構(gòu)造方法都必須初始化
//實(shí)例變量
main(){
}
class class1{
//實(shí)例變量
final int a=1;//在聲明時(shí)初始化
public class1(){
a=2;//可以在構(gòu)造方法中對(duì)其初始化
}
}
final修飾靜態(tài)變量,jvm不再分配默認(rèn)值
-
final修飾的靜態(tài)變量初始化的位置:
聲明時(shí)為其初始化
可以在靜態(tài)代碼塊中完成對(duì)其初始化
//3)靜態(tài)變量罢防、靜態(tài)屬性艘虎、類變量
main(){
}
class class2{
final static int a=1;//聲明時(shí)初始化
}
//靜態(tài)代碼塊
static{
a=2;//在靜態(tài)代碼塊中進(jìn)行初始化
}
- 如果引用被final修飾,代表引用中存儲(chǔ)的對(duì)象地址不可以改變咒吐,但是可以通過引用對(duì)象中的屬性進(jìn)行改變
//引用被final修飾
main(){
final MyClass mc=new MyClass();//引用中存儲(chǔ)的地址不允許改變
mc.a=5;
sout(mc.a);
}
class MyClass{
int a;
}
2.final可以修飾方法
- final修飾的方法可以被子類繼承野建,不允許被子類覆蓋
main(){
}
class class1{
public final void m1(){
sout("m1方法");
}
}
class class2 extends class1{//編譯不通過,final修飾的方法不允許被子類覆蓋
public final void m1(){
sout("子類中m1方法");
}
}
3.final可以修飾類
- final修飾的類不允許被繼承
main(){
}
final class class1{
public final void m1(){
sout("m1方法");
}
}
class class2 extends class1{//編譯出錯(cuò)恬叹,final修飾的類不允許被繼承
}
總結(jié)
abstract候生、static、final可以修飾的內(nèi)容
abstract 可以修飾類和方法
static可以修飾屬性绽昼、方法和靜態(tài)代碼塊
final可以修飾變量(局部變量唯鸭、實(shí)例變量、靜態(tài)變量)硅确、方法和類
abstract目溉、static、final是否可以修飾構(gòu)造方法菱农?
abstract:抽象方法只能有方法的聲明缭付,沒有方法實(shí)現(xiàn),實(shí)現(xiàn)部分(構(gòu)造方法)讓子類完成; 但是構(gòu)造方法不能被子類繼承循未,如果構(gòu)造方法被abstract修飾蛉腌,則子類無法完成構(gòu)造方法的實(shí)現(xiàn)內(nèi)容。
static:無法修飾構(gòu)造方法,static和對(duì)象沒有關(guān)系烙丛,但是構(gòu)造方法是用于創(chuàng)建對(duì)象的舅巷,相互矛盾; 同時(shí)static修飾的方法可以直接通過 類名.靜態(tài)方法名(實(shí)參)河咽; 但是構(gòu)造方法不允許手動(dòng)調(diào)用
final:final方法是約束子類不能覆蓋钠右,但是構(gòu)造方法本身就不允許子類繼承,談不上覆蓋忘蟹。
private飒房、abstract、static媚值、final是否可以聯(lián)合修飾成員方法狠毯?
private和abstract private修飾的方法不能被子類繼承,abstract修飾的方法需要通過子類覆蓋給予方法的實(shí)現(xiàn)部分褥芒,聯(lián)合修飾一個(gè)成員方法嚼松,矛盾;
static和abstract static修飾方法可以直接通過類名調(diào)用锰扶,如果通過類名調(diào)用的是一個(gè)抽象方法(半成品)献酗,jvm無法執(zhí)行,不能聯(lián)合修飾一個(gè)成員方法坷牛;
final和abstract final修飾的方法可以被子類繼承罕偎,但是不允許被覆蓋; 而abstract修飾的方法的實(shí)現(xiàn)需要通過子類覆蓋時(shí)給予實(shí)現(xiàn)京闰,所以不能聯(lián)合使用颜及。
private、static蹂楣、final可以聯(lián)合使用器予。
一個(gè)方法中必須而且只能有一個(gè)訪問修飾符
- private、default捐迫、protected乾翔、public
整理不易,喜歡請(qǐng)點(diǎn)個(gè)贊施戴!
編者微信:1014961803反浓,添加時(shí)請(qǐng)備注"CSDN"