Tips:
(1)、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。
(2)、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的 。
(3)、内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量 。
内部类最大的好处就是他可以自由的访问外部类的成员变量,无论是否是private的 ,下面以程序例子来进行说明它的好处。
class Outer {
private int a = 10;
/* 为什么要使用内部类,它可以访问外部类的私有属性 */
class Inner {
public void printInfo(){
System.out.println("a = "+a);/* 直接访问a这个私有成员 */
}
}
}
public class InnerDemo {
public static void main(String args[]) {
/* 内部类定义 */
Outer o = new Outer();//先实例化一个外部类对象
Outer.Inner i = o.new Inner();//再实例化一个内部类对象
i.printInfo();//然后调用
}
}
那么这里可能会觉得麻烦,需要先实例一个外部类,再去实例化一个内部类,能不能直接实例化内部类呢,可以的,在内部类前加上关键字 static 即可,但它有限制,就是只能访问外部类的 static 属性了。如下程序:
class Outer {
/* 加上static才能被内部类访问 */
private static int a = 10;
/* 加了static之后就只能访问外部的 static 属性了 */
static class Inner {
public void printInfo(){
System.out.println("a = "+a);
}
}
}
public class InnerDemo2 {
public static void main(String args[]) {
/* 直接实例化内部类方式 */
Outer.Inner i = new Outer.Inner();
i.printInfo();
}
}
还有一个内部类这里需要简单讲解下,就是 匿名内部类,什么意思呢,先看一个不使用匿名类的代码:
/* 定义个接口 */
interface A {
public void printInfo();
}
/* 继承接口 */
class B implements A {
public void printInfo() {
System.out.println("Hello World!");
}
}
public class Anony {
public static void main(String args[]) {
B b = new B();
testFunc(b);//b向上转换到A
/* 或化简为以下定义方式 */
//testFunc(new B());
}
public static void testFunc(A a) {
a.printInfo();/* 向上转换所以会调用到子类的方法 */
}
}
上面的代码我们只使用了一次 B 这个类,却需要辛苦的构造它,那可不可以不构造它呢,可以的,使用匿名内部类,实现如下:
interface A {
public void printInfo();
}
public class Anony {
public static void main(String args[]) {
/* 匿名内部类定义方式 */
testFunc(new A(){
/* 直接在这里实现接口 */
public void printInfo() {
System.out.println("Hello World2!");
}
});
}
public static void testFunc(A a) {
a.printInfo();
}
}
最后以思维导图做个简单的总结: