最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

全面解讀Java編程中的內(nèi)部類

 更新時(shí)間:2015年09月27日 15:32:20   投稿:goldensun  
這篇文章主要介紹了Java的內(nèi)部類,包括類成員訪問等Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下

Java內(nèi)部類及其實(shí)例化
在 Java 中,允許在一個類(或方法、語句塊)的內(nèi)部定義另一個類,稱為內(nèi)部類(Inner Class),有時(shí)也稱為嵌套類(Nested Class)。

內(nèi)部類和外層封裝它的類之間存在邏輯上的所屬關(guān)系,一般只用在定義它的類或語句塊之內(nèi),實(shí)現(xiàn)一些沒有通用意義的功能邏輯,在外部引用它時(shí)必須給出完整的名稱。

使用內(nèi)部類的主要原因有:
內(nèi)部類可以訪問外部類中的數(shù)據(jù),包括私有的數(shù)據(jù)。
內(nèi)部類可以對同一個包中的其他類隱藏起來。
當(dāng)想要定義一個回調(diào)函數(shù)且不想編寫大量代碼時(shí),使用匿名(anonymous)內(nèi)部類比較便捷。
減少類的命名沖突。

請看下面的例子:

public class Outer {
  private int size;
  public class Inner {
    private int counter = 10;
    public void doStuff() {
      size++;
    }
  }
  public static void main(String args[]) {
    Outer outer = new Outer();
    Inner inner = outer.new Inner();
    inner.doStuff();
    System.out.println(outer.size);
    System.out.println(inner.counter);
    // 編譯錯誤,外部類不能訪問內(nèi)部類的變量
    System.out.println(counter);
  }
}

這段代碼定義了一個外部類 Outer,它包含了一個內(nèi)部類 Inner。將錯誤語句注釋掉,編譯,會生成兩個 .class 文件:Outer.class 和 Outer$Inner.class。也就是說,內(nèi)部類會被編譯成獨(dú)立的字節(jié)碼文件。

內(nèi)部類是一種編譯器現(xiàn)象,與虛擬機(jī)無關(guān)。編譯器將會把內(nèi)部類翻譯成用 $ 符號分隔外部類名與內(nèi)部類名的常規(guī)類文件,而虛擬機(jī)則對此一無所知。

注意:必須先有外部類的對象才能生成內(nèi)部類的對象,因?yàn)閮?nèi)部類需要訪問外部類中的成員變量,成員變量必須實(shí)例化才有意義。

內(nèi)部類是 Java 1.1 的新增特性,有些程序員認(rèn)為這是一個值得稱贊的進(jìn)步,但是內(nèi)部類的語法很復(fù)雜,嚴(yán)重破壞了良好的代碼結(jié)構(gòu), 違背了Java要比C++更加簡單的設(shè)計(jì)理念。

內(nèi)部類看似增加了—些優(yōu)美有趣,實(shí)屬沒必要的特性,這是不是也讓Java開始走上了許多語言飽受折磨的毀滅性道路呢?本教程并不打算就這個問題給予一個肯定的答案。

Java靜態(tài)內(nèi)部類、匿名內(nèi)部類、成員式內(nèi)部類和局部內(nèi)部類
內(nèi)部類可以是靜態(tài)(static)的,可以使用 public、protected 和 private 訪問控制符,而外部類只能使用 public,或者默認(rèn)。
成員式內(nèi)部類

在外部類內(nèi)部直接定義(不在方法內(nèi)部或代碼塊內(nèi)部)的類就是成員式內(nèi)部類,它可以直接使用外部類的所有變量和方法,即使是 private 的。外部類要想訪問內(nèi)部類的成員變量和方法,則需要通過內(nèi)部類的對象來獲取。

請看下面的代碼:

public class Outer{
  private int size;
  public class Inner {
    public void dostuff() {
      size++;
    }
  }
  public void testTheInner() {
    Inner in = new Inner();
    in.dostuff();
  }
}

成員式內(nèi)部類如同外部類的一個普通成員。

成員式內(nèi)部類可以使用各種修飾符,包括 public、protected、private、static、final 和 abstract,也可以不寫。

若有 static 修飾符,就為類級,否則為對象級。類級可以通過外部類直接訪問,對象級需要先生成外部的對象后才能訪問。

非靜態(tài)內(nèi)部類中不能聲明任何 static 成員。

