詳解Java抽象類與普通類的區(qū)別
淺談抽象類
在面向?qū)ο蟾拍钪?所有的對象都是通過類來描述的,但是反過來,并不是所有的類都是用來描述對象的.如果一個類中沒有足夠多的信息來描述一個具體的對象,這樣的類就是抽象類。
看到這里可能還是覺得有些難以理解,舉個例子說明一下:說到動物你會想到什么?貓,狗,雞鴨鵝?當(dāng)然這些都可以.那么動物這兩個字,你能確定一個具體的對象嗎?顯然不能.甚至更嚴(yán)格意義上講,說到貓你會想到什么?橘貓,短美…
畢竟:
一千個人心中有一千個哈姆雷喵.
所以我們在設(shè)計中,動物類可以設(shè)計成為抽象類,而某一種特定的物種可以采用通過繼承動物類實現(xiàn).
多態(tài)這部分我理解了好久,有一天突然就會用了,也明白所謂的父類引用指向子類對象是什么意思了.但是寫完前面發(fā)現(xiàn),自己明白了講出來還是很模糊.多態(tài)真的是很重要很重要的一個點,要好好體會這部分.
抽象類和普通類的區(qū)別是什么?
抽象類的語法規(guī)則
抽象類的語法規(guī)則:abstract關(guān)鍵字修飾
1.抽象類不可以被實例化.
2.抽象類不定有抽象方法.
3.一個類中如果有抽象方法,那么這個類一定是抽象類.
4.抽象類中可以存在普通屬性、方法、靜態(tài)屬性和靜態(tài)方法.
5.抽象類中可以存在構(gòu)造方法.
public abstract class AbstractObject{
// 普通屬性
String name;
// 構(gòu)造方法
public AbstractObject(String name) {
this.name = name;
}
// 靜態(tài)方法 - 類名訪問
public static void staticMethod(){
System.out.println("抽象類可以有靜態(tài)方法.");
}
// 抽象方法
public abstract void move();
// 普通方法
public void commonMethod(String food){
System.out.println("抽象類可以有普通方法.");
}
}
抽象類不可以實例化
這部分可以直接暫時記住結(jié)論,整個過程可以暫時先跳過后面補,按照我的學(xué)習(xí)經(jīng)歷(基礎(chǔ)差到爆),這部分直接看會很懵.
定義一個動物的抽象類,動物總得動吧(并不!)所以定義一個共性的move()方法.
public abstract class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public abstract void move();
}
當(dāng)我使用IDEA寫示例的時候直接出現(xiàn)了第二種情況!見鬼了抽象類new出來了!
public class Test {
public static void main(String[] args) {
// 抽象類不能實例化!會直接報編譯期錯誤!
//標(biāo)紅信息: 'Animal' is abstract; cannot be instantiated
Animal animal = new Animal("小貓");
// 第二種情況
Animal animalObjcet = new Animal("小貓") {
@Override
public void move() {
System.out.println("我開始移動了!");
}
};
}
}
關(guān)于第二種情況的解釋 - 擴展知識:匿名內(nèi)部類(可跳過)
這里涉及到了一個知識點叫做匿名內(nèi)部類.
匿名內(nèi)部類的格式如下:
new 類名或者接口名(){
重寫方法;
}
// 放到一起對比看,很明顯后面的是一個匿名內(nèi)部類
new Animal("小貓") {
@Override
public void move() {
System.out.println("我開始移動了!");
}
};
匿名:這個類沒有名字
內(nèi)部類:存在于某個類的內(nèi)部的類.
它實際上是繼承并實現(xiàn)了Animal抽象類的一個子類.也就是說這里并不是實例化出了Animal類,這個簡便的寫法相當(dāng)于我們進行了如下的寫法.
public class AnimalObject extends Animal{
public AnimalObject(String name) {
super(name);
}
@Override
public void move() {
System.out.println("我是一只能動的動物!");
}
}
public class Test {
public static void main(String[] args) {
AnimalObject animalObject = new AnimalObject("我是動物抽象類的子類");
animalObjcet.move(); // 我是一只能動的動物!
}
}
抽象類的子類
注意:這里有一個需要強調(diào)的地方,對于抽象類中的方法我們的用詞應(yīng)該是實現(xiàn).對于已經(jīng)實現(xiàn)了的方法,我們的用詞才可以是重寫.寫到后面發(fā)現(xiàn)了前面描述過程中我用詞都是重寫這里進行了修正.
錯誤寫法:不重寫(Override)抽象類中的抽象方法
正確寫法:不實現(xiàn)(Implement)抽象類中的抽象方法
再次補充:好像說成重寫也不能算錯誤,IDEA自動生成的里面也加了 @Override 注解.就不繼續(xù)修改了.
1.不實現(xiàn)抽象類中的抽象方法
當(dāng)不對抽象類中的抽象方法進行重寫的時候,子類一定也是抽象類.(有抽象方法的類一定是抽象類)
public abstract class AbstractCat extends Animal{
Integer weight;
public AbstractCat(String name, Integer weight) {
super(name); // 繼承父類的名稱
this.weight = weight; // 貓咪的年齡
}
// 這個是沒有重寫,依舊是了抽象方法
public abstract void move();
// 注意:下面這種寫法是重寫過之后的!只是方法體為空.
// public void move(){};
}
2.實現(xiàn)抽象類中的抽象方法
當(dāng)對抽象類中的所有抽象方法進行實現(xiàn)之后,現(xiàn)在的貓咪類可以是一個普通類了.
public class Cat extends AbstractCat{
public Cat(String name, Integer weight) {
super(name, weight);
}
@Override
public void move() {
System.out.println("一只奔跑的重達" + weight + "kg的" + name);
}
}
測試一下:
public class Test {
public static void main(String[] args) {
Cat cat = new Cat("橘貓", 20);
cat.move(); // 一只奔跑的重達20kg的橘貓
}
}
好了到這里,屬于你的橘貓終于跑起來了!
關(guān)于實現(xiàn)抽象方法的延伸
我看很多文章都說要子類要重寫(重寫是錯誤的!這里更正為實現(xiàn))父類的抽象方法,抽象方法.那我如果只實現(xiàn)部分抽象方法呢?
第一步:改造Animal類
public abstract class Animal {
String name;
public Animal(String name) {
System.out.println("我是動物的構(gòu)造方法!");
this.name = name;
}
// 多添加幾個抽象方法
public abstract void move();
public abstract void eat();
public abstract void sleep();
}
第二步:AbstractCat 類中實現(xiàn)部分抽象方法
// 不添加 abstract 關(guān)鍵字會報錯
// Class 'AbstractCat' must either be declared abstract or implement abstract method 'move()' in 'Animal'
public abstract class AbstractCat extends Animal{
Integer weight;
public AbstractCat(String name, Integer weight) {
super(name);
System.out.println("我是抽象貓咪的構(gòu)造方法!");
// 繼承父類的名稱
this.weight = weight; // 貓咪的年齡
}
@Override
public void eat() {
System.out.println(this.name + "在吃貓糧");
}
@Override
public void sleep() {
System.out.println(this.name + "睡覺了!");
}
}
第三步:Cat類登場
public class Cat extends AbstractCat{
public Cat(String name, Integer weight) {
super(name, weight);
}
/*
sleep方法和eat方法已經(jīng)在父類中實現(xiàn)過了,所以這里只剩下最后一個 move 是需要實現(xiàn)的抽象方法.
*/
@Override
public void move() {
System.out.println("重達" + weight + "kg的" + this.name + "在懶洋洋的跑");
}
}
小結(jié)
1.普通類可以實例化調(diào)用,但是抽象類不可以,因為抽象類只是一種概念,無法映射為具體的對象.
2.普通類和抽象類都可以被繼承,但是抽象類被繼承之后,子類需要重寫抽象類中的全部抽象方法,否則子類必須是一個抽象類.
參考和擴展閱讀
Java基礎(chǔ)系列第一彈之方法重載和方法重寫的區(qū)別
Java基礎(chǔ)系列第二彈之Java多態(tài)成員訪問的特點
Java基礎(chǔ)系列第三彈之操作字符串的類都有哪些?區(qū)別是什么?
到此這篇關(guān)于詳解Java抽象類與普通類的區(qū)別的文章就介紹到這了,更多相關(guān)Java抽象類與普通類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea中項目前端網(wǎng)頁圖標(biāo)不顯示的原因及解決
這篇文章主要介紹了idea中項目前端網(wǎng)頁圖標(biāo)不顯示的原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Java編程實現(xiàn)五子棋人人對戰(zhàn)代碼示例
這篇文章主要介紹了Java編程實現(xiàn)五子棋人人對戰(zhàn)代碼示例,具有一定借鑒價值,需要的朋友可以參考下。2017-11-11
Spring Boot中Bean定義方調(diào)用方式解析
這篇文章主要介紹了Spring Boot中Bean定義方調(diào)用方式解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07
關(guān)于LinkedList集合對元素進行增查刪操作
LinkedList集合內(nèi)部包含有兩個Node類型的first和last屬性維護一個雙向循環(huán)鏈表,在鏈表中的每一個元素都使用引用的方式來記住它的前一個元素和后一個元素,從而可以將所有的元素彼此連接起來,需要的朋友可以參考下2023-04-04
Java中jqGrid 學(xué)習(xí)筆記整理——進階篇(二)
這篇文章主要介紹了Java中jqGrid 學(xué)習(xí)筆記整理——進階篇(二)的相關(guān)資料,需要的朋友可以參考下2016-04-04

