内部类详解
内部类:在类中的另外一个类。
1.分类
1)成员内部类:在类的成员变量/成员方法位置编写,与外部类的属性、方法并列。
2)静态内部类: 定义在类中,任何方法外,用static修饰
3)局部内部类:在方法中定义的类,与局部变量类似。
4)匿名内部类:没有名字的类
2.成员内部类
1)可以访问外部类的所有属性。
2)可以定义非静态属性和方法,不可以定义static修饰的属性和方法,可以定义static final修饰的编译期变量【不用加载类的字节码】
3)为什么不可以定义static修饰的属性和方法?
内部类是外部类的一个成员,外部类初始化的时候,内部类才能初始化,static修饰的属于类,在类加载的 时候就要初始化,前后矛盾。
static final 修饰的变量叫常量,
常量分为编译期常量,程序编译【不需要加载类的字节码】,就可以确定常量的值
非编译期常量。程序运行【需要加载类的字节码】,确定常量的值
4)方法的调用:
4.1)内部类调用:
调用自己的方法属性:直接调用 或者this.属性名、this.方法名();
调用外部类的方法属性:外部类.this.属性名、 外部类.this.方法名();
4.2) 外部类调用:
普通方法:构建内部类对象--》对象名.方法名();
main方法:构建外部类对象--》构建内部类对象---》对象名.方法();
3.静态内部类
3.1)可以定义静态的成员、非静态的成员。
3.2)方法属性调用:
3.2.1内部类调用
调用自己的静态属性、方法:类名.属性名 ;类名.方法名;
调用自己的普通方法:直接调用、this.方法名;
调用外部的静态方法属性:外部类名.方法名;
不能调用外部的普通方法
3.2.2外部类调用
非静态:对象名.属性名
静态: 类名.属性名
4.局部内部类(在方法体中定义)
1)不能使用任何的访问修饰符。
2)不可以定义静态的方法属性(同成员内部类)
3)方法调用:内部类调用:(同成员内部类)
访问局部变量
(1)、匿名内部类可以访问外部内的所有成员;
(2)、匿名内部类不能访问外部类未加final修饰的变量(注意:JDK1.8即使没有用final修饰也可以访问);
外部类调用: 不能访问内部类的任何属性方法
4)为什么外部类不能访问局部内部类的属性、方法?
因为局部内部类定义在方法中,而方法需要所在类的对象去调用。
5)为什么局部变量类只能访问局部变量中final修饰的变量?
内部类的生命周期比方法长。
5.匿名内部类:没有名字的内部类(必须继承一个父类或实现一个接口)
匿名内部类为局部内部类
作用:一般用匿名内部类来实现某接口(使用不多,不需要写一个类实现该接口,可以使用匿名内部类)【匿名内部类一般就是用来实现接口:】
重写接口(抽象类)中的方法
声明:
interface A{
public void showA();
}
eg: A a = new A(){
public void showA(){
}
};
可用于集合中的比较器
abstract class B{
public void showB(){}
public abstract void shohome();
}
eg:
B b = new B(){
//可以重写showB 可以不重写
public void shohome(){}//抽象方法一定要实现
};
解释:这里并不是new了接口, 而是多态, new的是接口的实现类,这个实现类就是匿名内部类充当了
调用:
(1)、匿名内部类可以访问外部内的所有成员;
(2)、匿名内部类不能访问外部类未加final修饰的变量(注意:JDK1.8即使没有用final修饰也可以访问);
匿名内部类也是不能有访问修饰符和 static 修饰符的。
匿名内部类和局部内部类都可以实现接口,区别?
局部类继承接口,有自己的类名,定义完成之后需要再用new关键字实例化才可以使用;
匿名内部类在定义的时候就实例化了,定义完了就可以直接使用;
匿名类是一个表达式,因此在定义的最后用分号";"结束
public class Test {
interface Fun{
public void say();
}
public static void main(String[] args) {
Test test = new Test();
test.play();
}
public void play(){
//局部内部类
class A implements Fun{
@Override
public void say() {
System.out.println("A");
}
}
//匿名内部类
Fun f=new Fun(){
@Override
public void say() {
System.out.println("F");
}
};
Fun fun = new A();
fun.say();
f.say();
}
}