內(nèi)部類可以相互調(diào)用,例如:

class A {
  // B、C 間可以互相調(diào)用
  class B {}
  class C {}
}


成員式內(nèi)部類的訪問

內(nèi)部類的對象以成員變量的方式記錄其所依賴的外層類對象的引用,因而可以找到該外層類對象并訪問其成員。該成員變量是系統(tǒng)自動為非 static 的內(nèi)部類添加的,名稱約定為“outClassName.this”。

1) 使用內(nèi)部類中定義的非靜態(tài)變量和方法時(shí),要先創(chuàng)建外部類的對象,再由“outObjectName.new”操作符創(chuàng)建內(nèi)部類的對象,再調(diào)用內(nèi)部類的方法,如下所示:

public class Demo{
  public static void main(String[] args) {
    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();
    inner.dostuff();
  }
}
class Outer{
  private int size;
  class Inner{
    public void dostuff() {
      size++;
    }
  }
}

2) static 內(nèi)部類相當(dāng)于其外部類的 static 成員,它的對象與外部類對象間不存在依賴關(guān)系,因此可直接創(chuàng)建。示例如下:

public class Demo{
  public static void main(String[] args) {
    Outer.Inner inner = new Outer.Inner();
    inner.dostuff();
  }
}
class Outer{
  private static int size;
  static class Inner {
    public void dostuff() {
      size++;
      System.out.println("size=" + size);
    }
  }
}

運(yùn)行結(jié)果:

size=1

3) 由于內(nèi)部類可以直接訪問其外部類的成分,因此當(dāng)內(nèi)部類與其外部類中存在同名屬性或方法時(shí),也將導(dǎo)致命名沖突。所以在多層調(diào)用時(shí)要指明,如下所示:

public class Outer{
  private int size;
  public class Inner{
    private int size;
    public void dostuff(int size){
      size++; // 局部變量 size;
      this.size; // 內(nèi)部類的 size
      Outer.this.size++; // 外部類的 size
    }
  }
}

局部內(nèi)部類

局部內(nèi)部類(Local class)是定義在代碼塊中的類。它們只在定義它們的代碼塊中是可見的。

局部類有幾個重要特性:

  • 僅在定義了它們的代碼塊中是可見的;
  • 可以使用定義它們的代碼塊中的任何局部 final 變量;
  • 局部類不可以是 static 的,里邊也不能定義 static 成員;
  • 局部類不可以用 public、private、protected 修飾,只能使用缺省的;

局部類可以是 abstract 的。

請看下面的代碼:

public class Outer {
  public static final int TOTAL_NUMBER = 5;
  public int id = 123;
  public void func() {
    final int age = 15;
    String str = "http://www.weixueyuan.net";
    class Inner {
      public void innerTest() {
        System.out.println(TOTAL_NUMBER);
        System.out.println(id);
        // System.out.println(str);不合法,只能訪問本地方法的final變量
        System.out.println(age);
      }
    }
    new Inner().innerTest();
  }
  public static void main(String[] args) {
    Outer outer = new Outer();
    outer.func();
  }
}

運(yùn)行結(jié)果:

5
123
15


匿名內(nèi)部類

匿名內(nèi)部類是局部內(nèi)部類的一種特殊形式,也就是沒有變量名指向這個類的實(shí)例,而且具體的類實(shí)現(xiàn)會寫在這個內(nèi)部類里面。

注意:匿名類必須繼承一個父類或?qū)崿F(xiàn)一個接口。

不使用匿名內(nèi)部類來實(shí)現(xiàn)抽象方法:

abstract class Person {
  public abstract void eat();
}
class Child extends Person {
  public void eat() {
    System.out.println("eat something");
  }
}
public class Demo {
  public static void main(String[] args) {
    Person p = new Child();
    p.eat();
  }
}

運(yùn)行結(jié)果:

eat something

可以看到,我們用Child繼承了Person類,然后實(shí)現(xiàn)了Child的一個實(shí)例,將其向上轉(zhuǎn)型為Person類的引用。但是,如果此處的Child類只使用一次,那么將其編寫為獨(dú)立的一個類豈不是很麻煩?

這個時(shí)候就引入了匿名內(nèi)部類。使用匿名內(nèi)部類實(shí)現(xiàn):

abstract class Person {
  public abstract void eat();
}
public class Demo {
  public static void main(String[] args){
    
    // 繼承 Person 類
    new Person() {
      public void eat() {
        System.out.println("eat something");
      }
    }.eat();
  }
}


可以看到,匿名類繼承了 Person 類并在大括號中實(shí)現(xiàn)了抽象類的方法。

內(nèi)部類的語法比較復(fù)雜,實(shí)際開發(fā)中也較少用到,本教程不打算進(jìn)行深入講解,各位讀者也不應(yīng)該將內(nèi)部類作為學(xué)習(xí)Java的重點(diǎn)。

相關(guān)文章

  • Java引用類型interface的用法總結(jié)

    Java引用類型interface的用法總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Java中引用類型interface的用法的相關(guān)資料,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java有一定幫助,感興趣的可以了解一下
    2022-10-10
  • Java連接redis報(bào)錯timed?out問題的解決辦法

    Java連接redis報(bào)錯timed?out問題的解決辦法

    最近項(xiàng)目開發(fā)中用到了Redis,下面這篇文章主要給大家介紹了關(guān)于Java連接redis報(bào)錯timed?out問題的解決辦法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入

    Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • Java實(shí)現(xiàn)Redis分布式鎖的三種方案匯總

    Java實(shí)現(xiàn)Redis分布式鎖的三種方案匯總

    setnx、Redisson、RedLock?都可以實(shí)現(xiàn)分布式鎖,從易到難得排序?yàn)椋簊etnx?<?Redisson?<?RedLock,本文為大家整理了三種方法的實(shí)現(xiàn),希望對大家有所幫助
    2023-11-11
  • SpringCloud配置動態(tài)更新原理解析

    SpringCloud配置動態(tài)更新原理解析

    在微服務(wù)架構(gòu)的浩瀚星海中,服務(wù)配置的動態(tài)更新如同魔法一般,能夠讓應(yīng)用在不重啟的情況下,實(shí)時(shí)響應(yīng)配置的變更,Spring Cloud作為微服務(wù)架構(gòu)中的佼佼者,其動態(tài)配置更新的能力尤為引人注目,本文給大家介紹了SpringCloud配置動態(tài)更新原理,需要的朋友可以參考下
    2025-01-01
  • Java父類繼承中的static和final用法

    Java父類繼承中的static和final用法

    這篇文章主要介紹了Java父類繼承中的static和final用法說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java+mysql本地圖片上傳數(shù)據(jù)庫及下載示例

    Java+mysql本地圖片上傳數(shù)據(jù)庫及下載示例

    本篇文章主要介紹了Java+mysql本地圖片上傳數(shù)據(jù)庫及下載示例,具有一定的參加價(jià)值,有興趣的可以了解一下。
    2017-01-01
  • idea創(chuàng)建的idea項(xiàng)目時(shí)springframework出現(xiàn)紅色的原因和解決方法

    idea創(chuàng)建的idea項(xiàng)目時(shí)springframework出現(xiàn)紅色的原因和解決方法

    當(dāng)使用 IntelliJ IDEA 創(chuàng)建 Spring Framework 項(xiàng)目時(shí),springframework 出現(xiàn)紅色可能是因?yàn)橄嚓P(guān)的 Spring Framework 依賴沒有正確加載或項(xiàng)目的配置有問題,本文給大家介紹了一些常見的原因和解決方法,需要的朋友可以參考下
    2023-09-09
  • 解決springboot報(bào)錯找不到自動注入的service問題

    解決springboot報(bào)錯找不到自動注入的service問題

    這篇文章主要介紹了解決springboot報(bào)錯找不到自動注入的service問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java實(shí)現(xiàn)打字游戲小程序

    java實(shí)現(xiàn)打字游戲小程序

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)打字游戲小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10

最新評論

潞城市| 定远县| 平度市| 东台市| 金湖县| 崇明县| 美姑县| 邮箱| 长兴县| 金华市| 南城县| 武宣县| 屏东市| 启东市| 漳浦县| 运城市| 精河县| 敦煌市| 巴东县| 贵溪市| 汝南县| 曲周县| 泸定县| 成都市| 固安县| 泊头市| 花垣县| 屏南县| 宜丰县| 金昌市| 高要市| 景德镇市| 新巴尔虎右旗| 达孜县| 永平县| 甘南县| 万源市| 彰化市| 青龙| 紫云| 枣强县|