前言知識,在一些資料中default又被稱之為friendly。
【1】接口
① 接口的修飾符
接口的修飾符隻有:public和預設修飾符default。
接口中的方法都為抽象方法,執行個體子類必須實作這些方法,抽象子類則不必。抽象子類不一定擁有抽象方法,但是擁有抽象方法的類肯定是抽象類。
[public] interface MyInterface{
[abstract]void myMethod();//abstract is redundant
}
接口中的屬性的預設是public static final 、方法預設是public abstract !
JDK1.8後接口中的方法被允許為
“預設方法”和靜态方法
,即jdk1.8下接口中方法可以被如下修飾符/關鍵字修飾:
public, abstract, default, static 和 strictfp
。
public interface MyInterface {
default String getName(){
return "呵呵呵";
}
//public, abstract, default, static and strictfp are permitted
strictfp static void show(){
System.out.println("接口中的靜态方法");
}
}
參考:JDK1.8新特性
② 接口的特性
- 接口不能用于執行個體化對象;
- 接口沒有構造方法;
- 接口中的所用方法都是抽象方法,方法會被隐式指定為
;public abstract
- 接口中不能包含成員變量,除了static和final變量,變量會被
為隐式指定
變量;public static final
- 接口被類實作,接口支援多繼承;
- 接口中的變量不能用private/protected修飾。
③ 接口中變量的隐式指定
如下所示,idea會提示
public static final is redundant
:
public interface E {
public static final int z=2;
static final int z2=2;
int z3=2;
}
class檔案如下(你會發現三個變量編譯後效果是一樣的):
public interface E {
int z = 2;
int z2 = 2;
int z3 = 2;
}
但是不能使用private/protected修飾,直接提示錯誤。
④ 接口和類的變量重名
執行個體如下:
public class ClassC extends ClassB implements A {
public void printX(){
System.out.println(x);
}
public static void main(String[] args){
new ClassC().printX();
}
}
class ClassB{
int x=1;
}
interface A{
int x=1;
}
上面代碼的錯誤之處在于A和B中都有一個同名變量x,A和B都是C的超類,那麼C繼承自哪個超類的變量呢?
答案是不知道!也就是C也不知道擷取哪個超類的變量。

