Java核心类库——内部类那点事儿
内部类 ———定义在类的内部的类 为何需要内部类? 典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。 使用内部类最吸引人的缘由是: 每一个内部类都能独立地继承自1个(接口的)实现,所以不管外围类是不是已继承了某个(接口的)实现,对内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,1些设计与编程问题就很难解决。从这个角度看,内部类使很多重继承的解决方案变得完全。接口解决了部份问题,而内部类有效地实现了“多重继承”。 内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。 特点: 1、内部类依然是1个独立的类,在编译以后内部类会被编译成独立的.class文件,但是前面冠之外部类的类命和$符号。 2、内部类可以直接或利用援用访问外部类的属性和方法,包括私有属性和方法(但静态内部类不能访问外部类的非静态成员变量和方法)。内部类所访问的外部属性的值由构造时的外部类对象决定。 3、而外部类要访问内部类的成员,则只能通过援用的方式进行,可问内部类所有成员 4、访问机制: System.out.println(this.x);或System.out.println(x);//内部类访问内部类的成员变量或成员方法可用此方法。 System.out.println(OuterClass.this.x);//内部类访问外部类的同名变量时可用此方法,如果没有同名可用System.out.println(x); 5、内部类可使用任意的范围限定:public/private/protected class InnerClass,且严格依照这几种访问权限来控制内部类能使用的范围。普通类的范围限定只可以是public或不加。 6、内部类的命名不允许与外部类 重名,内部类可以继承同级的内部类,也可继承其它类(除内部类和外部类)。
7、内部类可以定义为接口,并且可以定义另外1个类来实现它 从技术上讲,静态嵌套类不属于内部类。由于内部类与外部类同享1种特殊关系,更确切地说是对实例的同享关系。而静态嵌套类则没有上述关系。它只是位置在另外一个类的内部,因此也被称为顶级嵌套类。 静态的含义是该内部类可以像其他静态成员1样,没有外部类对象时,也能够访问它。静态嵌套类不能访问外部类的成员和方法。 1 package com.tarena.day13; 2 3 import com.tarena.day13.Foo.Koo; 4 /** 5 * 静态类内部语法演示 6 */ 7 public class StaticInner { 8 static void main(String[] args) { 9 Koo koo = new Koo(); 10 System.out.println(koo.add());//4 11 } 12 13 } 14 class Foo{ 15 int a = 1; 16 int b = 3; 17 /** 静态内部类,作用域类似于静态变量,属于类的 18 class Koo{ 19 int add(){ 20 a,不能访问a 21 return b+1; 22 } 23 } 24 } 2)成员内部类 * 1 成员内部类必须利用外部类实例创建 import com.tarena.day13.inn.Goo.Moo;
class InnerClassDemo {
4 5 Moo moo = new Moo(); 编译毛病,必须创建Goo的实例
6 Goo goo = new Goo();
7 Moo moo = goo.new Moo();利用goo实例创建Moo实例
8 Moo moo1 = goo.new Moo();
9 moo和moo1同享同1个goo实例的实例变量
10 System.out.println(moo.add());2
11 System.out.println(moo1.add());12 Goo goo1 = 13 goo1.a = 8;
14 Moo m1 = goo1.15 Moo m2 = goo1.16 System.out.println(m1.add());9
17 System.out.println(m2.add());18
19 }
20 }
21 class Goo{
22 23 成员内部类24 class Moo{
25 26 return a+1;
27 }
28 }
29 }
3)局部内部类(方法内部类) (2)、方法内部类对象不能使用该内部类所在方法的非final局部变量。 由于方法的局部变量位于栈上,只存在于该方法的生命期内。当1个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束以后,在方法内创建的内部类对象可能依然存在于堆中!例如,如果对它的援用被传递到其他某些代码,并存储在1个成员变量内。正由于不能保证局部变量的存活期和方法内部类对象的1样长,所之内部类对象不能使用它们。用法 package com.tarena.day13.inn;
import java.util.Comparator;
4
6 * 局部内部类
7 8 class LocalInnerClassDemo {
9 10 int a = 5;
11 final int b = 5;
12 局部内部类,定义在方法内部,作用域类似于局部变量
13 仅仅在方法内部可见
14 在局部内部类中可以访问方法中的局部final变量
15 16 17 return b;正确
18 return a;编译毛病
19 }
20 }
21
22 Foo foo = new Foo();
23 临时的自定义比较规则
24 class ByLength implements Comparator<String>{
25 int compare(String o1,String o2){
26 return o1.length()-o2.length();
27 }
28 }
29 }
30
31 }
4)匿名内部类 顾名思义,没着名字的内部类。表面上看起来它们似乎着名字,实际那不是它们的名字。 匿名内部类就是没着名字的内部类。甚么情况下需要使用匿名内部类?如果满足下面的1些条件,使用匿名内部类是比较适合的: ·只用到类的1个实例。
·类在定义后马上用到。 ·类非常小(SUN推荐是在4行代码以下) ·给类命名其实不会致使你的代码更容易被理解 在使用匿名内部类时,要记住以下几个原则: ·匿名内部类不能有构造方法。 ·匿名内部类不能定义任何静态成员、方法和类。 ·匿名内部类不能是public,protected,private,static。 ·只能创建匿名内部类的1个实例。 ·1个匿名内部类1定是在new的后面,用其隐含实现1个接口或实现1个类。 ·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。 A、继承式的匿名内部类和接口式的匿名内部类。 import java.util.Arrays;
2 3
匿名内部类 语法class AnnInnerClass {
6
8 TODO Auto-generated method stub
9 Yoo yoo = new Yoo();创建Yoo的实例
10 Yoo y1 = new Yoo(){};
new Yoo(){}创建匿名类实例
匿名类new Yoo(){}是继承Yoo类,并且同时创建了对象
new Yoo(){}是Yoo的子类型,其中{}是类体(class Body)
类体中可以定义任何类内的语法,如:属性,方法,方法重载,方法覆盖,等
子类型没着名字,所以叫匿名类!
16 Yoo y2 = new Yoo(){
17 public String toString(){方法重写(覆盖)
return "y2"; y2是子类的实例
20 };
21 System.out.println(y2);"y2",调用了匿名类对象toString()
22 匿名内部类可以继承/实现 于 类,抽象类,接口等
依照继承的语法,子类型必须实现所有的抽象方法
24
Xoo x = new Xoo(){};编译毛病,没有实现方法
26 27 Xoo xoo = new Xoo(){ 是实现接口,并且创建匿名类实例,不是创建接口对象
28 int add(int a){实现接口中的抽象方法
29 return a+b; 要访问局部变量b,只能访问final变量
30 }
31 };
32 System.out.println(xoo.add(5));10,调用对象的方法
33 Comparator接口也能够使用匿名类的方式
34 Comparator<String> byLength = new Comparator<String>(){
35 36 37
38 }
39 };
40 String[] names = {"Andy","Tom","Jerry"};
41 Arrays.sort(names,byLength);
42 System.out.println(Arrays.toString(names));
43 也能够这样写,工作中经常使用
44 Arrays.sort(names,45 46 47 }
48 });
49 }
50
51 }
接口式的匿名内部类是实现了1个接口的匿名类。而且只能实现1个接口。
B。参数式的匿名内部类。
class Bar{
2 void doStuff(Foo f){
3 }
4 }
interface Foo{
6 void foo();
7 }
class Test{
9 void go(){
10 Bar b = new Bar();
11 b.doStuff(new Foo(){
12 void foo(){
13 System.out.println("foofy");
14 }
15 });
16 }
17 }
构造内部类对象的方法有:
学习Java的同学注意了!!! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |