天天看點

Javase基礎part4--final關鍵字和内部類

final關鍵字

Final變量

1.    final變量

final關鍵字可用于聲明便令聲明,一旦該變量聲明,就不可以更改該變量的值。通常由fianl定義的變量為常量

2.    final聲明變量的文法

①:final關鍵字修飾的變量,一般都是全部大寫字母,以區分和常量的差別

       ②:final關鍵字修飾的變量,可以是基本資料類型也可以是引用類型

       ③:final關鍵字修飾的變量不可以在其他任何地方指派,否則會編譯期間就會不通過

       ④:final關鍵字修飾的變量一般要在定義的時候指派,否則是預設值,可能不是你需要的。

       ⑤:final關鍵字修飾的的對象隻能隻能恒定的指向一個對象

       ⑥:一個既被static修飾又被static關鍵字修飾的變量,占據一段不能改變的存儲空間

       ⑦:一個被定義的final的對象引用隻能指向唯一一個對象,不可以将它在指向其他對象,但是一個對象本身的值卻可以被改變的。

       下面就驗證一下7

       publicclass FinalTest {

   privatestatic Random rand = new Random();//産生随機數,每次為final變量指派

   privatefinalinta=rand.nextInt(10);

   privatestaticfinalintb = rand.nextInt(10);

   publicstaticvoid main(String[] args) {

      //第一次擷取final的值

      FinalTest test1 = new FinalTest();

      System.out.println(test1.a);

      System.out.println(test1.b);

      //第二次擷取final的值

      FinalTest test2 = new FinalTest();

      System.out.println(test2.a);

      System.out.println(test2.b);

   }

}

運作結果如下

2

8

可以看到static final定義的在每次運作的時候都不變,可是final定義的隻能是在當次運作之中不變。是以通常真正做到不變,需要用staticfinal修飾

Final方法

關于final方法,我隻想說一句,就是final定義的方法是不能被重寫的。即将方法定義為final,子類繼承父類的時候是不能重寫這個方法的。我們都知道權限修飾符private修飾的方法不能被重寫,也就是說其實private修飾的方法隐式定義了final

Final類

定義final的類不允許被繼承,final類中所有的方法都被隐式的設定為final方法,但是變量可以是final的或者是非final的。比如String就是final修飾的類,是不可以被繼承的。

格式如下:

       final類名{}

内部類

       什麼是内部類?

              将在類中定義的那個類稱為内部類,内部類可以分為成員内部類、局部内部類以及匿名内部類

成員内部類

      ◆什麼是成員内部類

              成員内部類,就是在類中定義一個類,并且這個類和成員變量以及成員方法并列,而不是存在于方法中這個就是成員内部類,

◆成員内部類的文法:

       public classOutClass{///外部類

              private classInnerClass{//内部類

}

}

      ◆内部類的注意事項:

              ①:在内部類中可以随便使用外部類的成員變量和成員方法,即使這些成員被修飾為private

              ②:内部類的執行個體化一定要綁定在外部類的執行個體上,

              ③:内部類可以通路外部類成員,但是内部類的成員隻能在内部類範圍内有效,不能被外部類使用。

◆内部類的例子

public class OutClass {

       privateString str = "我是内部類";//修飾為私有

       InnerClassin = new InnerClass();

       publicvoid out(){

              //a=4;不能直接調用内部類的成員

              in.info();

       }

       classInnerClass{

              inta = 0;

              publicvoid info(){

        System.out.println(str);//直接調用外部類的成員

              }

       }

       publicstatic void main(String[] args) {

              OutClasso = new OutClass();

              o.out();

       }

}

運作結果為:

我是内部類

◆内部類的應用場景

1.向上轉型為接口

       如果将一個權限修飾符為private的内部類,向上轉型為其父類,或者轉型為一個接口,就可以在一個程式中隐藏内部類的實作細節。

public class DemoOut {

       publicstatic void main(String[] args) {

              Outout = new Out();

              OutInterfaceinter = out.getInnerClass();

              inter.desc();

       }

}

interface OutInterface{

       publicvoid desc();

}

class Out {

   class InnerClassimplements OutInterface{

              publicInnerClass(String message){

                     System.out.println(message);

      }

