一.抽象類
抽象類的概念:
1衰抑、Java中可以定義沒有方法體的方法,還方法的具體實(shí)現(xiàn)由子類完成荧嵌,該方法稱為抽象方法呛踊,包含抽象方法的類就是抽象類;
2啦撮、如谭网,shape類計(jì)算周長和面積的方法無法確定,那么就可以將這樣的方法聲明為抽象的赃春,以便在具體的子類中實(shí)現(xiàn)
3.抽象類也叫做抽象基類愉择,抽象類是基礎(chǔ)類和接口中間的一個(gè)中庸之道,即有基礎(chǔ)類特性(已實(shí)現(xiàn)的方法體),又有接口特性(抽象方法)锥涕,抽象類用abstract修飾衷戈,抽象類中可以有抽象方法也用abstract來修飾。
抽象類的特征:
抽象方法的聲明
修飾符abstract 返回值類型 方法名([參數(shù)列表])层坠;
注意:因?yàn)槌橄蠓椒o法確定具體執(zhí)行的功能殖妇,所以抽象方法沒有方法體,需要在小括號后加上分號
抽象類的聲明
語法:修飾符 abstract class 類名 extends 父類名
抽象類和普通類除了使用abstract修飾外和普通的類相似破花;
抽象類中可以沒有抽象方法谦趣;但是一旦某個(gè)有抽象方法,那么這個(gè)類必須被聲明為抽象類
static final private不能和abstract共存
抽象類的使用:
因?yàn)槌橄箢惒皇且粋€(gè)具體的類座每,所以無法實(shí)例化蔚润,但是抽象類可以用于聲明變量;
抽象類可以被繼承尺栖,在子類中實(shí)現(xiàn)所有抽象類的所有抽象方法,以達(dá)到抽象類的具體化烦租;
注意:因?yàn)槌橄蠓椒o法確定具體執(zhí)行的功能延赌,所有抽象方法沒有方法體,需要在小括號后加上分號叉橱;
抽象方法:不允許包含方法體挫以;子類中需要重寫父類的抽象方法,否則窃祝,子類也是抽象類
格式:
public abstract void eat()掐松;
抽象方法:java 中可以定義一些不含方法體的方法,它的方法體的實(shí)現(xiàn)交給該類的子類根據(jù)自己的情況去實(shí)現(xiàn)粪小。 抽象類:包含抽象方法的類叫抽象類大磺。一個(gè)抽象類可以有一個(gè)或多個(gè)抽象方法。
抽象類必須使用abstract修飾符來定義探膊,抽象方法也必須用abstract來修飾杠愧。 抽象類不能被實(shí)例化,不能用new關(guān)鍵字去產(chǎn)生對象逞壁。 抽象方法只能聲明流济,不能實(shí)現(xiàn)。 含有抽象方法的類必須被聲明為抽象類,抽象類的子類必須覆蓋所有的抽象方法后才能被實(shí)例化腌闯,否則這個(gè)子類還是個(gè)抽象類绳瘟。
二. 接口
接口的概念:
接口為我們提供了一種將接口與實(shí)現(xiàn)分離的更加結(jié)構(gòu)化的方法。接口是一個(gè)完全的抽象類姿骏,它沒有提供任何形式的具體實(shí)現(xiàn)糖声,它允許創(chuàng)建者確定方法名,參數(shù)類表,返回類型沒有任何方法體的方法姨丈。
接口被用來建立類與類之間的協(xié)議畅卓。接口類修飾符必須是public,default(默認(rèn)的蟋恬,本包內(nèi)有訪問權(quán)限)或者前邊兩個(gè)和abstract組合翁潘,接口也可以包含域,但是這些域隱士地是public static final類型的歼争,所有接口域必須初始化值拜马。接口中方法默認(rèn)訪問級別都是public,如果定義訪問級別小于public沐绒,編譯將不能通過俩莽。
接口是用來實(shí)現(xiàn)類間多重繼承功能的結(jié)構(gòu). 接口不能實(shí)例化,即不能用new運(yùn)算符創(chuàng)建對象乔遮。 一個(gè)類通過使用關(guān)鍵字implements聲明自己實(shí)現(xiàn)一個(gè)或多個(gè)接口扮超。 在類體中可以使用接口中定義的常量,而且必須實(shí)現(xiàn)接口中定義的所有方法 接口中的方法是自動(dòng)公有的蹋肮,在實(shí)現(xiàn)接口時(shí)必須把方法聲明為public 出刷。接口中的方法都是抽象的。
一個(gè)接口可以繼承另一個(gè)接口坯辩。
任何類(包括普通類馁龟,內(nèi)部類,抽象類)可以實(shí)現(xiàn)一個(gè)接口漆魔。
接口的特征:
在Java中接口不僅僅是程序開發(fā)過程中“約定”坷檩,更是更加抽象化的抽象類
無法歸納到一個(gè)類的但某些特征相同
語法:
修飾符 interface 接口名{[常量];[抽象方法]改抡;}
接口中抽象方法可以不寫abstract關(guān)鍵字矢炼,訪問修飾符默認(rèn)public
當(dāng)類實(shí)現(xiàn)接口時(shí),需要去實(shí)現(xiàn)接口中的所有抽象方法雀摘,否則需要將該類設(shè)置為抽象類裸删;
接口中可以包含常量,默認(rèn)public static final
接口也可以實(shí)現(xiàn)繼承阵赠,并且可以繼承多個(gè)父接口
接口的作用:
提高程序的重用性涯塔;提高程序的可擴(kuò)展性;降低程序的耦合度清蚀;實(shí)現(xiàn)了多繼承 匕荸。
default:默認(rèn)方法 可以帶方法體 jdk1.8后新增;可以在實(shí)現(xiàn)類中重寫枷邪,并且可以通過接口的引用調(diào)用
static:靜態(tài)方法 可以帶方法體 jdk1.8后新增榛搔;不可以在實(shí)現(xiàn)類中重寫,可以通過接口名調(diào)用
三.內(nèi)部類
什么是內(nèi)部類? 在Java中践惑,可以將類定義在另一個(gè)類里面或者一個(gè)方法里面腹泌,這樣的類稱為內(nèi)部類
定義:
在一個(gè)類內(nèi)部定義類
內(nèi)部類的寫法:class 類名{ } 它可以直接訪問和引用他的外部類的所有變量和方法,與外部類相比尔觉,內(nèi)部類可以聲明為private或protected.
用static修飾一個(gè)內(nèi)部類時(shí)(嵌套類)凉袱,這個(gè)類相當(dāng)于是一個(gè)外部定義的類,所以static的內(nèi)部類中可聲明static成員 static內(nèi)部類不能使用外部類的非static成員變量
函數(shù)的局部變量(形參也是局部變量)侦铜,內(nèi)部類的成員變量专甩,外部類的成員變量重名,用以下方式來明確指定我們真正要訪問的變量钉稍。
<pre spellcheck="false"
class="md-fences md-end-block ty-contain-cm modeLoaded"
lang="java" cid="n311"
mdtype="fences"
style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
public class Outer {
private int size;
class Inner {
private int size;
public void doStuff(int size) {
size++; // 引用的是doStuff函數(shù)的形參
this.size++; // 引用的是Inner類中的成員變量
Outer.this.size++; // 引用的Outer類中的成員變量
}
}
}</pre>
方法中定義內(nèi)部類涤躲?
內(nèi)部類并非只能在類里定義,也可以在幾個(gè)程序塊的范圍之內(nèi)定義內(nèi)部類贡未。例如在方法或for循環(huán)體內(nèi)部种樱,均可以. 在方法中定義的內(nèi)部類只能訪問方法中的final類型的局部變量。
<pre spellcheck="false"
class="md-fences md-end-block ty-contain-cm modeLoaded"
lang="java" cid="n362"
mdtype="fences"
style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
public void testClassInMethod(final String arg) {
class ClassInMethod {
void test() {
System.out.println(arg);
}
}
}</pre>
內(nèi)部類如何被外部類引用俊卤?
內(nèi)部類可以通過創(chuàng)建對象從外部類之外被調(diào)用缸托,只要將內(nèi)部類聲明為public
<pre spellcheck="false"
class="md-fences md-end-block ty-contain-cm modeLoaded"
lang="java" cid="n330"
mdtype="fences"
style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class Outer {
private int size;
class Inner {
private int size;
public void doStuff(int size) {
size++; // 引用的是doStuff函數(shù)的形參
this.size++; // 引用的是Inner類中的成員變量
Outer.this.size++; // 引用的Outer類中的成員變量
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.doStuff(1);
}
}</pre>
內(nèi)部```類分類:
成員內(nèi)部類:將一個(gè)類定義在另一個(gè)類的成員位置; 獲取內(nèi)部類對象實(shí)例瘾蛋,
方式1:new外部類.new 內(nèi)部類
方式2:外部類對象.new 內(nèi)部類
方式3:外部類對象.獲取方法
1、內(nèi)部類在外部使用時(shí)矫限,無法直接實(shí)例化哺哼,需要借由外部類信息才能完成實(shí)例化;
2叼风、內(nèi)部類的訪問修飾符取董,可以任意,但是訪問范圍會(huì)受到影響无宿;
3茵汰、內(nèi)部類可以直接訪問外部類的成員;如果出現(xiàn)同名屬性孽鸡。優(yōu)先訪問內(nèi)部類中定義的蹂午;
4、可以使用外部類.this成員的方式彬碱,訪問外部類中同名的信息豆胸;
5、外部類訪問內(nèi)部類信息巷疼,需要通過內(nèi)部類實(shí)例晚胡,無法直接訪問;
6、內(nèi)部類編譯后.class文件命名:外部類$內(nèi)部類.class估盘;
7瓷患、內(nèi)部類中是否可以包含與外部類相同方法簽名的方法
局部內(nèi)部類:
將一個(gè)類定義在另一個(gè)類的方法體中或者代碼塊中;
1遣妥、定義在方法內(nèi)部擅编,作用范圍也在范圍內(nèi)
2、和方法內(nèi)部成員使用規(guī)則以用燥透,class前面不可以添加public沙咏、private、protected班套、static
3肢藐、類中不能包含靜態(tài)成員
4、類中可以包含final吱韭,abstract修飾的成員
靜態(tài)內(nèi)部類:
將一個(gè)類定義在另一個(gè)類的成員位置吆豹,并且static修飾符;
1理盆、靜態(tài)內(nèi)部類中痘煤,只能直接訪問外部類的靜態(tài)成員,如果需要調(diào)用非靜態(tài)成員猿规,可以通過對象實(shí)例
2衷快、靜態(tài)內(nèi)部類對象實(shí)例時(shí),可以不依賴于外部類對象
3姨俩、可以通過外部類.內(nèi)部類.靜態(tài)成員的方式蘸拔,訪問內(nèi)部類中的靜態(tài)成員
4、當(dāng)內(nèi)部類屬性與外部類屬性同名時(shí)环葵,默認(rèn)調(diào)用內(nèi)部類中的成員调窍;如果需要訪問外部類中的靜態(tài)屬性,則可以通過外部類.屬性的方式张遭;如果需要訪問外部類中的非靜態(tài)屬性邓萨,則可以通過new外部類().屬性的方式
匿名內(nèi)部類:
匿名內(nèi)部類沒有名字
只需要為局部內(nèi)部類建立一個(gè)對象,不必為該類指定一個(gè)名字菊卷。
<pre spellcheck="false"
class="md-fences md-end-block ty-contain-cm modeLoaded"
lang="java" cid="n293"
mdtype="fences"
style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
public Inner testAnonyClassInMethod() {
return new Inner() { // 此處為一個(gè)匿名類定義缔恳,沒有類名,意思為創(chuàng)建一個(gè)繼承自Inner內(nèi)部類的對象
?
@Override
public void doStuff(int size) {
super.doStuff(size);
}
};
}</pre>
1洁闰、匿名內(nèi)部類沒有類型名稱褐耳、實(shí)例對象名稱
2、編譯后的文件命名:外部類$數(shù)字.class
3渴庆、無法使用private铃芦、public雅镊、protected、abstract刃滓、static修飾
4仁烹、無法編寫構(gòu)造方法,可以添加構(gòu)造代碼塊
5咧虎、不能出現(xiàn)靜態(tài)成員
6卓缰、匿名內(nèi)部類可以實(shí)現(xiàn)接口也可以繼承父類,但是不能兼得
抽象類和接口的區(qū)別與聯(lián)系?
一個(gè)類可以實(shí)現(xiàn)多個(gè)接口砰诵, 而一個(gè)類只能繼承一個(gè)抽象類征唬。 接口只定義方法,實(shí)現(xiàn)一個(gè)接口就是要實(shí)現(xiàn)接口的所有方法茁彭。而抽象類可以實(shí)現(xiàn)部分方法总寒。 多個(gè)無關(guān)的類可以實(shí)現(xiàn)同一個(gè)接口,一個(gè)類可以實(shí)現(xiàn)多個(gè)無關(guān)的接口