----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------
这些天看了毕老师讲解的内部类的视频后,有点晕,在了解内部类的同时,还了解到了类还有个上帝的称号,传说中的父亲,首先来了解下内部类和匿名内部类的概念及其相关应用:(这些概念来源于互联网,关键是在于自己对知识点的掌握和理解程度的)
(1)内部类分为:成员内部类、静态嵌套类、方法内部类、匿名内部类。
定义在类中方法之外的内部类分为实例内部类和静态内部类;
实例内部类自动持有外部类的实例的引用,即可以访问外部类的所有变量;
静态内部类可以直接访问外部类的静态成员;
定义在方法中的内部类叫局部内部类,该类只能访问被final修饰的局部变量和参数。
几种内部类的共性:
A、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类命和$符号。
B、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
例如:
成员内部类:形式如下
class Outer
{
class Inner{}
}
编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。
成员内部类内不允许有任何静态声明!下面代码不能通过编译。
接下来解释一下为什么在成员内部类内不允许有任何静态声明的原因:
答:(A)因为静态变量是类在加载的时候就要分配内存空间的,你放在非静态内部类中,这个非静态内部类还没调用就给分配内存空间class Inner
静态变量就是在类被第一次使用的时候加载,而其可以直接用类名调用,为所有的实例所共享。
(B)因为声明为静态的方法是在类加载的时候就已经分配了内存空间的,静态的变量当然也是在类加载的时候分配内存空间啦,不然你直接用类名怎么可能引用它的 值。把静态变量声明在非静态方法里,方法都没加载,它其中的变量当然没办法加载了。
class Inner
{
static int a = 10;
}
能够访问成员内部类的唯一途径就是通过外部类的对象!
A、从外部类的非静态方法中实例化内部类对象。
class Outer
{
private int i = 10;
public void makeInner()
{
Inner in = newInner();
in.seeOuter();
}
class Inner
{
public void seeOuter()
{
System.out.print(i);
}
}
}
表面上,我们并没有创建外部类的对象就实例化了内部类对象,和上面的话矛盾。事实上,如果不创建外部类对象也就不可能调用makeInner()方法,所以到头来还是要创建外部类对象的。
你可能试图把makeInner()方法修饰为静态方法,即staticpublic void makeInner()。这样不创建外部类就可以实例化外部类了!但是在一个静态方法里能访问非静态成员和方法吗?显然不能。它没有this引用。没能跳出那条规则!但是如果在这个静态方法中实例化一个外部类对象,再用这个对象实例化外部类呢?完全可以!也就是下一条的内容。
B、从外部类的静态方法中实例化内部类对象。
class Outer
{
private int i = 10;
class Inner
{
public void seeOuter()
{
System.out.print(i);
}
}
}
public static void main(String[] args)
{
Outer out = new Outer();
Outer.Inner in = out.new Inner();
//Outer.Inner in = new Outer().new Inner();
in.seeOuter();
}
被注释掉的那行是它上面两行的合并形式,一条简洁的语句。
对比一下:在外部类的非静态方法中实例化内部类对象是普通的new方式:Inner in = new Inner();
在外部类的静态方法中实例化内部类对象,必须先创建外部类对象:Outer.Inner in = newOuter().new Inner();
C、内部类的this引用。
普通的类可以用this引用当前的对象,内部类也是如此。但是假若内部类想引用外部类当前的对象呢?用“外部类名”.this;的形式,如下例的Outer.this。
class Outer
{
class Inner
{
public void seeOuter()
{
System.out.println(this);
System.out.println(Outer.this);
}
}
}
D、成员内部类的修饰符。
对于普通的类,可用的修饰符有final、abstract、strictfp、public和默认的包访问。但是成员内部类更像一个成员变量和方法。可用的修饰符有:final、abstract、public、private、protected、strictfp和static。一旦用static修饰内部类,它就变成静态内部类了。