Nested Classes
来源:互联网 发布:杨裕生 铅酸 知乎 编辑:程序博客网 时间:2024/06/06 12:37
嵌套类(nested classes)
在Java应用程序语言中允许在一个类中定义另外一个类,这样的类叫做嵌套类:
class OuterClass {//外部类,顶级类 ... class NestedClass {//嵌套类 ... }}
嵌套类的分类
特别的,嵌套类可以分为静态和非静态的。声明为静态的叫做静态嵌套类(static nested classes),而非静态的可以分为inner class ,local classes anonymous classpublic class OuterClass {//顶级类,外部类 interface HelloWorld { void greet(); void greetSomeone(String someone); } /** * 静态嵌套类 */ static class StaticNestedClass { } /** * 内部类 * */ class InnerClass { } public void sayHello() { /*** *局部类 */ class LocalClass implements HelloWorld { String name = "world"; public void greet() { greetSomeone("world"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hello " + name); } } HelloWorld englishGreeting = new LocalClass(); /** * 匿名类 * */ HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } }; englishGreeting.greet(); frenchGreeting.greetSomeone("Fred"); } public static void main(String... args) { OuterClass myApp = new OuterClass(); myApp.sayHello(); }}
为什么使用嵌套类
- 对于那种仅在一个地方使用的类,嵌套的方式是一种很好的逻辑分组方式。假如一个类只对其他类中的一个类有用,这是非常符合逻辑的将这个类嵌套在那个使用它的类里面,使他们连在一起。嵌套就好像是一个“帮助类”一样,使他们的封装更加的简化
- 增加封闭性。考虑一下这样的情景,两个顶级类A和B,在类B中要用权限能够使用到A的组成成分(域/方法),那么对于A的组成成分要么暴露(public)出来(get/set也是),要么不给B这个权限(private)。(个人理解:类A中组成成分只想给类B使用)。那么,可以通过将类B嵌套在类A中,A的组成成分就可以声明为private,类B又能有权限使用到,还有,对于类B,它也可以对除了类A之外的其他类隐藏(也就是声明为private)
- 增加代码的可读性和可维护性。在顶级类中嵌套的类 ,嵌套类的代码更加接近它被使用的地方。(离得近)
静态嵌套类(static nested classes)
package com.company;import java.util.Random;/** *① 可以使用访问修饰符 *②对外部类方法和域的权限:对声明为static的域和方法有使用权限,即使它们申明为private *③是否可以在类中创建static的域和method 可以,也可以声明接口 */public class StaticNestedClassTest { static int i = 0; int a = 0; final static Object o = new Random(); private static void method1() { } public static void method2() { } public void method3() { } /** * static nested classes 可以使用访问修饰符修饰,可以访问到外部类的static 域和方法,在static nested classes内部可以创建任何东西 * 就像是另外的一个顶级类一样使用,不过static nested classes却可以访问它外部类的一些private的静态域和方法,而其他的顶级类却不能 * */ static class StaticNestedClass { static int s = 0; Object object = new Object(); private static void method4() { System.out.println(i);//可以引用外部类中的静态域// System.out.println(a);//非静态类型的a不能在一个静态环境中引用 System.out.println(o.toString());//引用外部类静态常量 method1();//外部类的静态方法,即使它申明为private method2();// method3();//非静态方法不能在一个静态环境中引用 } public void method5() { System.out.println(i);// System.out.println(a);//非静态类型的a不能在一个静态环境中引用 method1(); method2();// method3();//非静态方法不能在一个静态环境中引用 } interface Test{ } class Test1 { } } /** * 除了StaticNestedClassTest类之外的类,其他类无法访问到这个私有的StaticNestedClass1 * */ private static class StaticNestedClass1{ } public static void main(String[] args) { //创建一个静态嵌套类实例 StaticNestedClassTest.StaticNestedClass staticNestedClass = new StaticNestedClassTest.StaticNestedClass(); }}
non-static nested classes
inner classes
package com.company;import java.util.Random;/** *①可以使用访问修饰符 *②对外部类方法和域的权限:所有的方法和域都有使用权,即使声明为private *③是否可以在类中创建static的域和method 不可以,(可以声明全局常量,基本数据类和String 的final static String s = "sad"; final static int g = 0;) 也不可以声明接口 * 相关:A constant variable is a variable of primitive type or type String that is declared final and initialized with a compile-time constant expression. * A compile-time constant expression is typically a string or an arithmetic expression that can be evaluated at compile time. * 涉及到编译时。不解释 ,知道就ok */public class InnerClassTest { static int i = 0; private int a = 0; final static Object o = new Random(); private static void method1() { } public static void method2() { } public void method3() { } /** * InnerClass 可以使用访问修饰符修饰 */ public class InnerClass { private void method4() { /** * 可以使用外部类的所用域和方法,即使是private, * */ System.out.println(i); System.out.println(a); System.out.println(o.toString()); method1(); method2(); method3(); } //不可以在inner class中有静态的声明// private static void method5(){//// }// static int a;// interface test{//// }//interface 在本质上市static属性的,所以也是不可以 /** * 对于像基本类型,String 这两种情况,因为本身它们是属于常量 * 被final static 修饰的变量可以认为是全局的常量, * 很明显,s g ob 都是一个常量,但是s g 指向的实例对象依旧还是常量,而ob指向的确不是 * */ final static String s = "sad"; final static int g = 0; //不可以在inner class中有静态的声明// final static Object ob = new Random(); /** * 为什么在innerclass中不可以有static的方法和变量和一些常量,因为在inner class中是包含有一个 * 外部类对象实例的,要不是就不能够直接的访问到外部类的域和方法了,而static nested class里面没有包含 * 它外部类的实例对象所以他只能使用到static的域和方法 * */ } class InnerClass1 { }}
创建实例:
package com.company;public class Main{ public static void main(String[] args) throws ClassNotFoundException { //报错,提示InnerClass不是一个外部顶级类// InnerClassTest.InnerClass innerClass = new InnerClassTest.InnerClass(); InnerClassTest innerClassTest = new InnerClassTest(); InnerClassTest.InnerClass innerClass = innerClassTest.new InnerClass(); //从这里可以印证:InnerClass 内部是有一个InnerClassTest的实例对象的, //InnerClass 的对象实例 依存它外部类InnerClassTest实例,先有我外部类实例,再有InnerClass实例 }}
local classes
localclass 可以说是inner class 的继续限制版,inner class里面 不能定义static域和方法和一些常量,localclass也是不能的
看列子:
package com.company;import java.util.Random;/** *①不能使用访问修饰符 *②对外部类方法和域的权限:对于在非静态块的localClass 对外部类的所有域和方法都有使用权,(即使声明为private) * 在静态块定义的localClass只对外部类声明为是static的域和方法有使用权(即使声明为private) *③是否可以在类中创建static的域和method 不可以,(可以声明全局常量,基本数据类和String 的final static String s = "sad"; * final static int g = 0;) 也不可以声明接口 * ***即使localClass在static块出定义也不可以 *④对于方法(块)中的局部变量/参数 只有当它们是final/effective final的时候才可以在LocalClass中使用,详细看代码 */public class LocalClassTest { static int i = 0; private int a = 0; final static Object o = new Random(); private static void method1() { } public static void method2() { } public void method3() { } /** * 既然叫局部,当然是不能使用访问修饰符啦 * */ //定义在static 块 中 static { class LocalClass1 { private void method8(){ System.out.println(i);// System.out.println(a);//静态中不能引用非静态的变量 System.out.println(o.toString()); } } } //定义在构造方法中 public LocalClassTest() { class LocalClass2 { } for (int i = 0; i < 5; i++) {//定义在for循环块 中 class LocalClass3 { } } } //定义在普通的方法中 private void method4(int jj,Object ll) { final int aa = 0; int bb = 5;// bb++;// ll = null; //ll 和bb 是effectively final才能被LocalClass使用 。effectively final是在JDK8才出现的,所以8之前的只有final的才能在LocalClass中使用 class LoadClass4 { public void method6() { /** * 可以使用外部类的所用域和方法,即使是private, * */ System.out.println(i); System.out.println(a); System.out.println(o.toString()); method1(); method2(); method3(); /** * 对于包含LocalClass的块的一些局部变量,这些变量要么是final要么是effectively final(这个变量这能赋值一次) * */ System.out.println(jj); System.out.println(ll); System.out.println(aa); System.out.println(bb);// jj++;// ll = null;// bb = 80; } //不可以在inner class中有静态的声明// private static void method5(){//// }// static int a;// interface test{//// }//interface 在本质上市static属性的,所以也是不可以 final static String s = "sad"; final static int g = 0; //不可以在inner class中有静态的声明// final static Object ob = new Random(); } } //定义在static方法中 /** * 这个特殊 */ private static void method5(int jj,Object ll) { final int aa = 0; int bb = 5; class LocalClass5 { private void method7() { System.out.println(i);// System.out.println(a);//静态中不能引用非静态的变量 System.out.println(o.toString()); method1(); method2();// method3();//静态中不能引用非静态的变量 /** * * */ System.out.println(jj); System.out.println(ll); System.out.println(aa); System.out.println(bb);// jj++;// ll = null;// bb = 80; }// 不可以在inner class中有静态的声明// private static void method5() {// }// static int a;// interface test{//// }//interface 在本质上市static属性的,所以也是不可以 final static String s = "sad"; final static int g = 0; //不可以在inner class中有静态的声明// final static Object ob = new Random(); } if (true) {//定义在if块中 class LocalClass6 { } } }}
anonymous classes
package com.company;import java.util.Random;/** * Anonymous classes enable you to make your code more concise. * They enable you to declare and instantiate a class at the same time. * 同时声明和实例化 * They are like local classes except that they do not have a name. * Use them if you need to use a local class only once. * 其实本质上说,anonymousclass是表达式,如 * new HelloWorld() { * String name = "tout le monde"; * <p> * public void greet() { * greetSomeone("tout le monde"); * } * <p> * public void greetSomeone(String someone) { * name = someone; * System.out.println("Salut " + name); * } * }; *表达式包含:①new关键字 ② 要实现的接口或者继承的抽象类③在()中包含构造函数的参数,假如又需要的话 * 用的最多的就是GUI 事件当中 * * */public class AnonymousClassTest { static int i = 0; private int a = 0; final static Object o = new Random(); private static void method1() { } public static void method2() { } public void method3() { } interface HelloWorld { public void greet(); public void greetSomeone(String someone); } abstract class HelloWorldTest { abstract void greet(); abstract void greetSomeone(String someone); } public void sayHello(int jj, Object ll) { final int aa = 0; int bb = 5;// bb++;// ll = null; //ll 和bb 是effectively final才能被LocalClass使用 。effectively final是在JDK8才出现的,所以8之前的只有final的才能在LocalClass中使用 class EnglishGreeting implements HelloWorld { String name = "world"; public void greet() { greetSomeone("world"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hello " + name); } } //使用LocalClass实例化englishGreeting HelloWorld englishGreeting = new EnglishGreeting(); //使用anonymousClass实例化 HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } }; HelloWorld spanishGreeting = new HelloWorld() { String name = "mundo"; public void greet() { greetSomeone("mundo"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hola, " + name); } }; englishGreeting.greet(); frenchGreeting.greetSomeone("Fred"); spanishGreeting.greet(); //使用anonymousClass HelloWorldTest helloWorldTest = new HelloWorldTest() { private void method4() { /** * 可以使用外部类的所用域和方法,即使是private, * */ System.out.println(i); System.out.println(a); System.out.println(o.toString()); method1(); method2(); method3(); /** * 对于包含LocalClass的块的一些局部变量,这些变量要么是final要么是effectively final(这个变量这能赋值一次) * */ System.out.println(jj); System.out.println(ll); System.out.println(aa); System.out.println(bb);// jj++;// ll = null;// bb = 80; } @Override void greet() { } @Override void greetSomeone(String someone) { } //不可以在inner class中有静态的声明// private static void method5(){//// }// static int a;// interface test{//// }//interface 在本质上市static属性的,所以也是不可以 final static String s = "sad"; final static int g = 0; //不可以在inner class中有静态的声明// final static Object ob = new Random(); }; } //使用anonymousClass HelloWorldTest helloWorldTest = new HelloWorldTest() { @Override void greet() { } @Override void greetSomeone(String someone) { } };}
0 0
- Nested classes
- nested classes
- Nested Classes
- Nested Classes和Inner Classes
- Nested classes (C++ only)
- Nested Classes嵌套类
- java-basics [nested classes]
- Java中的Nested Classes和Inner Classes
- 嵌套类(Nested Classes)
- Java - nested classes 嵌套类
- java_嵌套类(Nested Classes)
- Nested Classes,Static Classes,Non-static Classes,Inner Classes,Local Classes,Anonymous Classes
- Kotlin-16.嵌套类/内部类(Nested Classes/Inner classes)
- Nested, Inner, Member, and Top-Level Classes
- [Compile Error] Classes must not be nested
- Nested Classes(just for self-learning)
- C++ Gossip: 巢狀類別(Nested Classes)
- java嵌套类(Nested Classes)总结
- 网络知识博客收集
- python初识
- POJ-2503-Babelfish
- 10033---div--background-image的路径问题
- Java复制、读取大文件的固定套路
- Nested Classes
- git 快速入门一:安装
- List使用add方法添加对象问题
- Andorid MVP模式
- iOS应用截屏
- 如何写一个jquery 插件
- OC 视图的生命周期
- 03 为什么封装,为什么有this?
- 容斥原理1002 HDU 1796