abstract類和介面

張超帥發表於2017-08-06

比較一下兩者的語法區別:
1.抽象類可以有構造方法,介面中不能有構造方法。
2.抽象類中可以有普通成員變數,介面中沒有普通成員變數
3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。
4. 抽象類中的抽象方法的訪問型別可以是public,protected和(預設型別,雖然
eclipse下不報錯,但應該也不行),但介面中的抽象方法只能是public型別的,並且預設即為public abstract型別。
5. 抽象類中可以包含靜態方法,介面中不能包含靜態方法
6. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是public static final型別,並且預設即為public static final型別。
7. 一個類可以實現多個介面,但只能繼承一個抽象類。

介面:
屬性:public static final
方法:public abstract

為什麼介面中不能包含靜態方法?
靜態方法是不能被子類重寫的.
介面中是不能有被實現的方法的,否則它就不是介面而是抽象類
一個類要實現介面中的方法,其實就是對介面方法的重寫。而要實現靜態方法,就必須重寫介面中的靜態方法,這和第一點產生衝突。

在子類中,可以定義與父類同名的靜態方法,不過並不存在“多型”,嚴格的說,方法間沒有多型就不能稱作“覆蓋”。所以說,子類的靜態方法,並沒有覆蓋父類的方法。

在子類繼承父類時,形構相同(返回值,方法名,引數都相同)的方法會被覆蓋。 但這是有前提的,他針對的是例項方法,像static這樣的方法就不能被”覆蓋“。

根據Java Language Specification 的描述,子類在繼承父類時,對於方法而言,存在兩種關係:
1.override即覆蓋,這是對例項方法(instance method)而言的;子類與父類中形構相同的方法會override父類中的那個方法。

2.hide 即隱藏,這是對類方法(class method)即static方法而言的。如果子類中定義了靜態方法,則它會隱藏父類中形構相同的所有方法,但如果隱藏了父類中的例項方法,則會編譯報錯。

根據上面的規定,“override覆蓋”的前提是 例項方法,只有例項方法在繼承時才會出現override情況。 如果是static方法,在繼承時出現的現象根本就不能用“override”這個詞描述,如果static方法在父類和子類中形構一致,則被成為 hide(隱藏)

那什麼是隱藏呢?隱藏 :child隱藏了parent的變數和方法,那麼,child例項就不能訪問parent中被隱藏的變數或者方法,但是,將child例項向上提升轉換成parent,可以訪問parent中被隱藏的變數或者方法了。 我的理解是被隱藏的東西就是隻和類繫結的東西。當子類繼承父類,在子類物件中是訪問不到父類中的被隱藏的東西的。因為這些東西只和父類繫結了。

在從動態繫結的角度來看看這個覆蓋問題,因為static方法是類方法,實現時是靜態繫結的(引用“JAVA 核心技術 卷1 第六版”中149頁內容“private、static、final”修飾的方法是靜態繫結的,所以他們修飾的方法不能實現多型,當然不需要被子類覆蓋了(子類覆蓋父類方法是為了實現多型)。而其他的方法在執行時動態繫結。 同時,所有的變數也都是靜態繫結的。

抽象類:
不管是成員變數,還是非抽象方法都不建議用private修飾,抽象方法是禁止使用private修飾。原因就是我們建立抽象類的目的就是要實現程式碼複用,方便子類繼承,private修飾的是不能繼承的,同時抽象類不能例項化物件,所以用private修飾的成員毫無用處。

java1.8實測,抽象類中的抽象方法和非抽象方法在不加修飾符的情況下,都是預設的default

abstract修飾符能放的地方:
一個類若有抽象方法,其本身也必須宣告為抽象類;介面中的方法預設就是public abstract;綜上所訴:abstract方法必須在abstract類或介面中。

相關文章