黑马程序员技术交流社区
标题:
关于内部类的问题!---解决,谢谢
[打印本页]
作者:
何万县
时间:
2012-3-29 13:08
标题:
关于内部类的问题!---解决,谢谢
本帖最后由 何万县 于 2012-3-29 14:37 编辑
public enum WeekDay{
SUN{},MON{},TUE{};
}
谁能告诉我内部类的具体格式,为什么,该代码的SUN后,没有括号?
作者:
黄方
时间:
2012-3-29 17:54
import java.util.Date;
public class Enum {
public static void main(String[] args) {
new Date(300){};
}
public enum TrafficLight{
RED(30){
public TrafficLight nextlight(){
return YELLOW;
}
}
,GRENN(45){
public TrafficLight nextlight(){
return YELLOW;
}
},YELLOW(8){
public TrafficLight nextlight(){
return RED;
}
};
public abstract TrafficLight nextlight();
private int time;
private TrafficLight(int time){
this.time=time;
}
}
}
java内部类
【1】内部类的分类:成员(实例)内部类,静态内部类,局部内部类,匿名内部类
成员内部类:如同类的普通成员一样。
1 可以加任意的修饰:private, protected.顶级类只可以为public, default
2 内部类不可脱离其外部类的限制使用, 因此在外部类以外创建内部类要这样:
outerObject=new outerClass(Constructor Parameters);
outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);
3 内部类对象可以访问外部类的任意变量或方法(包括private变量或方法);因为Java编译器在创建内部类对象时,隐式的把其外部类对象的引用也传了进去并一直保存着.
4 在内部类中,外部类与内部类同名的成员会被屏蔽, 不过可以这样访问外部的同名属性: OuterClass.this.field ;
5 内部类可以实现一个外部接口或抽象类, 外部类返回这样的一个接口,以达到隐藏接口的实现的目的.经典的例子:jdk中List的Iterator.
6 非静态内部类不能有静态成员,因为它违背了"成员类必须依赖外部类而存在"的原则(静态成员在Class被load的时候就初始化了);
静态内部类:如同类的静态成员一样; 它和成员内部类的区别是它没有指向外部类的引用;
1 创建静态内部类对象:OuterClass.InnerClass obj = OuterClass.InnerClass(params);
2 静态内部类可以有非静态成员;
3 静态内部类只能访问外部类的静态成员;
局部内部类:方法体或者代码片断中定义的类.
1 局部内部类前面不能有access修饰符; (和定义局部变量一样)
2 它有它自己的作用域,超出了这个范围就无效(无法使用);
3 它可以访问外部类的所有成员(因为外部类的成员对该方法可见);
4 定义在方法体中的内部类只能访问该方法的final变量,原因:定义在方法体中的变量会随着方法的退出而消亡,通过定义其为final变量,可以扩展其生命期;
5 定义在代码块中的内部类只能使用在该block中定义的final变量;
匿名内部类:在某些情况下,我们只需要内部类的一个对象,而不需要该类的名字;
1 匿名内部类的实例化: new SomeInterfaceOrClass(){......}; 意思是创造一个实现(继承)了SomeInterfaceOrClass的类的对象;
2 定义匿名内部类的时候,如果用到外面的对象,需要把这个参数的引用声明成final的
【2】.Java的内部类实在是一个非常复杂的机制,这个问题在Thinking In Java中似乎并没有阐述得非常清楚,在Core Java2的最新版本中,对Java内部类的机理做了更为详尽的说明。看来,我们在进行某个领域的学习时,找到一本好书固然重要,以此书为索引,同时借鉴其他好书对同一部分内容的叙述也时有必要(Core Java2、Java in a Nutshell也是份量相当的好书,尤其是不断更新的最新版本,值得研究其中的变化部分)。至少,通过Core Java2里的解释,弄明白了为什么局部类(Local Inner Class)只能引用被final修饰的局部变量。
局部类都定义在某个作用域或者方法中,它与成员内部类的区别是在作用域或方法外不可见,并且除了可以引用外部类的成员以外,它还可以引用所有被final修饰的同一作用域或方法内的局部变量。
但是,引用外部类的成员和引用局部变量的成员的情况又有所不同。因为一个内部类保有一个对外部类实例的链接,因此无论何时,某个内部类实例总能引用到某个外部类实例的成员,也就是说,外部类实例不会在任何一个和它有关联的内部类之前消失。而局部变量就不同了,出了作用域,所有局部变量将会被释放,而此时局部类的某个实例对象还很可能仍然存在,显然此时如果该局部类对象还试图在执行某个方法的时候去引用局部变量就不可能了。
实际上,编译器的解决办法,是对于局部类中每一个被引用到的局部变量,都新建一个该类型的类成员用于存放该局部变量的拷贝,一旦拷贝工作做完了,实际上局部类就与被引用的局部变量没有任何关系了(这与引用外部类的数据成员的情况不同,这种引用关系可以一直被保持,因为外部类不会在内部类之前消失)。而为了保证在整个作用域期间被引用的局部变量与类成员拷贝的值的一致性,就要求能被引用的局部变量都带有final修饰符,从而强制其在整个作用域期间的值不会改变(即在拷贝工作完成以后再改变被引用的局部变量的值是不允的)。
1.1 静态成员类特性
静态成员类可访问外部类的任一静态字段或静态方法 像静态方法或静态字段一样,静态成员类有public/private/default权限修饰符 1.2 静态成员类约束
静态成员类不能与外部类重名 像外部类的静态方法一样,不能直接访问外部类的实例字段和实例方法 静态成员类只能定义于外部类的顶层代码或外部类其它静态成员类的顶层代码中(嵌套定义);不能定义于外部类的某个函数中。 1.3 新增语法如示例代码所示,可以以“OuterClass.InnerClass”的方式来引用某个内部类。1.4 什么时候使用静态成员类B为A的辅助类,且只为A所用时,可将B定义为A的静态成员类。例如JDK中的LinkedList类就有Entry静态成员类:public class LinkedList<E> extends AbstractSequentialList<E>
…;
}
2.1 成员类特性· 类似于外部类的实例函数,成员类有public/private/default权限修饰符· 一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段和实例函数。
2.2 成员类约束成员类不能与外部类重名 不能在成员类中定义static字段、方法和类(static final形式的常量定义除外)。因为一个成员类实例必然与一个外部类实例关联,这个static定义完全可以移到其外部类中去 成员类不能是接口(interface)。因为成员类必须能被某个外部类实例实例化,而接口是不能实例化的。事实上,如示例代码所示,如果你以成员类的形式定义一个接口,该接口实际上是一个静态成员类,static关键字对inner interface是内含(implicit)的。
3.1 局部类特性如示例代码所示,局部类能且只能访问其所属代码段中的声明为final的局部变量。为什么只能访问声明为final的局部变量呢?我们知道,局部变量在其所属的代码段(譬如某个函数)执行完毕后就会被回收,而一个局部类的实例却可以在其类定义所属代码段执行完毕后依然存在,如果它可操控非final的局部变量,用户就可以通过该实例修改已不存在的局部变量,无意义。
3.2 局部类约束如示例代码所示,内部类只在定义它的代码段中可见,不能在它所属代码段之外的代码中使用;因此也就没有public/private/default权限修饰符(无意义) 不能以局部类形式定义一个接口。局部类只在其所属代码段中可见,定义这样的接口无意义 局部类类名不能与其外部类类名重复
3.3 什么时候使用局部类局部类大部分以匿名类的形式使用。4 Anonymous class(匿名类)没有类名的局部类就是匿名类。用一条语句完成匿名类的定义与实例创建。
4.1 匿名类特性与约束匿名类是一种特殊的局部类。局部类的特性与约束都适用与它。4.2 新增语法4.2.1 继承自某个基类的匿名类
new class-name ( [ argument-list ] ) { class-body }
创建匿名类实例时,“argument-list”将被传入其基类(即class-name)对应的构造函数。4.2.2 实现某个接口的匿名类new interface-name () { class-body }
4.3 什么时候使用匿名类
该类定义代码段很短 只需要创建该类的一个实例 类的定义代码与类的使用代码紧邻 使用匿名不影响代码的易读性 譬如,如下实现类似与c的callback功能的代码就是匿名类的典型应用: File f = new File("/src"); // The directory to list
// Now call the list() method with a single FilenameFilter argument
// Define and instantiate an anonymous implementation of FilenameFilter
// as part of the method invocation expression.
String filelist = f.list(new FilenameFilter() {
public boolean accept(File f, String s) { return s.endsWith(".java"); }
}); // Don‘t forget the parenthesis and semicolon that end the method call!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2