Java 嵌套類

2018-02-20 01:36 更新

Java教程 - Java嵌套類


在任何類外部聲明的類是頂級類。嵌套類是聲明為其他類或作用域的成員的類。

有四種嵌套類:

  • 靜態(tài)成員類
  • 非靜態(tài)成員類
  • 匿名類
  • 局部類

Java匿名類

匿名類是沒有名稱并同時聲明的類。您可以實例化一個匿名類,在其中指定一個表達(dá)式是合法的。

一個匿名類實例只能訪問局部最終變量和最終參數(shù)。

如何定義一個匿名類?

abstract class People {
  abstract void speak();
}

public class Main {
  public static void main(final String[] args) {
    new People() {
      String msg = "test";

      @Override
      void speak() {
        System.out.println(msg);
      }
    }.speak();
  }
}

上面的代碼生成以下結(jié)果。


例子

下面的代碼聲明和實例化一個實現(xiàn)接口的匿名類。

interface People {
  abstract void speak();
}

public class Main {
  public static void main(final String[] args) {
    new People() {
      String msg = (args.length == 1) ? args[0] : "nothing to say";

      @Override
      public void speak() {
        System.out.println(msg);
      }
    }.speak();
  }
}

上面的代碼生成以下結(jié)果。

Java局部類

本地類是在聲明局部變量的任何地方聲明的類。局部類與局部變量具有相同的范圍。

一個本地類有一個名稱,可以重復(fù)使用。本地類實例可以訪問周圍范圍的本地最終變量和最終參數(shù)。

Java局部類

class MyClass {
  void myMethod(final int x) {
    final int y = x;
    
    class LocalClass {
      int a = x;
      int b = y;
    }
    
    LocalClass lc = new LocalClass();
    System.out.println(lc.a);
    System.out.println(lc.b);
  }
}

public class Main {
  public static void main(String[] args) {
    MyClass ec = new MyClass();
    ec.myMethod(10);
  }
}

上面的代碼生成以下結(jié)果。

例2

下面的代碼聲明了一個Iterator接口和Iter內(nèi)部類。

class Item{
  private String name;
  private String value;
  
  public Item(String n, String v){
    name = n;
    value = v;
  }
  public String toString(){
    return name + value;
  }
}

interface Iterator {
  boolean hasMoreElements();

  Object nextElement();
}

class ItemManager {
  private Item[] itemArray;
  private int index = 0;

  ItemManager(int size) {
    itemArray = new Item[size];
  }

  Iterator iterator() {
    class Iter implements Iterator {
      int index = 0;

      @Override
      public boolean hasMoreElements() {
        return index < itemArray.length;
      }

      @Override
      public Object nextElement() {
        return itemArray[index++];
      }
    }
    return new Iter();
  }

  void add(Item item) {
    itemArray[index++] = item;
  }
}

public class Main {
  public static void main(String[] args) {
    ItemManager itemManager = new ItemManager(5);
    itemManager.add(new Item("#1", "A"));
    itemManager.add(new Item("#2", "B"));
    itemManager.add(new Item("#3", "C"));
    Iterator iter = itemManager.iterator();
    while (iter.hasMoreElements()){
      System.out.println(iter.nextElement());
    }
      
  }
}

輸出:

Java成員類

成員類是封閉類的成員。成員類的每個實例都與封閉類的實例相關(guān)聯(lián)。

成員類的實例方法可以調(diào)用實例方法封閉類和訪問封閉類實例的非靜態(tài)字段。

以下代碼具有一個名為 EnclosingClass 的外部類和非靜態(tài)成員類命名為 EnclosedClass 。

class EnclosingClass {
  private int outerVariable;

  private void privateOuterMethod() {
    System.out.println(outerVariable);
  }

  class EnclosedClass {
    void accessEnclosingClass() {
      outerVariable = 1;
      privateOuterMethod();
    }
  }
}

public class Main {
  public static void main(String[] args) {
    EnclosingClass ec = new EnclosingClass();
    ec.new EnclosedClass().accessEnclosingClass(); // Output: 1
  }
}

上面的代碼生成以下結(jié)果。

例3

下面的代碼使用內(nèi)部類ItemList來存儲項目。

class Item {
  private String name;
  private String desc;

  Item(String name, String desc) {
    this.name = name;
    this.desc = desc;
  }

  String getName() {
    return name;
  }

  String getDesc() {
    return desc;
  }

  @Override
  public String toString() {
    return "Name = " + getName() + ", Desc = " + getDesc();
  }
}

class ItemManager {
  private ItemList itemList;
  private int index = 0;

  ItemManager() {
    itemList = new ItemList(2);
  }

