标签:
http://www.cnblogs.com/wenruo/p/5387995.html
内部类 就是在类中嵌套的另一个类。
创建内部类的方式就是把类定义在外部类里面。
class Out { class In { } }
内部类对于外部类是特殊的,内部类可以访问到外部类的所有成员,包括私有成员。
class Outer { private String str = "Outer"; class Inner { public Inner() {str = "Inner";} } }
当生成一个内部类对象的时候,它自动和它的外部类有联系,所以要创建内部类对象,必须先有外部类对象。
内部类的类型在外部类除外部类静态方法外不能直接使用内部类的名字,应为OuterClassName.InnerClassName。
内部类可以为私有权限,当内部类为私有时,外部类外对内部类是不可见的。内部类不能有static的域,除非是final的。
创建内部类的方法:
1,外部类方法发返回内部类的引用。
2,通过.new语法实现。
class Outer { class Inner { } public Inner getInner() { return new Inner(); } } public class Test { public static void main(String args) { Outer out = new Outer(); Outer.Inner in = out.new Inner(); Outer.Inner in1 = out.getInner(); } }
在内部类通过OuterClassName.this可以访问外部类对象。
class Outer { int a = 17; class Inner { int a = 3; public void f() { System.out.println(this.a + " " + Outer.this.a); } } } public class Test { public static void main(String[] args) { Outer out = new Outer(); Outer.Inner in = out.new Inner(); in.f(); } } // output:3 17
类也可以定义在方法内部。这样类的作用域也就限制在方法内部。【名字实在是很糟糕
interface Inf { void f(); } class Outer { public Inf f() { class Inner implements Inf { public void f() { System.out.println("Inner"); } } return new Inner(); } } public class Test{ public static void main(String[] args) { Outer out = new Outer(); Inf inf = out.f(); inf.f(); } }
在这个例子中,通过向上转型为接口类型,完全隐藏了具体实现。
匿名内部类就是没有名字的内部类使用样例
interface Contents { int value(); } public class AnonymousInnerClassTest { public Contents contents() { return new Contents() { private int i = 11; public int value() { return i; } }; } public static void main(String[] args) { AnonymousInnerClassTest a = new AnonymousInnerClassTest(); Contents c = a.contents(); System.out.println(c.value()); } }
乍一看很奇怪,但其实很方便的使用方法。在需要使用类的地方直接写一个类的定义。
很容易想到因为匿名类没有名字,而构造器的名字需要和类名一样,所以……它没!有!构!造!器!
如果基类需要有参数的构造器怎么办?只需要在new的时候加上参数就可以了。
public class A { int i, j; A(int i, int j) { this.i = i; this.j = j; } } class B { public A f(int i, int j) { return new A(i, j) { //... }; } }
那么如果一个匿名内部类需要构造器来初始化的时候怎么办呢?
在学习类的初始化顺序的时候知道,在构建类对象时是先执行非静态代码段再执行构造器。所以这里可以用代码块带到类似构造器的效果。
class B { public void print() {} } public class A { public B getB() { return new B() { { System.out.println("Inside Instance initialize."); } public void print() { System.out.println("in anonymous f()"); } }; } public static void main(String[] args) { B b = new A().getB(); b.print(); } }
如果定义一个匿名内部类,并且希望它使用一个在其外部定义的外部对象,那么编译器会要求其参数引用是final的。
Java8中,可以不是final了,但是默认是final的,在内部类不能改变。原因是在内部类,外部变量相当于形参,也就是在内部类改变对外部类无影响,就会造成数据不同步的问题。
interface I {} public class A { public static void main(String[] args) { int x = 0; new I() { // x = 3; error void f() { System.out.println(x); } }; } }
Java8中匿名内部类可以用lambda表达式代替,感觉超简洁。语法糖,写代码方便,不过也增加了阅读代码的难度。
interface A1 { void print(); } class A2 { public A1 f() { return () -> { System.out.println("lambda expression."); }; } } public class Test { public static void main(String[] args) { A1 a1 = new A2().f(); a1.print(); } }
略过略过,以后再学,,,
静态内部类常被称作嵌套类。
创建静态内部类的对象,并不需要外部类的对象。
不能从嵌套类的对象中访问非静态的外围类对象。
普通的内部类不能有static数据和static字段,也不能包含嵌套类,但是嵌套类可以包含所有这些东西。
class B { static class C { } } public class A { public static void main(String[] args) { B.C c = new B.C(); } }
待续。。。
标签:
原文地址:http://www.cnblogs.com/wenruo/p/5387995.html