2018-09-13

Java抽象類\多態(tài)

1抽象類什么時候使用?

當(dāng)某個父類只是知道子類應(yīng)該包含怎么樣的方法,但是無法準(zhǔn)確知道子類如何實現(xiàn)這些方法。

比如一個圖形類應(yīng)該有一個求周長的方法,但是不同的圖形求周長的算法不一樣。那該怎么辦呢?

(分析事物時,發(fā)現(xiàn)了共性內(nèi)容,就出現(xiàn)向上抽取。會有這樣一種特殊情況,就是方法功能聲明相同,但方法功能主體不同。那么這時也可以抽取,但只抽取方法聲明,不抽取方法主體。那么此方法就是一個抽象方法。)

2抽象類: 包含抽象方法的類,一定是抽象類,,使用 abstract 修飾的類,是抽象類

抽象類的特點:

1,抽象類與抽象方法都必須使用 abstract 來修飾

2,抽象類不能直接創(chuàng)建對象(意義),原因:調(diào)用抽象方法沒有意義。

3,抽象類中可以有抽象方法,也可以沒有抽象方法(面試問題)

4,抽象類的子類(繼承)

a,實現(xiàn)了抽象方法的具體類,,只有覆蓋了抽象類中所有的抽象方法后,其子類才可以創(chuàng)建對象。

b,抽象類,否則該子類還是一個抽象類,子類不可以創(chuàng)建對象。

抽象類面試題://抽象類中是否可以沒有抽象方法?如果可以,那么,該類還定義成抽象類有意義嗎?為

什么?可以沒有抽象方法,有意義,不會讓其他人直接創(chuàng)建該類對象

3抽象方法

抽象方法: 方法只有聲明部分,沒有方法體.

抽象方法定義的格式:

public abstract 返回值類型 方法名(參數(shù));

抽象類定義的格式:

public abstract void class 類名 {

}

4 抽象類的細(xì)節(jié)問題:

1)、抽象類一定是個父類?是的,因為不斷抽取而來的。

2)、抽象類中是否可以不定義抽象方法。

是可以的,那這個抽象類的存在到底有什么意義呢?不讓該類創(chuàng)建對象,方法可以直接讓子類去使用

3)、抽象關(guān)鍵字 abstract 不可以和哪些關(guān)鍵字共存?

①private:私有的方法子類是無法繼承到的,也不存在覆蓋,而 abstract 和 private 一起使用修飾方法,abstract 既要子類去實現(xiàn)這個方法,而 private 修飾子類根本無法得到父類這個方法?;ハ嗝堋?/p>

②final.

③static.

eg:

抽象類Employee


package com.hello.abstrsct;

public abstract class Employee {

public abstract void working();//聲明抽象類方法

}

抽象類PhpCoder


package com.hello.abstrsct;

public  class  PhpCoder extends Employee {

public void working() {

System.out.println("java");

}

}

測試


package com.hello.abstrsct;

import org.junit.Test;

public class Demo {

@Test

public void test() {

PhpCoder p=new PhpCoder();//實例化子類

p.working();

}

}

多態(tài)

現(xiàn)實事物經(jīng)常會體現(xiàn)出多種形態(tài),如學(xué)生,學(xué)生是人的一種,則一個具體的同學(xué)張三既是學(xué)生也是人,即出現(xiàn)兩種形態(tài)。如 Student 類繼承了 Person 類,一個 Student 的對象便既是 Student,又是 Person。那么一個 Student 對象既可以賦值給一個 Student 類型的引用,也可以賦值給一個 Person 類型的引用。

多態(tài)使用的前提:

1,有繼承或者實現(xiàn)關(guān)系

2,要方法重寫

3,父類引用指向子類對象

多態(tài)特點:

①最終多態(tài)體現(xiàn)為父類引用變量可以指向子類對象。

②多態(tài)的前提是必須有子父類關(guān)系或者類實現(xiàn)接口關(guān)系,否則無法完成多態(tài)。

③在使用多態(tài)后的父類引用變量調(diào)用方法時,會調(diào)用子類重寫后的方法。

多態(tài)的定義格式:就是父類的引用變量指向子類對象

父類類型 變量名 = new 子類類型();

變量名.方法名();

分類:

①普通類多態(tài)定義的格式

父類 變量名 = new 子類();

如: class Fu {}

class Zi extends Fu {}

//類的多態(tài)使用

Fu f = new Zi();//實例化子類

