什么是内部类,匿名类,匿名接口,匿名方法?
内部类有什么特点?
内部类有哪些应用?
JAVA语言是一个JAVA文件名对应一个类名称,在类作用域里面所定义的类就是内部类,它可以是静态,或是非静态的。而我们关注的大部分是非静态内部类。为什么要定义内部类呢?
从面向对象来讲,比如人有心脏,人被定义成类后,心脏是其身体必要的一部分,在设计时,我们可以把心脏定义成外部类,但是设计成内部类不是更加符合现实意义吗?是的。
对于现实世界中的场景抽象,很多都需要内部类的支持。当然这不仅仅是SUN公司设计出内部类的唯一用处,内部类最大的特点就是其不是单一存在,其还有一个外部对象的引用,在内部类中可以任意操作外部对象的属性和方法,包括private。我引用了《Think in Java》中的代码。
package thinkInJava;
public class Outer {
private int o_a = 10;
public void print() {
System.out.println(o_a);
}
public Inner newInner() {
return new Inner();
}
class Inner {
private int i_b = 5;
public Outer getOuter() {
return Outer.this;
}
public void showstop() {
System.out.println(o_a);
}
}
public static void main(String args[]) {
Outer outer = new Outer();
Inner inner = outer.newInner();
inner.getOuter().print();
inner.showstop();
}
}
所以说脱离了外部对象,内部对象是不可能存在的(静态内部类除外)。同样代码附上。
package thinkInJava;
public class Outer {
private int o_a = 10;
public void print() {
System.out.println(o_a);
}
public Inner newInner() {
return new Inner();
}
static class Inner {
private int i_b = 5;
public void print(){
System.out.println(i_b);
}
public void haveATry() {
i_b++;
}
}
public static void main(String args[]) {
Outer outer = new Outer();
Inner inner = outer.newInner();
inner.print();
inner.haveATry();
Outer.Inner inner1 = new Inner();
inner1.print();
Outer outer1 = new Outer();
Inner inner2 = outer1.newInner();
inner2.print();
}
}
这里有一点,是Inner没办法用.this来获取外部类实例,
有一些注意点,一是非内部类中是不允许有内部变量、方法或类,即不允许定义静态内部成员
因为静态变量的作用就是让所有类对象共享一个状态,而这和内部类要依赖外部类对象存在产生矛盾。
内部类可以继承类或实现接口。典型的类子可以看一看HashMap,HashTable的源码,里面定义了Entry内部类,而且此内部类实现了Map.Entry的接口。
二是我们也应该关注到SUN引入内部类的又一优点,就是变相实现了JAVA多重继承,本身一个类是没办法继承多个类的,但是可以定义多个内部类,之后对内部类的一系列操作来实现这个特点。当然,你也可以用asm来实现JAVA多重继承。
public class Outer {
class InnerA extends A {
}
class InnerB extends B {
}
......
}
三是内部类下面还可以再定义内部类,理论上应该可以无限嵌套下去(这个没试过……)。
四是可以匿名定义类,接口。最相关的实例就是SWING中GUI的事件驱动模型,和声明各种监听器。
五是内部类/接口可以被继承/实现,但是初始化要同时关联到内部类的外部对象
package thinkInJava;
class WithInner{
class Inner{}
}
public class Outer extends WithInner.Inner{
public Outer(WithInner wi){
wi.super();
}
public static void main(String args[]) {
WithInner wi = new WithInner();
Outer t = new Outer(wi);
}
}
六是内部类不可以被外部类的子类覆盖,二者是独立存在的。
package thinkInJava;
public class Outer {
class WithInner {
class Inner {
public void print() {
System.out.println("super inner class");
}
}
}
class InheritWithInner extends WithInner {
class Inner {
public void print() {
System.out.println("child inner class");
}
}
public Inner newInner() {
return new InheritWithInner.Inner();
}
public WithInner.Inner newInner1() {
return new WithInner.Inner();
}
}
public void test() {
InheritWithInner tt = new InheritWithInner();
tt.newInner().print();
tt.newInner1().print();
}
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
}
}
对于内部类,自己还是需要大量时间去使用,去体会。适时用,用的好。