java_嵌套类(Nested Classes)

来源:互联网 发布:c# 网络编程视频教程 编辑:程序博客网 时间:2024/06/07 14:26

 1.java语言允许在一个类中定义另一个类。这种类被称为嵌套类。

class OuterClass {    ...    class NestedClass {        ...    }}


Terminology: 嵌套类被分为两类:静态和非静态;被声明为静态的嵌套类被叫做静态嵌套类,非静态的嵌套类被称作内部类。     
class  OuterClass {    ...    static class StaticNestedClass {        ...    }    class InnerClass {        ...    }     }        

          嵌套类是包围它的类的一个成员.。非静态嵌套类(内部类)能够访问它的包围类的其他成员,即使这些成员被声明为私有的。静态嵌套类不能访问它的包围类的其他成员。嵌套类作为外部类的成员之一,可以被声明为private,public,protected,or  package private (default) .(注意外部类只能被声明为public或者package private)。

        注意:protected :只有在当前类和他的继承类中才能访问。

2.我们为什么使用嵌套类?

  • 将类在逻辑上分组的方式之一:如果一个类只对哦另外一个类有用,在逻辑上能够嵌入另一个类,让它们两个类在一块,嵌套这样的帮助类使他们的包内结构更加精简

  • 增强封装性:考虑两个顶层的类 A 和 B, B如果将要访问A中被声明为private 的变量. 通过将B隐藏在A中, B作为A的一个成员,A的成员能被设置为private,并且B能够访问他们,而且B自身能够相对于外面的世界而言隐藏自己。

  • 增强代码的可读性和可维护性: 嵌套小的类在顶层类中能够把代码放到使用它的更近的位置。


3.静态嵌套类

          就这种类的方法和变量与它的外部类有关(依赖于类)。像静态的方法一样,静态内部类不能直接引用和实例化一个它的外部类的实力或方法。(静态不能访问非静态)只能通过对象引用。

          通过外部类来访访问静态嵌套类。

          

       OuterClass.StaticNestedClass

        创建静态嵌套类的语法如下:

           

      OuterClass.StaticNestedClass nestedObject =         new OuterClass.StaticNestedClass();


   4,内部类 

          就这种类的方法和变量与它的外部类的实例有关(依赖于该类的实例)。它可以直接引用这个对象(实例)的属性和方法。因为内部类与实例有关,所以自身不能定义任何静态成员。

           内部类的实例存在于外部类对象之内。

         

    class OuterClass {        ...        class InnerClass {        ...        }    }

          因为内部类的对象存在于外部类的对象之中,所以,它能直接访问 外部类的成员方法和成员变量。

          实例化内部类的语法如下:

          

     OuterClass.InnerClass innerObject = outerObject.new InnerClass();

5  屏蔽 

         

 public class ShadowTest {    public int x = 0;    class FirstLevel {        public int x = 1;        void methodInFirstLevel(int x) {            System.out.println("x = " + x);            System.out.println("this.x = " + this.x);            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);        }    }    public static void main(String... args) {
        //实例化外部类        ShadowTest st = new ShadowTest();
         //实例化内部类        ShadowTest.FirstLevel fl = st.new FirstLevel();
         //调用内部类的方法,传参数进去        fl.methodInFirstLevel(23);    }}

          

x = 23this.x = 1ShadowTest.this.x = 0

        1,传进内部类的参数屏蔽了内部类的成员变量x,挡在内部类中引用X时,它指向了参数x

        2,引用内部类成员变量X时,用this.表明了他的包含范围。

        3.通过他们所属的外部类的类名.this确定范围引用外部类的成员变量x.

6.序列化

       强烈推荐不要进行内部类的序列化,包括本地内部类和 匿名内部类,当java编译器在编译某种例如内部类的结构时会创造很多的合成结构。




原创粉丝点击