天天看點

Java的接口、類、屬性、方法的修飾符使用總結

前言知識,在一些資料中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也不知道擷取哪個超類的變量。

Java的接口、類、屬性、方法的修飾符使用總結

【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 修飾嗎?

繼續閱讀