  boolean hasMoreElements() {
    return index < itemList.size();
  }

  Item nextElement() {
    return itemList.get(index++);
  }

  void add(Item item) {
    itemList.add(item);
  }

  private class ItemList {
    private Item[] itemArray;
    private int index = 0;

    ItemList(int initSize) {
      itemArray = new Item[initSize];
    }

    void add(Item item) {
      if (index >= itemArray.length) {
        Item[] temp = new Item[itemArray.length * 2];
        for (int i = 0; i < itemArray.length; i++)
          temp[i] = itemArray[i];
        itemArray = temp;
      }
      itemArray[index++] = item;
    }

    Item get(int i) {
      return itemArray[i];
    }

    int size() {
      return index;
    }
  }
}

public class Main {
  public static void main(String[] args) {
    ItemManager itemManager = new ItemManager();
    itemManager.add(new Item("1", "A"));
    itemManager.add(new Item("2", "B"));
    itemManager.add(new Item("3", "C"));
    while (itemManager.hasMoreElements())
      System.out.println(itemManager.nextElement());
  }
}

上面的代碼生成以下結(jié)果。

例4

以下程序說明如何定義和使用內(nèi)部類。

 
class Outer {
  int outer_x = 100;
  void test() {
    Inner inner = new Inner();
    inner.display();
  }
  class Inner {
    void display() {
      System.out.println("display: outer_x = " + outer_x);
    }
  }
}
public class Main {
  public static void main(String args[]) {
    Outer outer = new Outer();
    outer.test();
  }
}

此應(yīng)用程序的輸出如下所示:

例5

內(nèi)部類成員只能在內(nèi)部類中訪問,并且可能不被外部類使用。如果您嘗試編譯以下代碼,您將收到錯誤消息。

 
public class Main {
  int outer_x = 100;
  // this is an inner class
  class Inner {
    int y = 10; // y is local to Inner

    void display() {
      System.out.println("display: outer_x = " + outer_x);
    }
  }

  void showy() {
    System.out.println(y); 
  }
}

當(dāng)編譯上面的代碼:

Java靜態(tài)成員類

靜態(tài)成員類是封閉類的靜態(tài)成員。靜態(tài)成員類不能訪問包含類的實例字段并調(diào)用其實例方法。

靜態(tài)成員可以訪問包含類的靜態(tài)字段并調(diào)用其靜態(tài)方法,包括私有字段和方法。

下面的代碼有一個靜態(tài)成員類聲明。

class Demo {
  public static void main(String[] args) {
    Main.EnclosedClass.accessEnclosingClass(); 
    Main.EnclosedClass ec = new Main.EnclosedClass();
    ec.accessEnclosingClass2(); 
  }
}

class Main {
  private static int outerVariable;

  private static void privateStaticOuterMethod() {
    System.out.println(outerVariable);
  }

  static void staticOuterMethod() {
    EnclosedClass.accessEnclosingClass();
  }

  static class EnclosedClass {
    static void accessEnclosingClass() {
      outerVariable = 1;
      privateStaticOuterMethod();
    }

    void accessEnclosingClass2() {
      staticOuterMethod();
    }
  }
}

靜態(tài)成員類可以聲明其封閉類的多個實現(xiàn)。

例6

下面的代碼聲明一個 Rectangle 類,它使用靜態(tài)成員類為不同的數(shù)據(jù)類型提供 Rectangle 實現(xiàn),一個是 double 類型另一個是 float 類型。

abstract class Rectangle {
  abstract double getX();

  abstract double getY();

  abstract double getWidth();

  abstract double getHeight();

  static class Double extends Rectangle {
    private double x, y, width, height;

    Double(double x, double y, double width, double height) {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
    }

    double getX() {
      return x;
    }

    double getY() {
      return y;
    }

    double getWidth() {
      return width;
    }

    double getHeight() {
      return height;
    }
  }

  static class Float extends Rectangle {
    private float x, y, width, height;

    Float(float x, float y, float width, float height) {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
    }

    double getX() {
      return x;
    }

    double getY() {
      return y;
    }

    double getWidth() {
      return width;
    }

    double getHeight() {
      return height;
    }
  }

  private Rectangle() {
  }

  boolean contains(double x, double y) {
    return (x >= getX() && x < getX() + getWidth()) && (y >= getY() && y < getY() + getHeight());
  }
}

public class Main {
  public static void main(String[] args) {
    Rectangle r = new Rectangle.Double(10.0, 10.0, 20.0, 30.0);
    r = new Rectangle.Float(10.0f, 10.0f, 20.0f, 30.0f);
  }
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號