4大内部类的解析
首先我们要先了解java类的主要组成部分。
类的成员:
1.属性
普通属性
静态属性
2.方法
普通方法
静态方法
3.构造器
4.代码块
普通代码块
静态代码块
5.内部类:
在一个类的内部在写一个类-内部类
(1).普通成员内部类 普通属性
(2).静态成员内部类 静态属性 查看源码
(3).局部内部类 局部变量
(4).匿名内部类 匿名对象 参照
内部类的作用:
1.可以对外部类的功能进行拓展 且 可以不被外界访问
2.间接实现多继承 内部类与外部类都去继承一个类
(1).普通成员内部类:
普通成员内部类:
1.外部类 只能使用 public default 修饰
2.内部类可以被四种权限修饰符修饰
3.内部类中不能有静态的属性 但是可以存在 静态的常量
4.内部类中不能有静态的方法
5.内部类中可以直接使用外部类中的资源 属性 方法 静态非静态都可以
6.外部使用内部类的资源
非静态资源 创建内部类对象才能访问
静态资源 内部类名.属性名
7.在外部类的静态方法内 不能直接创建内部类对象
8.在外部直接创建内部类对象的方式
外部类名.内部类名 变量名 = 外部类对象.new 内部类对象();
Person.Inner inner = new Person().new Inner();
9.内部类编译后 产生的字节码文件 命名规则
外部类名 内 部 类 名 P e r s o n 内部类名 Person 内部类名PersonInner
内部类也会生成独立的字节码文件
(2).静态成员内部类:
静态成员内部类:
1.声明方式 在外部类中 写 static class 类名{
}
2.内部类中可以存在静态的属性
3.内部类中 不能直接使用外部类中的 非静态资源 需要创建外部类对象才能使用
4.在外部类的静态方法内 可以创建内部类对象
可以通过 内部类对象 调用内部类中 非静态资源
内部类名 调用 内部类中 静态资源
5.在外部类中直接创建内部类对象
外部类名.内部类名 变量名 = new 外部类名.内部类名();
变量名:内部类对象
Outer.Inner inner = new Outer.Inner();
6.内部类会生成独立的字节码文件 命名方式
外部类名$内部类名
7.直接创建外部类对象 是否会引发 静态内部类的初始化?
如果没有使用内部类中的资源 那不会进行内部类的初识化
如果只是使用内部类中的资源 也不会触发外部类的初始化
(3).局部内部类:
局部内部类: 参照 局部变量
1.如何声明局部内部类
在方法中 新建一个类
2.局部内部类地位比较低 使用外部类的什么资源 由所在方法决定
静态方法 可以使用外部类中的静态资源
非静态方法 可以使用外部类中的所有资源
3.局部内部类中的不能有静态属性但是可以有静态的常量
4.使用内部类中的资源 需要先执行外部类的方法 创建内部类的对象
通过内部类对象.相关资源
5.局部内部类也会生成独立的字节码文件 字节码文件的命名方式
外部类名$序号内部类名 序号从1开始
Outer$1Inner
Outer$2Inner
6.当 局部内部类中的方法 使用 所在外部类的局部变量时 该局部变量 会自动被final修饰
jdk1.8自动加final
(4).匿名内部类:
匿名内部类:
没有名字的内部类
什么作用:
节约代码
如何创建匿名内部类:
new 类(){
}
new 接口(){
}
1.创建了一个没有名字的匿名子类
2.创建了该匿名子类对象
注意:
1.匿名内部类 就是没有名字的局部内部类
2.匿名内部类能使用外部类什么资源 要看所在的方法是否静态
静态方法 只能使用静态资源
非静态方法 能使用所有资源
3.匿名内部类使用了所在方法的局部变量 则此变量 会被final修饰
4.匿名内部类也会生成独立的字节码文件
命名方式 外部类名$序号
Test2$1.class
Test2$2.class
Test2$3.class
示例:
public class Test2 {
static String name = "Test2";
int age =10;
public static void main(String[] args) {
int num = 10;
//创建了一个Person的匿名子类 并且完成了该匿名子类对象的创建
new Person() {
}.eat();
new Person("李白", 20) {
}.eat();
new Animal() {
@Override
void eat() {
System.out.println(name);
System.out.println("小猫吃饭");
System.out.println(num);
}
}.eat();
new Fly() {
@Override
public void fly() {
System.out.println("超人飞");
}
}.fly();
}
}
interface Fly {
void fly();
}
abstract class Animal {
abstract void eat();
}
class Person {
String name;
int age;
public void eat() {
System.out.println(name + "Person eat");
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}