      @Override

              publicvoid desc() {

                     System.out.println("内部類的方法");

              }

       }

       publicInnerClass getInnerClass(){

              returnnew InnerClass("得到内部類的對象");

       }

}

運作結果為:

       得到内部類的對象

内部類的方法

這樣做就很好的隐藏了接口中的方法的具體邏輯

局部内部類

◆什麼是局部内部類

              就是在類中的局部位置定義一個類,比如方法或者任意的作用域。

◆局部内部類的文法

              public classOutClass{///外部類

                  public void aa(){

                            class InnerClass{//内部類

}

                            }

}

◆局部内部類注意的事項

       ①:同成員内部類

       ②:如果成員内部類使用方法内的變量或形參,必須将這個變量聲明為final的。這是為了讓該變量超出方法的運作的聲明周期。

◆局部内部類的應用執行個體

public class JuBuNeiBuLei {

       publicvoid aa(final String str){

              classInnerClass {

                     publicInnerClass(String message){

                            System.out.println(message+str);

                     }

              }

       }

}

可以看到内部類引用形參必須是final的。

◆為什麼局部内部類用的局部變量和形參必須是final修飾的。

       因為方法中的局部變量和形參,在方法結束之後就會被銷毀,而此時局部内部類還有可能沒有用到這個變量。

       下面就舉出一個這個例子:

              publicclass JuBuNeiBuLei {

       publicOutInterface2 aa(final String str){

              finalString str1 = "局部變量";

              classInnerClass implements OutInterface2{

                     publicInnerClass (String message){

                            System.out.println(message+str+str1);

                     }

                     @Override

                     publicvoid desc() {

                            System.out.println(str+str1);

                     }

              }

              System.out.println("方法結束了");

              returnnew InnerClass("得到内部類的對象");

       }

       publicstatic void main(String[] args) {

              OutInterface2a = new JuBuNeiBuLei().aa("形參");//到這裡局部内部類引用并沒有用,可是外部類方法

                     //已經結束了。正常來說,形參和局部變量都被銷毀了,那麼下面的内部類是不能用的了,可是聲明為final,方法結束之後,變量

                     //就不會被銷毀了

              a.desc();

       }

}

interface OutInterface2{

       publicvoid desc();

}

運作結果為:

       方法結束了

得到内部類的對象形參局部變量

形參局部變量

匿名内部類

◆什麼是匿名内部類:

       匿名内部類就是沒有名字的内部類。當我們在使用一個接口或者抽象類的時候,由于他們的内部方法是沒有邏輯的,而且是不能執行個體化的,是以我們可以通過繼承來寫出這個方法的邏輯。但是,是不是可以不用繼承也能直接實作接口中方法的邏輯呢?答案是可以的,這個方式就是匿名内部類,這次大家明白了為什麼叫匿名内部類了吧,因為它沒有實作類,而是直接用一種文法實作沒有方法的邏輯體

◆匿名内部類的文法:

       publicvoid test(){

              new接口名 (){

                     邏輯

                     沒有實作的方法

};

       }

大家可以看到文法中直接new了一個接口,可是接口是不能new的呀,其實這個不是new的接口,而是它的實作類,隻不過這個實作類沒有名字,而是直接實作了這個接口中的方法

◆匿名内部類的注意事項

       ①:同局部内部類

       ②:定義内部類的前提是必須有一個接口或者抽象類,讓他實作

       ③:實作的接口方法不應該定義過多,否則在用匿名内部類的時候,就會導緻重寫的方法過多,進而影響代碼的可讀性和整潔性

       ④:匿名内部類其實就是一個匿名的實作了某一接口的子類對象。

◆匿名内部類的例子

       publicclass JuBuNeiBuLei {

       publicstatic void main(String[] args) {

              OutInterface2  b = new OutInterface2(){

                     @Override

                     publicvoid desc() {

                            System.out.println("我是匿名内部類");

                     }

              };

              b.desc();

       }

}

interface OutInterface2{

       publicvoid desc();

}

◆匿名内部類的應用

       匿名内部類通常應用在句柄函數中。具體的例子就等大家接觸之後會明白的,比如集合中排序的時候,按照自己的定義規則排序,就有一個實作某接口