參考資料
《Java語言程序設(shè)計(jì)(基礎(chǔ)篇)》—— Y.Daniel Liang
前言
本人菜鳥闰非,入IT只為當(dāng)鼓勵師。本編文章旨在對 Java 中的 抽象類 做總結(jié)
一骏庸、抽象類
1. 定義一個(gè)抽象類
// 抽象類
public abstract class Shape {
// 可以有屬性
// private String color;
// 可以有普通方法
/* public void setColor(String color) {
this.color = color;
}
public String getColor() {
return this.color;
}
*/
// 抽象方法
public abstract double getArea(); // 獲取面積
public abstract double getPan(); // 獲取周長
public abstract void printShape(); // 獲取周長
}
上方代碼中的Shape類是一個(gè)抽象類募舟,它表示一種形狀景东。它擁有兩個(gè)抽象方法, 分別為 getArea()
和 getPan()
捆探。
- 抽象類需要在類頭使用
abstract
修飾符修飾 - 抽象類中未實(shí)現(xiàn)的方法也必須加
abstract
修飾符修飾然爆,我們把這些方法稱為抽象方法。(區(qū)分于接口黍图,接口中的方法默認(rèn)修飾為public abstract
曾雕,不管有無加修飾詞) - 抽象類中不僅可以含有抽象方法,還可以擁有自己的數(shù)據(jù)成員助被,包括屬性和普通方法剖张。(區(qū)分于接口,接口中的方法必須是抽象方法恰起,屬性必須被
public final static
修飾)
2. 繼承抽象類并實(shí)現(xiàn)其抽象方法
public abstract class ShapeTest extends Shape{
public abstract double getArea(); // 獲取面積
public abstract double getPan(); // 獲取周長
public void printShape() { // 輸出形狀信息
System.out.println("我實(shí)現(xiàn)了Shape類的printShape方法修械,但沒有實(shí)現(xiàn)其他兩個(gè)方法,所以我還是一個(gè)抽象類");
}
}
// 正方形類
public class Square extends Shape {
private double len; // 邊長
protected Square(double len) {
this.len = len;
}
public double getArea() {
return len * len; // 邊長 × 邊長
}
public double getPan() {
return 4 * len; // 4 × 邊長
}
public void printShape() {
System.out.println("正方形");
}
}
// 圓形類
public class Circle extends Shape {
private double r; // 半徑
protected Circle (double r) {
this.r = r;
}
public double getArea() {
return Math.PI * r * r; // π × 半徑^2
}
public double getPan() {
return Math.PI*r*2; // 2 × π × 半徑
}
public void printShape() {
System.out.println("圓形");
}
}
二检盼、要點(diǎn)
- 抽象方法不能包含在非抽象類中肯污。如果抽象父類的子類不能實(shí)現(xiàn)所有抽象方法,那么子類也必須定義為抽象吨枉。
- 包含抽象方法的類必須是抽象的蹦渣。但可以定義一個(gè)不含抽象方法的抽象類,作用是使類不能創(chuàng)建實(shí)例貌亭,用來定義新子類的基類柬唯。
- 抽象類不可以創(chuàng)建對象,否則拋出
InstantiationException
異常(使用newInstance()方法創(chuàng)建抽象類或接口實(shí)例拋出的異常)圃庭。但是仍然可以定義它的構(gòu)造方法锄奢,這個(gè)構(gòu)造方法在它子類的構(gòu)造方法中調(diào)用失晴。 - 抽象類不可以用final修飾。因?yàn)槌橄蠓椒ǖ膶?shí)現(xiàn)由子類提供拘央,需要子類繼承該抽象類涂屁,而用了final修飾的類不能被繼承。
- 即使子類的父類是具體的灰伟,這個(gè)子類也可以是抽象的拆又。例如,Object類是具體的栏账,但它的子類Shape是抽象的(所有類均繼承Object類)帖族。
- 子類可以覆蓋父類的方法并將它定義為abstract。這很少見挡爵,作用是實(shí)現(xiàn)父類的方法在子類中變得無效竖般。
- 抽象類的構(gòu)造函數(shù)要定義為protected,因?yàn)樗槐蛔宇愂褂谩?/li>
三了讨、抽象類的好處
- 抽象類可以包含方法的實(shí)現(xiàn)細(xì)節(jié)捻激,因此可以將子類中公用的邏輯上提,增加的代碼的復(fù)用前计。
- 抽象類可以通過方法的覆蓋來實(shí)現(xiàn)多態(tài)的屬性胞谭,也就是運(yùn)行期綁定,由JVM在運(yùn)行時(shí)期根據(jù)對象的類型動態(tài)地決定調(diào)用哪一個(gè)方法男杈。如下面的代碼:
Shape square = new Square(2);
Shape circle = new Circle (3);
square.printShape(); // 正方形
circle .printShape(); // 圓形
square.getArea(); // 4
circle .getArea(); // 9π
square.getPan(); // 8
circle .getPan(); // 6π
四丈屹、抽象類的UML圖形記號
在UML圖形記號中,抽象類和抽象方法的名字用斜體表示伶棒。
五旺垒、示例:抽象的Number類
- Number類 來自于
java.lang.Number
,它是數(shù)值包裝類肤无、BigInteger先蒋、BigDecimal的抽象父類。