举报投诉联系我们 手机版 热门标签 名动网
您的位置:名动网 > java嵌套类型无法隐藏外层类型 Java 嵌套类

java嵌套类型无法隐藏外层类型 Java 嵌套类

2023-04-14 15:20 Java教程

java嵌套类型无法隐藏外层类型 Java 嵌套类

java嵌套类型无法隐藏外层类型

Java中的嵌套类型是指在一个类中定义另一个类,这样就可以将外部类的成员变量和方法封装起来,使其不能被外部访问。但是,由于Java语言的特性,嵌套类型无法隐藏外层类型。

首先,Java语言本身没有提供对内部类的保护机制,因此外部类中定义的内部类可以直接被外部代码所引用。例如:

public class OuterClass {
    public class InnerClass {
        // ... 
    } 

    public static void main(String[] args) { 
        OuterClass.InnerClass inner = new OuterClass().new InnerClass(); 
    } 
} 

上面的代码中,OuterClass定义了一个内部类InnerClass,但是在main方法中却可以直接通过OuterClass.InnerClass来创建InnerClass对象。这就表明了内部类无法隐藏外层类型。

其次,Java语言本身也不允许在名字上加以区分来区分内部类与外部类。例如:

public class OuterClass { 

    public static class InnerStaticClass { 

    }

    public class InnerNonStaticClass {

    }  

    public static void main(String[] args) {  

        OuterClass.InnerStaticClass innerStatic = new OuterClass.InnerStaticClass();  

        OuterClass.InnerNonStaticClass innerNonStatic = new Outerclass().new InnerNonStaticclass();  

    }  
} 

上面的代码中,Outerclass定义了一个静态内部类InnerStaticclass以及一个非静态内部类InnerNonstaticclass。但是在main方法中却使用相同的语法来创建这两个内部对象。这尽显出Java语言并没有提供对内部对象名字上的保护机制。

Java 嵌套类

Java教程 - Java嵌套类


在任何类外部声明的类是顶级类。嵌套类是声明为其他类或作用域的成员的类。

有四种嵌套类:

  • 静态成员类
  • 非静态成员类
  • 匿名类
  • 局部类

Java匿名类

匿名类是没有名称并同时声明的类。您可以实例化一个匿名类,在其中指定一个表达式是合法的。

一个匿名类实例只能访问局部最终变量和最终参数。

如何定义一个匿名类?

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();
  }
}

上面的代码生成以下结果。


例子

下面的代码声明和实例化一个实现接口的匿名类。

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();
  }
}

上面的代码生成以下结果。

Java局部类

本地类是在声明局部变量的任何地方声明的类。局部类与局部变量具有相同的范围。

一个本地类有一个名称,可以重复使用。本地类实例可以访问周围范围的本地最终变量和最终参数。

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);
  }
}

上面的代码生成以下结果。

例2

下面的代码声明了一个Iterator接口和Iter内部类。

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成员类

成员类是封闭类的成员。成员类的每个实例都与封闭类的实例相关联。

成员类的实例方法可以调用实例方法封闭类和访问封闭类实例的非静态字段。

以下代码具有一个名为 EnclosingClass 的外部类和非静态成员类命名为 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
  }
}

上面的代码生成以下结果。

例3

下面的代码使用内部类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());
  }
}

上面的代码生成以下结果。

例4

以下程序说明如何定义和使用内部类。

 
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();
  }
}

此应用程序的输出如下所示:

例5

内部类成员只能在内部类中访问,并且可能不被外部类使用。如果您尝试编译以下代码,您将收到错误消息。

 
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); 
  }
}

当编译上面的代码:

Java静态成员类

静态成员类是封闭类的静态成员。静态成员类不能访问包含类的实例字段并调用其实例方法。

静态成员可以访问包含类的静态字段并调用其静态方法,包括私有字段和方法。

下面的代码有一个静态成员类声明。

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();
    }
  }
}

静态成员类可以声明其封闭类的多个实现。

例6

下面的代码声明一个 Rectangle 类,它使用静态成员类为不同的数据类型提供 Rectangle 实现,一个是 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);
  }
}
阅读全文
以上是名动网为你收集整理的java嵌套类型无法隐藏外层类型 Java 嵌套类全部内容。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
相关文章
© 2024 名动网 mdwl.vip 版权所有 联系我们