②抽象類多態(tài)定義的格式

抽象類 變量名 = new 抽象類子類();

如: abstract class Fu {

public abstract void method();

}

class Zi extends Fu {

public void method(){

System.out.println(“重寫父類抽象方法”);

}

}

//類的多態(tài)使用

Fu fu= new Zi();//實例化抽象子類

③接口多態(tài)定義的格式

接口 變量名 = new 接口實現(xiàn)類();

如:

//接口

interface Fu {

public abstract void method();

}

接口實現(xiàn)類implements

class Zi implements Fu {

public void method(){

System.out.println(“重寫接口抽象方法”);

}

}

//接口的多態(tài)使用

Fu fu = new Zi();//實例化接口實現(xiàn)類

成員變量在使用上有沒有變化,有的


package com.hello.abstrsct;

public class Fu {

int num = 4;

void show() {

System.out.println("Fu show num");

}

}

子類


package com.hello.abstrsct;

public class Zi extends Fu {

int num = 5;

public void show() {

System.out.println("Zi show num");

}

}

多態(tài)測試


public class Test1 {

public static void main(String[] args) {

Fu f = new Zi();

//f.show();//顯示子類的

Zi zi=new Zi();

System.out.println(zi.num);//5

System.out.println(f.num);//4

}

成員方法在使用上有沒有變化,有的


public static void main(String[] args) {

Fu f = new Zi();//實例化子類

f.show();//顯示子類的

}

instanceof 關(guān)鍵字

來判斷某個對象是否屬于某種數(shù)據(jù)類型。如學(xué)生的對象屬于學(xué)生類,學(xué)生的對象也屬于人類。

使用格式:

boolean b = 對象 instanceof 數(shù)據(jù)類型;

Person p1 = new Student(); // 前提條件,學(xué)生類已經(jīng)繼承了人類

boolean flag = p1 instanceof Student; //flag 結(jié)果為 true

boolean flag2 = p2 instanceof Teacher; //flag 結(jié)果為 false

多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型與向下轉(zhuǎn)型兩種:

向上轉(zhuǎn)型:當(dāng)有子類對象賦值給一個父類引用時,便是向上轉(zhuǎn)型,多態(tài)本身就是向上轉(zhuǎn)型的過程。

使用格式:

父類類型 變量名 = new 子類類型();

如:Person p = new Student();

向下轉(zhuǎn)型:一個已經(jīng)向上轉(zhuǎn)型的子類對象可以使用強制類型轉(zhuǎn)換的格式,將父類引用轉(zhuǎn)為子類引用,這個過程是向下轉(zhuǎn)型。如果是直接創(chuàng)建父類對象,是無法向下轉(zhuǎn)型的!

使用格式:

子類類型 變量名 = (子類類型) 父類類型的變量;

Person p = new Student();

如:Student stu = (Student) p; //變量 p 實際上指向 Student 對象

!!如果是調(diào)用子類獨有的功能時,必須要向下轉(zhuǎn)型,才能調(diào)用.

//描述動物類,并抽取共性 eat 方法


abstract class Animal {

abstract void eat();

}

// 描述狗類,繼承動物類,重寫 eat 方法,增加 lookHome 方法


class Dog extends Animal {

void eat() {

System.out.println("啃骨頭");

}

void lookHome() {

System.out.println("看家");

}

}

// 描述貓類,繼承動物類,重寫 eat 方法,增加 catchMouse 方法


class Cat extends Animal {

void eat() {

System.out.println("吃魚");

}

void catchMouse() {

System.out.println("抓老鼠");

}

}

測試


public class Test {

public static void main(String[] args) {

Animal a = new Dog(); //多態(tài)形式,創(chuàng)建一個狗對象

a.eat(); // 調(diào)用對象中的方法,會執(zhí)行狗類中的 eat 方法

// a.lookHome();//使用 Dog 類特有的方法,需要向下轉(zhuǎn)型,不能直接使用

// 為了使用狗類的 lookHome 方法,需要向下轉(zhuǎn)型

// 向下轉(zhuǎn)型過程中,可能會發(fā)生類型轉(zhuǎn)換的錯誤,即 Class Cast Exception 異常

// 那么,在轉(zhuǎn)之前需要做健壯性判斷

if( !a instanceof Dog){ // 判斷當(dāng)前對象是否是 Dog 類型

System.out.println("類型不匹配,不能轉(zhuǎn)換");

return;}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容