您好,登錄后才能下訂單哦!
這篇文章主要介紹Java中抽象類與普通類的區(qū)別有哪些,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
在面向?qū)ο蟾拍钪?所有的對(duì)象都是通過類來描述的,但是反過來,并不是所有的類都是用來描述對(duì)象的.如果一個(gè)類中沒有足夠多的信息來描述一個(gè)具體的對(duì)象,這樣的類就是抽象類。
看到這里可能還是覺得有些難以理解,舉個(gè)例子說明一下:說到動(dòng)物你會(huì)想到什么?貓,狗,雞鴨鵝?當(dāng)然這些都可以.那么動(dòng)物這兩個(gè)字,你能確定一個(gè)具體的對(duì)象嗎?顯然不能.甚至更嚴(yán)格意義上講,說到貓你會(huì)想到什么?橘貓,短美…
畢竟:
一千個(gè)人心中有一千個(gè)哈姆雷喵.
所以我們?cè)谠O(shè)計(jì)中,動(dòng)物類可以設(shè)計(jì)成為抽象類,而某一種特定的物種可以采用通過繼承動(dòng)物類實(shí)現(xiàn).
多態(tài)這部分我理解了好久,有一天突然就會(huì)用了,也明白所謂的父類引用指向子類對(duì)象是什么意思了.但是寫完前面發(fā)現(xiàn),自己明白了講出來還是很模糊.多態(tài)真的是很重要很重要的一個(gè)點(diǎn),要好好體會(huì)這部分.
抽象類的語法規(guī)則
抽象類的語法規(guī)則:abstract
關(guān)鍵字修飾
1.抽象類不可以被實(shí)例化.
2.抽象類不定有抽象方法.
3.一個(gè)類中如果有抽象方法,那么這個(gè)類一定是抽象類.
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("抽象類可以有普通方法."); } }
抽象類不可以實(shí)例化
這部分可以直接暫時(shí)記住結(jié)論,整個(gè)過程可以暫時(shí)先跳過后面補(bǔ),按照我的學(xué)習(xí)經(jīng)歷(基礎(chǔ)差到爆),這部分直接看會(huì)很懵.
定義一個(gè)動(dòng)物的抽象類,動(dòng)物總得動(dòng)吧(并不!)所以定義一個(gè)共性的move()方法.
public abstract class Animal { String name; public Animal(String name) { this.name = name; } public abstract void move(); }
當(dāng)我使用IDEA寫示例的時(shí)候直接出現(xiàn)了第二種情況!見鬼了抽象類new
出來了!
public class Test { public static void main(String[] args) { // 抽象類不能實(shí)例化!會(huì)直接報(bào)編譯期錯(cuò)誤! //標(biāo)紅信息: 'Animal' is abstract; cannot be instantiated Animal animal = new Animal("小貓"); // 第二種情況 Animal animalObjcet = new Animal("小貓") { @Override public void move() { System.out.println("我開始移動(dòng)了!"); } }; } }
關(guān)于第二種情況的解釋 - 擴(kuò)展知識(shí):匿名內(nèi)部類(可跳過)
這里涉及到了一個(gè)知識(shí)點(diǎn)叫做匿名內(nèi)部類.
匿名內(nèi)部類的格式如下:
new 類名或者接口名(){ 重寫方法; } // 放到一起對(duì)比看,很明顯后面的是一個(gè)匿名內(nèi)部類 new Animal("小貓") { @Override public void move() { System.out.println("我開始移動(dòng)了!"); } };
匿名:這個(gè)類沒有名字
內(nèi)部類:存在于某個(gè)類的內(nèi)部的類.
它實(shí)際上是繼承并實(shí)現(xiàn)了Animal抽象類的一個(gè)子類.也就是說這里并不是實(shí)例化出了Animal類,這個(gè)簡便的寫法相當(dāng)于我們進(jìn)行了如下的寫法.
public class AnimalObject extends Animal{ public AnimalObject(String name) { super(name); } @Override public void move() { System.out.println("我是一只能動(dòng)的動(dòng)物!"); } } public class Test { public static void main(String[] args) { AnimalObject animalObject = new AnimalObject("我是動(dòng)物抽象類的子類"); animalObjcet.move(); // 我是一只能動(dòng)的動(dòng)物! } }
抽象類的子類
注意:這里有一個(gè)需要強(qiáng)調(diào)的地方,對(duì)于抽象類中的方法我們的用詞應(yīng)該是實(shí)現(xiàn).對(duì)于已經(jīng)實(shí)現(xiàn)了的方法,我們的用詞才可以是重寫.寫到后面發(fā)現(xiàn)了前面描述過程中我用詞都是重寫這里進(jìn)行了修正.
錯(cuò)誤寫法:不重寫(Override)抽象類中的抽象方法
正確寫法:不實(shí)現(xiàn)(Implement)抽象類中的抽象方法
再次補(bǔ)充:好像說成重寫也不能算錯(cuò)誤,IDEA自動(dòng)生成的里面也加了 @Override 注解.就不繼續(xù)修改了.
1.不實(shí)現(xiàn)抽象類中的抽象方法
當(dāng)不對(duì)抽象類中的抽象方法進(jìn)行重寫的時(shí)候,子類一定也是抽象類.(有抽象方法的類一定是抽象類)
public abstract class AbstractCat extends Animal{ Integer weight; public AbstractCat(String name, Integer weight) { super(name); // 繼承父類的名稱 this.weight = weight; // 貓咪的年齡 } // 這個(gè)是沒有重寫,依舊是了抽象方法 public abstract void move(); // 注意:下面這種寫法是重寫過之后的!只是方法體為空. // public void move(){}; }
2.實(shí)現(xiàn)抽象類中的抽象方法
當(dāng)對(duì)抽象類中的所有抽象方法進(jìn)行實(shí)現(xiàn)之后,現(xiàn)在的貓咪類可以是一個(gè)普通類了.
public class Cat extends AbstractCat{ public Cat(String name, Integer weight) { super(name, weight); } @Override public void move() { System.out.println("一只奔跑的重達(dá)" + weight + "kg的" + name); } }
測(cè)試一下:
public class Test { public static void main(String[] args) { Cat cat = new Cat("橘貓", 20); cat.move(); // 一只奔跑的重達(dá)20kg的橘貓 } }
好了到這里,屬于你的橘貓終于跑起來了!
關(guān)于實(shí)現(xiàn)抽象方法的延伸
我看很多文章都說要子類要重寫(重寫是錯(cuò)誤的!這里更正為實(shí)現(xiàn))父類的抽象方法,抽象方法.那我如果只實(shí)現(xiàn)部分抽象方法呢?
第一步:改造Animal類
public abstract class Animal { String name; public Animal(String name) { System.out.println("我是動(dòng)物的構(gòu)造方法!"); this.name = name; } // 多添加幾個(gè)抽象方法 public abstract void move(); public abstract void eat(); public abstract void sleep(); }
第二步:AbstractCat 類中實(shí)現(xiàn)部分抽象方法
// 不添加 abstract 關(guān)鍵字會(huì)報(bào)錯(cuò) // 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)在父類中實(shí)現(xiàn)過了,所以這里只剩下最后一個(gè) move 是需要實(shí)現(xiàn)的抽象方法. */ @Override public void move() { System.out.println("重達(dá)" + weight + "kg的" + this.name + "在懶洋洋的跑"); } }
小結(jié)
1.普通類可以實(shí)例化調(diào)用,但是抽象類不可以,因?yàn)槌橄箢愔皇且环N概念,無法映射為具體的對(duì)象.
2.普通類和抽象類都可以被繼承,但是抽象類被繼承之后,子類需要重寫抽象類中的全部抽象方法,否則子類必須是一個(gè)抽象類.
以上是“Java中抽象類與普通類的區(qū)別有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。