一、概念
内部类:在一个类的内部定义的一个类;
分类: 可以分为 成员内部类、局部内部类、匿名内部类和静态内部类;
《Think in java》):
1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
2、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
3、创建内部类对象的时刻并不依赖于外围类对象的创建。
4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
二、各种内部类的介绍
1.成员内部类
特点:
1.成员内部类可以直接访问外部类的成员(包括private定义的成员),而外部类不能直接访问内部类的成员属性和方法。
2.成员内部类是依附在外部类,需要先创建外部类对象才能创建内部类对象;
3.成员内部类区别于静态内部类,成员内部类中不能存在static的成员和方法;
//相对于内部类,这是外部类
public class Outer {
private int out = 1;//private的外部类变量
public void OutPrint() {
System.out.println("Out:"+out);
}
//内部类
public class Inner {
int inn;
public void InPrint() {
System.out.println("In中的Out:"+out);//可以使用外部类的成员变量
OutPrint();//可以使用外部类的方法
}
}
//
}
public class Show {
public static void main(String[] args) {
Outer o = new Outer();//1.外部类创建对象
Outer.Inner i = o.new Inner();//2.外部类的对象创建后,创建内部类对象
// Inner i = new Inner();不会报错但是是无效定义方式
// Outer.Inner j = new Outer().new Inner();//结合1和2直接创建也是可行的
i.InPrint();
}
}
console结果:
In中的Out:1
Out:1
2.局部内部类
概念: 定义在外部类方法或作用域内的类
特点:
1.局部内部类可以直接访问外部类的成员;
2.在局部位置可以创建局部内部类对象,通过对象调用成员;
3. 局部内部类在访问局部变量时,被访问的变量必须用 final 修饰;
3.匿名内部类
简单写法:
new 父类(){
重写方法;
};
new 接口(){
实现方法;
};
特点:
1.匿名内部类我们必须是继承一个父类或者实现一个接口,不能是抽象的;
2.匿名内部类仅能被使用一次因为匿名内部类是直接使用new来生成一个对象的引用,该类的定义会立即消失;
3.匿名内部类中是不能定义构造函数的,匿名内部类中不能存在任何的静态成员变量和静态方法;
4.匿名对象可以作为实际参数传递;
5.如果定义了一个匿名内部类,并且希望它使用一个其外部定义的参数,那么编译器会要求该参数引用是final的;
使用时机: 当一个对象只需要使用一次可以使用,匿名对象使用完毕就变成垃圾被回收;
//抽象类
public abstract class Person {
String name;
int age;
public abstract void Print();
}
//接口
public interface PlayBall {
public abstract void Play();
}
//
public class Show {
//定义一个测试匿名类对象可以作为形参传递的方法
public static void Test(Person pp) {
pp.Print();
}
public static void main(String[] args) {
//创建抽象类的匿名内部类
new Person() {
public void Print() {
System.out.println("hello");
}
};
//使用new创建匿名内部类后,直接引用其成员
new Person() {
public void Print() {
System.out.println("hello");
}
}.Print();
//通过多态创建对象
Person a= new Person() {
public void Print() {
System.out.println("hello");
}
};
a.Print();
//匿名类对象作为形参
Show.Test( new Person() {
public void Print() {
System.out.println("hello");
}
});
//创建接口的内部类,同样道理,可以通过多态创建对象
PlayBall p = new PlayBall() {
public void Play() {
System.out.println("踢足球");
}
};
p.Play();
}
}
console结果:
hello
hello
hello
踢足球
4.静态内部类
使用static修饰的内部类
特点:
1.不能访问任何外部类的非static成员变量和方法
2.静态内部类可以直接创建实例不需要依赖于外围类