【2】類的修飾符
類的修飾符分為:可通路控制符和非通路控制符兩種。
可通路控制符是:公共類修飾符 public
非通路控制符有:抽象類修飾符 abstract ;最終類修飾符 final
① 公共類修飾符 public
Java 語言中類 的可通路控制符隻有一個: public 即公共的。
每個 Java 程式的主類都必須是 public 類,作為公共工具供其它類和程式使用的應定義為 public 類。
② 抽象類修飾符 abstract
凡是用 abstract 修飾符修飾的類,被稱為抽象類。所謂抽象類是指這種類沒有具體對象的一種概念類。這樣的類就是 Java 語言的 abstract 類。
③ 最終類修飾符 final
當一個類不可能有子類時可用修飾符 final 把它說明為最終類,也就是說被final修飾的類不能被繼承。被定義為 final 的類通常是一些有固定作用、用來完成某種标準功能的類。
④ 類預設通路控制符
如果一個類沒有通路控制符,說明它具有預設的通路控制符特性。此時,這個
類隻能被同一個包中的類通路或引用
。這一
通路特性又稱為包通路性
。
[public] [abstract|final] class MyClass implements MyInterface {
@Override
public void myMethod() {
}
}
⑤ 内部類
如果一個類為内部類,則可以使用
public,protected、default、private、abstract、static、final
等修飾 。即,可以把内部類了解為
外部類的"成員變量
",那麼自然可以用這些關鍵字修飾符修飾。
【3】屬性的修飾符
屬性的修飾符也分為:可通路控制符和非通路控制符兩類。
可通路控制符有 4 種:
- 公共通路控制符: public ;
- 私有通路控制符: private ;
- 保護通路控制符: protected ;
- 預設通路控制符 : default
非通路控制符有 4 種:
- 靜态域修飾符: static ;
- 最終域修飾符: final ;
- 易失 ( 共享 ) 域修飾符: volatile ;
- 暫時性域修飾符: transient
① 公共通路控制符 public
用 public 修飾的域稱為公共域。如果公共域屬于一個公共類,則可以被所有其它類所引用。由于 public 修飾符會降低運作的安全性和資料的封裝性,是以一般應減少 public 域的使用。
② 私有通路控制符 private
用 private 修飾的成員變量 ( 域 ) 隻能被該類自身所通路,而不能被任何其它類 ( 包括子類 ) 所引用。
③ 保護通路控制符 protected
用 protected 修飾的成員變量可以被三種類所引用:
- 該類自身;
- 與它在同一個包中的其它類;
- 在其它包中的該類的子類。
使用修飾符 protected 的主要作用是允許其它包中它的子類來通路父類的特定屬性。
④ 預設通路控制符default
用 default修飾的成員變量可以被在同一個包中的其它類引用。
⑤ 靜态域修飾符 static
- 用 static 修飾的成員變量僅屬于類的變量,而不屬于任何一個具體的對象。
- 靜态成員變量的值是儲存在類的記憶體區域的公共存儲單元,而不是儲存在某一個對象的記憶體區間。
- 任何一個類的對象通路它時取到的都是相同的資料。
- 任何一個類的對象修改它時 , 也都是對同一個記憶體單元進行操作。
⑥ 最終域修飾符 final
最終域修飾符 final 通常是用來定義符号常量的。一個類的域 ( 成員變量 ) 如果被修飾符 final 說明,則它的取值在程式的整個執行過程中都是不變的。也就是說final定義的變量是最終常量不可改變。
⑦ 易失 ( 共享 ) 域修飾符 volatile
易失 ( 共享 ) 域修飾符 volatile 是用來說明這個成員變量可能被幾個線程所控制和修改。也就是說在程式運作過程中,這個成員變量有可能被其它的程式影響或改變它的取值。是以,在使用中要注意這種成員變量取值的變化。通常 volatile 用來修飾接受外部輸入的域。
關于volatile參考博文:從記憶體可見性看Volatile、原子變量和CAS算法
⑧ 暫時性域修飾符 transient
暫時性域修飾符 transient 用來定義一個暫時性變量。
其特點是:用修飾符 transient 限定的暫時性變量,将指定 Java 虛拟機認定該暫時性變量不屬于永久狀态,以實作不同對象的存檔功能。否則,類中所有變量都是對象的永久狀态的一部分,存儲對象時必須同時儲存這些變量。
私有保護通路控制符 private protected
有的地方提到組合體,private protected。其釋義為:用修飾符 private protected 修飾的成員變量可以被該類本身或該類的子類兩種類通路和引用。
但是已經不再可用,故無需理會
!
【4】方法的修飾符
方法的修飾符也分為:可通路控制符和非通路控制符兩類。
可通路控制符有 4 種
- 公共通路控制符: public ;
- 私有通路控制符: private ;
- 保護通路控制符: protected ;
- 預設通路控制符:default
同樣無需理會組合體,private protected。
非通路控制符有 5 種
- 抽象方法控制符: abstract ;
- 靜态方法控制符: static ;
- 最終方法控制符: final ;
- 本地方法控制符: native ;
- 同步方法控制符: synchronized
可通路控制符參考屬性中的可通路控制符介紹,下面介紹非通路控制符的五種。
① 抽象方法控制符 abstract
用修飾符 abstract 修飾的方法稱為抽象方法。抽象方法是一種僅有方法頭,沒有方法體和操作實作的一種方法。通常需要被子類實作。
② 靜态方法控制符 static
用修飾符 static 修飾的方法稱為靜态方法。靜态方法是屬于整個類的類方法,而不使用 static 修飾、限定的方法是屬于某個具體類對象的方法。
由于 static 方法是屬于整個類的,是以它不能操縱和處理屬于某個對象的成員變量,而隻能處理屬于整個類的成員變量,即 static 方法隻能處理 static 的域。
③ 最終方法控制符 final
用修飾符 final 修飾的方法稱為最終方法。
最終方法是功能和内部語句不能更改的方法,即最終方法不能重寫(覆寫),但是可以被重載。
這樣,就固定了這個方法所具有的功能和操作,防止目前類的子類對父類關鍵方法的錯誤定義,保證了程式的安全性和正确性。
所有被 private 修飾符限定為私有的方法,以及所有包含在 final 類 ( 最終類 ) 中的方法,都被認為是最終方法。
④ 本地方法控制符 native
用修飾符 native 修飾的方法稱為本地方法。為了提高程式的運作速度,需要用其它的進階語言書寫程式的方法體,那麼該方法可定義為本地方法用修飾符 native 來修飾;
⑤ 同步方法控制符 synchronized
該修飾符主要用于多線程共存的程式中的協調和同步。
【5】抽象類與接口
抽象類是用來捕捉子類的通用特性的。接口是抽象方法的集合。從設計層面來說,抽象類是對類的抽象,是一種模闆設計,接口是行為的抽象,是一種行為的規範。
相同點
- 接口和抽象類都不能執行個體化
- 都位于繼承的頂端,用于被其他實作或繼承
- 都包含抽象方法,其子類都必須覆寫這些抽象方法
參數 | 抽象類 | 接口 |
聲明 | 抽象類使用abstract關鍵字聲明 | 接口使用interface關鍵字聲明 |
實作 | 子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有聲明的方法的實作 | 子類使用implements關鍵字來實作接口。它需要提供接口中所有聲明的方法的實作 |
構造器 | 抽象類可以有構造器 | 接口不能有構造器 |
通路修飾符 | 抽象類中的方法可以是任意通路修飾符 | 接口方法預設修飾符是public。并且不允許定義為 private 或者protected |
多繼承 | 一個類最多隻能繼承一個抽象類 | 一個類可以實作多個接口 |
字段聲明 | 抽象類的字段聲明可以是任意的 | 接口的字段預設都是 static 和 final |
備注: Java8中接口中引入預設方法和靜态方法,以此來減少抽象類和接口之間 的差異。
現在,我們可以為接口提供預設實作的方法了,并且不用強制子類來實作它。 接口和抽象類各有優缺點,在接口和抽象類的選擇上,必須遵守這樣一個原則:
- 行為模型應該總是通過接口而不是抽象類定義,是以通常是優先選用接口,盡量 少用抽象類。
- 選擇抽象類的時候通常是如下情況:需要定義子類的行為,又要為子類提供通用 的功能。
普通類和抽象類有哪些差別?
普通類不能包含抽象方法,抽象類可以包含抽象方法。
抽象類不能直接執行個體化,普通類可以直接執行個體化。
抽象類能使用 final 修飾嗎?