8--黑馬程式設計師---技術總結之抽象類、內部類
、期待與您交流! ----------------------
一.抽象類
1.抽象類的概念
在面向物件的概念中,所有的物件都是通過類來描繪的,但是反過來,並不是所有的類都是用來描繪物件的,如果一個類中沒有
包含足夠的資訊來描繪一個具體的物件,這樣的類就是抽象類。
抽象類往往用來表徵對問題領域進行分析、設計中得出的抽象概念,是對一系列看上去不同,但是本質上相同的具體概念的抽象。
比如,在一個圖形編輯軟體的分析設計過程中,就會發現問題領域存在著圓、三角形這樣一些具體概念,它們是不同的,但是它
們又都屬於形狀這樣一個概念,形狀這個概念在問題領域並不是直接存在的,它就是一個抽象概念。而正是因為抽象的概念在問題領
域沒有對應的具體概念,所以用以表徵抽象概念的抽象類是不能夠例項化的。通常在程式設計語句中用abstract修飾的類是抽象類。在
Java中,含有抽象方法的類稱為抽象類,不能用來生成物件。抽象類是不完整的,它只能用作基類。在面向物件方法中,抽象類主要
用來進行型別隱藏和充當全域性變數的角色。
抽象類的宣告格式為
abstract class A {
···
}
2.抽象類的特點
1)abstract類中可以有abstract方法
與普通的類相比,abstract類可以有abstract方法。對於abstract方法,只允許宣告,不允許實現,而且不允許使用final修飾abstract方
法。下面的AbstractDemo1類中的min()方法是abstract方法。
- abstract class AbstractDemo1 {
- abstract int min(int x,int y); //抽象方法不允許實現
-
int max(int x,int y) { //非抽象方法必須實現
- return x>y?x:y;
- }
- }
注意:abstract類也可以沒有abstract方法。
2)abstract類不能用new運算子建立物件
對於abstract類,不能使用new運算子建立該類的物件,需產生其子類,由子類建立物件,如果一個類是abstract類的子類,它必須具體實現父類的abstract方法,這就是為什麼不允許使用final修飾abstract方法的原因。在下面的程式碼示例,使用了abstract類。
-
<
- /**使用抽象類,併為之建立物件,呼叫其抽象方法
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- A a; //A a = new A();是非法的,因為abstract類不能用new運算子建立物件
- B b = new B();
- int max = b.max(12, 13); //呼叫最大值方法算最大值
- int min = b.min(12, 13); //呼叫最小值方法算最小值
- System.out.println("12和13的最大值是" + max); //輸出結果是:12和13的最大值是13
- System.out.println("12和13的最小值是" + min); //輸出結果是:12和13的最小值是12
- }
- }
- abstract class A {
- abstract int min(int x, int y); //定義抽象方法算最小值
- int max(int x, int y) { //定義抽象方法算最大值
- return x > y ? x : y; //返回最大值
- }
- }
- class B extends A {
- int min(int x, int y) { //abstract方法必須實現
- return x <y ? x : y; //返回最小值
- }
- }</span>
在下面的程式碼示例中,有一個abstract的“圖形”類,圖形類要求其子類都必須有具有計算面積的功能。
- public class AbstractDemo3 {
- /**建立一個abstract的圖形類,要求子類必須具有計算面積的功能
- * @黑馬ZWF
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- 梯形 t = new 梯形(2.0, 5.2, 12.3);
- 圓 y = new 圓(5.6);
- System.out.println("該梯形的面積是:" + t.求面積()); //輸出結果是:該梯形的面積是:44.28
- System.out.println("該圓的面積是:" + y.求面積()); //輸出結果是:該圓的面積是:98.52034561375999
- }
- }
- abstract class 圖形 { //定義抽象類
- public abstract double 求面積(); //定義抽象方法求面積();這樣可以要求子類必須實現
- }
- class 梯形 extends 圖形 { //定義梯形類繼承圖形類
- double a, b, h;
- 梯形(double a, double b, double h){
- this.a = a;
- this.b = b;
- this.h = h;
- }
- public double 求面積() { //實現圖形的抽象方法
- return ((1/2.0) * (a + b) * h);
- }
- }
- class 圓 extends 圖形 { //定義圓類繼承圖形類
- double r;
- final double PI = 3.1415926535;
- 圓(double r) {
- this.r = r;
- }
- public double 求面積() { //實現圖形的抽象方法
- return PI * r * r;
- }
- }
3.比較區別
與具體類比較
1)抽象類不能直接例項化,並且對抽象類使用new運算子會導致編譯時錯誤。雖然一些變數和值在編譯時的型別可以是抽象的,但是這樣的變數和值必須或者為 null,或者含有對非抽象類的例項的引用(此非抽象類是從抽象類派生的)。
2)允許(但不要求)抽象類包含抽象成員。
3)抽象類不能被密封。
與介面比較
抽象類表示該類中可能已經有一些方法的具體定義,但是介面就僅僅只能定義各個方法的介面(方法名,引數列表,返回型別),並不關心具體細節。
介面是引用型別的,和抽象類的相似之處有三點:
1)不能例項化;
2)包含未實現的方法宣告;
3)派生類必須實現未實現的方法,抽象類是抽象方法,介面則是所有成員(不僅是方法包括其他成員)。
抽象類與介面緊密相關。然而介面又比抽象類更抽象,這主要體現在它們的差別上:
1)類可以實現無限個介面,但僅能從一個抽象(或任何其他型別)類繼承,從抽象類派生的類仍可實現介面,從而得出介面是用來解決多重繼承問題的。
2)抽象類當中可以存在非抽象的方法,可介面不能,且它裡面的方法只是一個宣告必須用public來修飾沒有具體實現的方法。
3)抽象類中的成員變數可以被不同的修飾符來修飾,可介面中的成員變數預設的都是靜態常量(static final)。
4)抽象類是物件的抽象,然而介面是一種行為規範。
抽象類裡面可以有非抽象方法但接口裡只能有抽象方法 宣告方法的存在而不去實現它的類被叫做抽像類(abstract class),它用於要建立一個體現某些基本行為的類,併為該類宣告方法,但不能在該類中實現該類的情況。不能建立abstract 類的例項。然而可以建立一個變數,其型別是一個抽像類,並讓它指向具體子類的一個例項。不能有抽像建構函式或抽像靜態方法。Abstract 類的子類為它們父類中的所有抽像方法提供實現,否則它們也是抽像類為。取而代之,在子類中實現該方法。知道其行為的其它類可以在類中實現這些方法。介面(interface)是抽像類的變體。在介面中,所有方法都是抽像的。多繼承性可通過實現這樣的介面而獲得。介面中的所有方法都是抽像的,沒有一個有程式體。介面只可以定義static
final成員變數。介面的實現與子類相似,除了該實現類不能從介面定義中繼承行為。當類實現特殊介面時,它定義(即將程式體給予)所有這種介面的方法。然後,它可以在實現了該介面的類的任何對像上呼叫介面的方法。由於有抽像類,它允許使用介面名作為引用變數的型別。通常的動態聯編將生效。引用可以轉換到介面型別或從介面型別轉換,instanceof 運算子可以用來決定某物件的類是否實現了介面。
4.抽象類的用法要求總結
1)abstract class 在 Java 語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。但是,一個類卻可以實現多個interface。
2)在abstract class 中可以有自己的資料成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態的不能被修改的資料成員(也就是必須是static final的,不過在 interface中一般不定義資料成員),所有的成員方法都是abstract的。
3)abstract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關係,interface表示的是"like-a"關係。
4)實現抽象類和介面的類必須實現其中的所有方法。抽象類中可以有非抽象方法。介面中則不能有實現方法。
5)介面中定義的變數預設是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值。
6)抽象類中的變數預設是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。
7)介面中的方法預設都是 public,abstract 型別的。
二.內部類
1)非靜態成員內部類
A:定義,:在一個外部類中有成員變數和成員方法,那麼成員內部類就是把整個一個類當成了外部類的成員對待了
B: 訪問方式:內部類訪問外部類,內部類可以直接訪問外部類,包括私有成員,因為內部類擁有外部類的引用是類名.this。外部類訪問內部類,外部類訪問外部類的成員,必須要建立內部類的物件
格式:外部類名.內部類名 = 外部類物件.內部類物件;
Outer.Inner oi = new Outer().new Inner();//outer代表外部類,Inner代表內部類
C:存放位置:在外部類裡,在外部類的成員方法外.
D:修飾符:final、abstract、public、private、protected和static等,那麼被static修飾的就是下面所說的靜態內部類.
- <spanstyle="font-size:12px;">public class InnerDemo1 {
- /**展示非靜態成員內部類的建立方式
- * @黑馬ZWF
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Outer.Inner oi = new Outer().new Inner(); //非靜態成員內部類的建立方式
- oi.show(); //呼叫內部類的show()方法
- }
- }
- class Outer {
- private String name = "張三"; //設定私有變數
- class Inner {
- public void show() {
- System.out.println(Outer.this.name); //讀取name變數並列印
- }
- }
- }</span>
A:定義,就是在成員內部類的基礎上加上static
B:格式:外部類名.內部類名 = 外部類名.內部類物件;
Outer.Inner oi = new Outer.Inner();
C:存放位置:和成員內部類一樣,就是多了個static
- public class InnerDemo2 {
- /**展示靜態內部類的建立方式
- * @黑馬ZWF
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Outer.Inner oi1 = new Outer.Inner(); //靜態內部類的建立方式
- oi1.show(); //輸出結果是:Hello World!
- Outer.Inner2 oi2 = new Outer.Inner2();
- oi2.show2(); //輸出結果是:Hello World!2
- }
- }
- class Outer {
- static class Inner {
- public void show() {
- System.out.println("Hello World!");
- }
- }
- static class Inner2 {
- public static void show2() {
- System.out.println("Hello World!2"); //注意不要在非靜態的內部類中定義靜態的方法
- }
- }
- }
A:定義,在外部類成員方法中定義的內部類,他更像區域性變數
B: 注意:
第一:方法內部類只能在定義該內部類的方法內例項化,不可以在此方法外對其例項化。
第二:方法內部類物件不能使用該內部類所在方法的非final區域性變數。因為方法的區域性變數位於棧上,只存在於該方法的生命期內。當一個方法結束,其棧結構被刪除,區域性變數成為歷史。但是該方法結束之後,在方法內建立的內部類物件可能仍然存在於堆中!例如,如果對它的引用被傳遞到其他某些程式碼,並存儲在一個成員變數內。 正因為不能保證區域性變數的存活期和方法內部類物件的一樣長,所以內部類物件不能使用它們。
第三:方法內部類的修飾符。與成員內部類不同,方法內部類更像一個區域性變數 。可以用於修飾方法內部類的只有final和abstract。
第四:靜態方法內的方法內部類。靜態方法是沒有this引用的,因此在靜態方法內的內部類遭受同樣的待遇,即:只能訪問外部類的靜態成員。
(4)匿名類:匿名類是不能有名稱的類,所以沒辦法引用它們。必須在建立時,作為new語句的一部分來宣告它們。這就要採用另一種形式的new語句,也就是匿名類。這種形式的new語句宣告一個新的匿名類,它對一個給定的類進行擴充套件,或者實現一個給定的介面。它還建立那個類的一個新例項,並把它作為語句的結果而返回。要擴充套件的類和要實現的介面是new語句的運算元,後跟匿名類的主體。如果匿名類對另一個類進行擴充套件,它的主體可以訪問類的成員、覆蓋它的方法等等,這和其他任何標準的類都是一樣的。如果匿名類實現了一個介面,它的主體必須實現介面的方法。
A:前提:內部類可以繼承或實現一個外部類或者介面。
B:格式為:new 外部類名或者介面名(){覆蓋類或者介面中的程式碼,(也可以自定義內容。)}
C:簡單理解:就是建立一個帶內容的外部類或者介面的子類的匿名物件。
D: a,繼承式的匿名類
b,介面式(也可以叫實現式的,名字無所謂)的匿名類
c,引數式的匿名類
程式碼示例:
- public class InnerDemo3 {
- /**匿名內部類的使用
- * @黑馬ZWF
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Outer o = new Outer();
- o.print();
- }
- }
- class Demo {
- public void show() {
- System.out.println("Hello World!");
- }
- }
- class Outer {
- public void print() { //匿名內部類
- new Demo() {
- }.show();
- }
- }
匿名內部類的注意事項
注意匿名類的宣告是在編譯時進行的,例項化在執行時進行。這意味著for迴圈中的一個new語句會建立相同匿名類的幾個例項,而不是建立幾個不同匿名類的一個例項。
在使用匿名內部類時,要記住以下幾個原則:
1)匿名內部類不能有構造方法。
2)匿名內部類不能定義任何靜態成員、方法和類。
3)匿名內部類不能是public,protected,private,static。
4)只能建立匿名內部類的一個例項。
5)一個匿名內部類一定是在new的後面,用其隱含實現一個介面或實現一個類。
6)因匿名內部類為區域性內部類,所以區域性內部類的所有限制都對其生效。
7)內部類只能訪問外部類的靜態變數或靜態方法。
8)匿名類和內部類中的中的this :有時候,我們會用到一些內部類和匿名類。當在匿名類中用this時,這個this則指的是匿名類或內部類本身。這時如果我們要使用外部類的方法和變數的話,則應該加上外部類的類名
匿名內部類的作用
Java的內部類和C++中的巢狀類有本質的不同:C++的巢狀類沒有指向包裝類的控制代碼。僅僅表達一個封裝的概念;但是Java的內部類不同,它可以訪問包裝類的成員(這表示它擁有指向包裝類的控制代碼)。
匿名內部類是內部類的一種簡化寫法:return new Wrapper {
...
};
等價於:Wrapped extends Wrapper {
...
}
return new Wrapped();
難道匿名內部類就只這一點作用嗎?考慮一下下面的例子
- interface ICount {
- int count();
- }
- class Parent {
- int i = 0;
- int count() {
-
相關推薦
8--黑馬程式設計師---技術總結之抽象類、內部類
、期待與您交流! ---------------------- 一.抽象類 1.抽象類的概念 在面向物件的概念中,所有的物件都是通過類來描繪的,但是反過來,並不是所有的類都是用來描繪物件的,如果一個類中沒有 包含足夠的資訊來描繪一個具體的物
7--黑馬程式設計師--技術總結之幾個重要的關鍵字
、期待與您交流! ---------------------- 一.static關鍵字 static表示“全域性”或者“靜態”的意思,用來修飾成員變數和成員方法,也可以形成靜態static程式碼塊,但是Java語言中沒有全域性變數的概念。
5--黑馬程式設計師--技術總結之面向物件
、期待與您交流! ---------------------- 一.什麼是面向物件? 1.面向物件的定義 面向物件是一種對現實世界理解和抽象的方法,是計算機程式設計技術發展到一定階段後的產物。早期的計算機程式設計是基於面向過程
9--黑馬程式設計師--技術總結之多執行緒
、期待與您交流! ---------------------- 一.多執行緒的概念 以往開發的程式大多是單執行緒的,即一個程式只有一條從頭至尾的執行線索。然而現實世界中的很多過程都具有多條線索同時動作的特性:例如,我們可以一邊看電視,一邊活動胳膊,如果
4--黑馬程式設計師--技術總結之陣列
<span style="white-space: pre; color: rgb(68, 68, 68); font-family: 'Microsoft Yahei', 微軟雅黑, Tahoma, Arial, Helvetica, STHeiti; font-
黑馬程式設計師——方法總結之網編
------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ------- /* 1.IP地址類 InetAddress 所在包:java.net.InetAddress
黑馬程式設計師----Java基礎之集合類(一)
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師----Java基礎之String類
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師——java拾遺之代理類及AOP
動態代理其實就是java.lang.reflect.Proxy類動態的根據您指定的所有介面生成一個class 位元組碼,該class會繼承Proxy類,並實現所有你指定的介面(您在引數中傳入的介面陣列);然後再利用您指定的classloader將 class 位元組碼載
JavaSE--抽象類、內部類、接口
-- ann 固定 com init 外部 普通 new t eve 一、抽象類 當事物不能具體描述時可將事物抽象化,只對其應有的行為進行簡單的描述而不進行深度具體的描述,這樣就產生了抽象類,使用abstract關鍵字對類進行修飾內部方法也是用abstract進行描述。
黑馬程式設計師技術部落格之哲學家吃飯問題
----------- android培訓、java培訓、java學習型技術部落格、期待與您交流! ------------ 哲學家就餐:有五個哲學家繞著圓桌坐,每個哲學家面前有一碗麵,兩人之間有一支筷子,這樣每個哲學家左右各有一支筷子。哲學家有2個狀態,思考或者拿起筷子吃
黑馬程式設計師——Java高新技術之反射學習總結一
反射學習總結 基礎補充: Java程式中的各個Java類屬於同一類事務,描述這類事務的Java類名就是C
黑馬程式設計師 java程式設計之面向物件學習筆記總結
---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ---------------------- 繼承: 在java中,在我們要對一個事物進行封裝時,發現有某一個類的特性和要封裝的這個 類的特性相同,而我們可以在這個
黑馬程式設計師----Java基礎之反射
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師----Java基礎之GUI
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師----Java基礎之IO包中其它類
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師----Java基礎之多執行緒
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師----Java基礎之面向物件(最終篇)
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師----Java基礎之面向物件(封裝 繼承 多型)(二)
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g
黑馬程式設計師----Java基礎之面向物件(封裝 繼承 多型)
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a&g