在java语言中,可以把一个类定义到另外一个类的内部,在类里面的这个类就叫内部类,外面的类就叫外部类。
顾名思义,成员内部类就是指一个类作为一个成员存在于另一个类的内部。这就成为成员内部类。如下:
public class ExterNal {
class InsIde{ //内部类
public void a () {
System.out.println("a");
}
}
}
这样看起来InsIde类就像是ExterNal类的一个成员,ExterNal称为外部类。内部类可以访问外部类的所有成员属性和成员方法。包括private成员和静态成员。如下:
public class ExterNal {
private int ExterNal_a = 1;
private static int ExterNal_b = 2;
private int a = 1;
class InsIde { // 内部类
private int a = 2;
public void a() {
System.out.println(ExterNal_a); // 外部类成员属性
System.out.println(ExterNal_b); // 外部类静态成员属性
// 但需要注意的是,当内部类和外部类存在同名属性或者方法时,内部类访问外部类同名属性或者方法需要按以下格式:
System.out.println(ExterNal.this.a); // 访问外部类同名属性
}
}
}
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。包括私有化变量和方法也可以访问。
public class ExterNal {
private int ExterNal_a = 1;
private static int ExterNal_b = 2;
private int a = 1;
class InsIde { // 内部类
private int a = 2;
private void a() {
System.out.println("a");
System.out.println(ExterNal_a); // 外部类成员属性
System.out.println(ExterNal_b); // 外部类静态成员属性
// 但需要注意的是,当内部类和外部类存在同名属性或者方法时,内部类访问外部类同名属性或者方法需要按以下格式:
System.out.println(ExterNal.this.a); // 访问外部类同名属性
}
}
// 创建内部类对象
public InsIde getInsIde() {
return new InsIde();
}
public ExterNal() {
//使用内部类对象访问内部类方法
this.getInsIde().a();
//使用内部类对象访问内部类属性
System.out.println(this.getInsIde().a);
}
}
成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:
public static void main(String[] args) {
/*创建内部类的两种方式*/
// 第一种
ExterNal exterNal = new ExterNal();
ExterNal.InsIde insIde = exterNal.new InsIde();
// 第二种
ExterNal.InsIde insIde1 = exterNal.getInsIde();
}
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
public class ExterNal {
class b{
}
public void ExterNalFun() {
//局部内部类
class InsIde extends b{
int a = 0;
}
}
}
需要注意的是局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
匿名内部类也就是没有名字的内部类,正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。当然也仅能只继承一个父类或者实现一个接口。同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。当然这个引用是隐式的。
匿名内部类的基本实现。
public abstract class InsIde {
public abstract void a () ;
}
public class ExterNal{
public static void main(String[] args) {
InsIde insIde = new InsIde() {
@Override
public void a() {
// TODO Auto-generated method stub
System.out.println("这是内部类中的方法---a");
}
};
insIde.a();
}
}
在接口上使用匿名内部类
public interfact class InsIde {
public abstract void a () ;
}
public class ExterNal{
public static void main(String[] args) {
InsIde insIde = new InsIde() {
@Override
public void a() {
// TODO Auto-generated method stub
System.out.println("这是内部类中的方法---a");
}
};
insIde.a();
}
}
由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现。最常用的情况就是在多线程的实现上,因为要实现多线程必须j继承Thread类或是实现Runnable接口
Thread的匿名内部类实现
public class Demo {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
}
};
t.run();
}
}
Runnable的匿名内部类实现
public class Demo {
public static void main(String[] args) {
Runnable r = new Runnable () {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
}
};
Thread t = new Thread(r);
t.run();
}
}
在使用匿名内部类时需要注意以下几点
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法。相反,它可以使用外部类的所有静态方法和属性包括private修饰的方法和属性。
public class ExterNal{
int a = 0; //外部类属性
private int private_a = 1; //外部类私有属性
static int static_a = 2; //外部类静态属性
private static int private_static_a = 3; //外部类私有静态属性
//外部类私有方法
private void function_a() {
System.out.println("function_a");
}
//外部类私有静态方法
private static void function_static_b() {
System.out.println("function_static_b");
}
static class InsIde{
public void test() {
System.out.println(static_a); //调用外部类静态属性
System.out.println(private_static_a); //调用外部类私有静态属性
function_static_b();//调用外部类私有静态方法
}
}
}
文章均为学习阶段记录笔记,若有不妥请留言指正。谢谢!