设为首页 加入收藏

TOP

深入理解Java:内部类(二)
2015-07-16 12:55:22 来源: 作者: 【 】 浏览:12
Tags:深入 理解 Java 部类
外围类的一部分,但是它可以访问当前代码块内的常量,和此外围类所有的成员。


需要注意的是:


(1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。


(2)、方法内部类对象不能使用该内部类所在方法的非final局部变量。


具体原因等下再说
public class Outer {
? ? private int s = 100;
? ? private int out_i = 1;


? ? public void f(final int k) {
? ? ? ? final int s = 200;
? ? ? ? int i = 1;
? ? ? ? final int j = 10;


? ? ? ? // 定义在方法内部
? ? ? ? class Inner {
? ? ? ? ? ? int s = 300;// 可以定义与外部类同名的变量


? ? ? ? ? ? // static int m = 20;//不可以定义静态变量
? ? ? ? ? ? Inner(int k) {
? ? ? ? ? ? ? ? inner_f(k);
? ? ? ? ? ? }


? ? ? ? ? ? int inner_i = 100;


? ? ? ? ? ? void inner_f(int k) {
? ? ? ? ? ? ? ? // 如果内部类没有与外部类同名的变量,在内部类中可以直接访问外部类的实例变量
? ? ? ? ? ? ? ? System.out.println(out_i);
? ? ? ? ? ? ? ? // 可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的
? ? ? ? ? ? ? ? System.out.println(j);
? ? ? ? ? ? ? ? // System.out.println(i);
? ? ? ? ? ? ? ? // 如果内部类中有与外部类同名的变量,直接用变量名访问的是内部类的变量
? ? ? ? ? ? ? ? System.out.println(s);
? ? ? ? ? ? ? ? // 用this.变量名访问的也是内部类变量
? ? ? ? ? ? ? ? System.out.println(this.s);
? ? ? ? ? ? ? ? // 用外部类名.this.内部类变量名访问的是外部类变量
? ? ? ? ? ? ? ? System.out.println(Outer.this.s);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? new Inner(k);
? ? }


? ? public static void main(String[] args) {
? ? ? ? // 访问局部内部类必须先有外部类对象
? ? ? ? Outer out = new Outer();
? ? ? ? out.f(3);
? ? }
}


静态内部类(嵌套类):


如果你不需要内部类对象与其外围类对象之间有联系,那你可以将内部类声明为static。这通常称为嵌套类(nested class)。想要理解static应用于内部类时的含义,你就必须记住,普通的内部类对象隐含地保存了一个引用,指向创建它的外围类对象。然而,当内部类是static的时,就不是这样了。嵌套类意味着:


1. 要创建嵌套类的对象,并不需要其外围类的对象。


2. 不能从嵌套类的对象中访问非静态的外围类对象。
public class Outer {
? ? private static int i = 1;
? ? private int j = 10;


? ? public static void outer_f1() {}


? ? public void outer_f2() {}


? ? // 静态内部类可以用public,protected,private修饰
? ? // 静态内部类中可以定义静态或者非静态的成员
? ? private static class Inner {
? ? ? ? static int inner_i = 100;
? ? ? ? int inner_j = 200;


? ? ? ? static void inner_f1() {
? ? ? ? ? ? // 静态内部类只能访问外部类的静态成员(包括静态变量和静态方法)
? ? ? ? ? ? System.out.println("Outer.i" + i);
? ? ? ? ? ? outer_f1();
? ? ? ? }


? ? ? ? void inner_f2() {
? ? ? ? ? ? // 静态内部类不能访问外部类的非静态成员(包括非静态变量和非静态方法)
? ? ? ? ? ? // System.out.println("Outer.i"+j);
? ? ? ? ? ? // outer_f2();
? ? ? ? }
? ? }


? ? public void outer_f3() {
? ? ? ? // 外部类访问内部类的静态成员:内部类.静态成员
? ? ? ? System.out.println(Inner.inner_i);
? ? ? ? Inner.inner_f1();
? ? ? ? // 外部类访问内部类的非静态成员:实例化内部类即可
? ? ? ? Inner inner = new Inner();
? ? ? ? inner.inner_f2();
? ? }


? ? public static void main(String[] args) {
? ? ? ? new Outer().outer_f3();
? ? }
}


生成一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner in = new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类(正常情况下,你不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分,因为它是static 的。只是将嵌套类置于接口的命名空间内,这并不违反接口的规则)


匿名内部类:


简单地说:匿名内部类就是没有名字的内部类。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:


?只用到类的一个实例。
?类在定义后马上用到。
?类非常小(SUN推荐是在4行代码以下)
?给类命名并不会导致你的代码更容易被理解。


在使用匿名内部类时,要记住以下几个原则:


?  匿名内部类不能有构造方法。


?  匿名内部类不能定义任何静态成员、方法和类。


?  匿名内部类不能是public,protected,private,static。


?  只能创建匿名内部类的一个实例。


?? ? 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。


?  因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。


?


下面的代码展示的是,如果你的基类需要一个有参数的构造器,应该怎么办:


public class Parcel7 {
? ? public Wrapping wrap(int x) {
? ? ? ? // Base constructor call:
? ? ? ? return new Wrapping(x) { // Pass constructor argument.
? ? ? ? ? ? public int value() {
? ? ? ? ? ? ? ? return super.value() * 47;
? ? ? ? ? ? }
? ? ? ? }; // Semicolon required
? ? }
? ? public static void main(String[] args) {
? ? ? ? Parcel7 p = new Parcel7();
? ? ? ? Wrapping w = p.wrap(10);
? ? }
}


只需简单地传递合适的参数给基类的构造器即可,这里是将x 传进new Wrapping(x)。在匿名内部类末尾的分号,并不是用来标记此内部类结束(C++中是那样)。实际上,它标记的是表达式的结束,只不过这个表达式正巧包含了内部类罢了。因此,这与别的地方使用的分号是一致的。


如果在匿名类中定义成员变量或者使用带参数的构造函数,你同样能够对其执行初始化操作:


public class Parcel8 {
? ? // Argument must be final to use inside
?

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇关于Java内部类的“内部” 下一篇深入理解Java垃圾回收机制

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: