内部类:在类的内部定义的类叫内部类
1、有名内部类:
(1)实例化时必须先实例化外部对象,格式:
外部类.内部类 对象名 = 外部类对象名.new.内部类名();
代码实现:
//student类
public class Student{
public class Body{
public void desc() {
System.out.println("有名内部类");
}
}
}
//Main类
Student stu = new Student();
Student.Body body = stu.new Body();
body.desc();
2、匿名内部类
(1)匿名内部类由于没有类名而不能单独存在,定义匿名内部类的同时必须直接实例化该类
(2)普通类的匿名内部类实质是普通类的子类、抽象类的匿名内部类实质为抽象类的子类、接口类的匿名内部类实质为接口类的实现类。
(3)匿名内部类一定是接口的实现类(该实现类仅能实现一个接口)或类(普通类或抽象类)的子
类,其中new 关键字后面的类名或接口名即是该匿名内部类继承的父类或实现的接口
(4)匿名内部类不能自定义构造方法,但是可以通过非静态代码块初始化成员变量
(5)匿名内部类一定不能是抽象类(但可以是静态类)
(6)可以在匿名内部类中添加新的属性和方法,但是这些属性和方法不能被上转型对象所调用,只能被非上转型对象(大括号内整个就是一个非上转型对象)方式创建的匿名内部类对象所调用
如
new Human(){
public void run(){
System.out.println("跑");
}
}.run();
代码实现:
//human类
public class Human {
public void eat() {
System.out.println("吃饭");
}
public void test() {
System.out.println("human test");
}
}
//Main类
Human man = new Human() {
public void eat() {
System.out.println("男人在吃饭");
}
};
public void testClass(){
Human teacher = new Human(){
public void eat() {
System.out.println("老师在吃饭");
}
};
teacher.eat();
}
public static void main(String[] args) {
//匿名内部类的练习
Main main = new Main();
main.man.eat();
main.testClass();
}
}
3、静态内部类
(1)静态内部类的实例化
//student类
public static class stuNo{
public void outPut() {
System.out.println("学生的学号!");
}
}
//Main类
Student.stuNo stuno = new Student.stuNo();
stuno.outPut();
(2)如果为static类只能直接定义在外部类内(不能定义到方法内)
(3)静态内部类仅能直接访问外部类的静态成员变量和方法,可以通过创建外部类的对象间接使用非静态的成员变量和方法。
(4)在非外部类中定义的内部类和局部变量一样,其使用范围从定义的位置开始到其所在直接语句
块结束。
(5)只有有名类才允许使用静态成员
(6)内部类是一个独立的类:编译之后内部类会被编译成独立的.class文件,如果该内部类为有名内部类,则有名内部类字节码文件名为外部类的类名++内部类类名;如果为匿名内部类,则匿名内部类字节码文件名为外部类类名++内部类类名;如果为匿名内部类,则匿名内部类字节码文件名为外部类类名++内部类类名;如果为匿名内部类,则匿名内部类字节码文件名为外部类类名++数字;
(7)内部类可以直接定义在类中,也可以定义在方法或代码块中;其中直接定义在外部类中的内部类可以有public、protected、默认的和private四种访问权限修饰(普通外部类、接口和抽象类只能使用public和default修饰),也可以使用static修饰( static不能修饰普通外部类、接口和抽象类);但是定义在方法或代码块中的内部类不能有访问修饰符修饰,也不能有static修饰。
(8)内部类可以访问外部类的所有访问权限的成员变量