目录
- 在Java中可以将一个类定义在另一个类里面或者一个方法李米娜,这样的类叫做内部类。
- 与之对应,包含内部类的类被称为外部类。
- 内部类提供了更好的封装,可以把内部类隐藏在外部之内,不允许同一个包中的其他类访问该类,跟好的实现了信息隐藏。
内部类根据不同的修饰符或者定位的位置不同,分成四类:
- 匿名内部类:适用于仅使用一次使用的类,属于局部内部类的特殊情况。
- 静态内部类:内部类使用了static修饰。
- 方法内部类:在方法中定义内部类。
- 成员内部类:内部类没有使用static修饰。
注意:
对于每一个内部类来说:Java编译器会生成独立的.class文件
成员内部类:外部类名$内部类名字
方法内部类:外部类名$数字内部类名称
匿名内部类:外部类名$数字
为什么使用内部类:
1):增强封装 ,把内部类隐藏在外部类之内,不许其他类访问内部类。
2):内部类可以提高代码的可读性和可维护性,把小型类嵌入到外部类中
3):内部类可以直接访问外部类的成员。
1.匿名内部类:
匿名内部类的特点:
·匿名内部类的对象类型相当于是当前new的那个类型的子类类型
·匿名内部类没有类型名称、实例对象名称。
·匿名内部类没有构造方法,但是可以有构造代码块初始化。
·不能有private、protected、abstract、static、final关键字修饰。
·匿名内部类可以实现接口也可以继承父类,但是不可兼得。
·通过匿名内部类返回的是一个对象的引用,所以可以直接使用或将其复制给一个对象变量。
匿名内部类的使用场景:
- 只用到类的一个实例
- 类定义后马上用到
- 给类命名并不会导致代码更容易被理解
代码如下:
定义一个的抽象类,并有一个看书的抽象方法
public abstract class Person {
//抽象方法没有方法体
public abstract void read() ;
}
定义一个测试类
public class TextPerson {
public void read(Person person) {
person.read();
}
public static void main(String[] args) {
TextPerson pt = new TextPerson();
//使用匿名内部类
pt.read(new Person(){
{
System.out.println("初始化");
}
@Override
public void read() {
System.out.println("看Java");
}
});
System.out.println("======================");
//使用匿名内部类
pt.read(new Person() {
@Override
public void read() {
System.out.println("看杂志");
}
});
}
}
2.成员内部类:
没有使用static修饰内部类,说明内部类属于外部类的对象,不属于外部类本身
-
特点
- 创建成员内部类前,必须存在外部类对象,通过外部类对象创建内部类对象(当存在内部类对象时,一定存在外部类对象)
- 成员内部类的实例自动持有外部类的实例引用,内部类可以直接访问外部类成员。
- 外部类中不能直接访问内部类成员,必须通过内部类的实例去方法问
- 成员内部类中不能定义静态成员,,只能定实例成员
- 如果成员内部类和外部类存在同名的字段或方法,那么在内部类中:用this.xxx表示访问内部类成员,外部类.this.xxx表示外部类成员。
- 内部类访问权限修饰符随意,但是访问范围会受到影响。
代码如下:
public class Outter {
String name = "Outter.name";
public void ooxx() {
System.out.println(this.new Inner().age);
}
//成员内部类
class Inner{
int age = 17;
String name = "Inner.name";
public void test() {
String name = "local.name";
System.out.println(name);
System.out.println(this.name);
System.out.println(Outter.this.name);
}
}
}
获取成员内部类的实例的方法:
1.通过外部类.内部类 = new 外部类.new 内部类的方式获取
2.通过外部类.内部类 = 外部类实例.new 内部类的方式获取
3.通过外部类的get方法获取内部类实例对象
3.静态内部类
使用static修饰的内部类
如果一个类要被声明为static的,只有一种情况,就是静态内部类。
-
特点
- 静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例。
- 静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类对象的实例去访问。
- 静态内部类中可以定义静态成员和实例成员
- 测试类可以通过完整的类名直接访问静态内部类的静态成员,也可以通过外部类.内部类.静态方法的形式条用静态内部类的静态成员;
public class Outter {
String name = "Outter.name";
static String name2 = "name2";
//静态内部类
static class Inner{
static int age = 17;
public void test() {
System.out.println(name2);
System.out.println(new Outter().name);
}
}
}
获取静态内部类的实例方式:
通过外部类.new 内部类()的方式
4.方法内部类:
在方法中定义内部类,其可见范围是当前方法和局部变量是同一个级别
特点
1.不能使用public ,private,protected,static修饰符
2.方法内部类只能在当前方法中使用
3.方法内部类和成员内部类一样,不能包含静态成员
4.方法内部类和成员内部类一样,可以访问外部类的所有成员。
5.方法内部类的使用:一般情况下返回方法内部类中的方法
public class Outter {
public Object getMothodClass() {
class Inner{
int age = 12;
public String print1() {
return "我是方法内部类1";
}
public String print2(){
return "我是方法内部类2";
}
}
return new Inner().print1();
}
}
获取方法内部类的实例
System.out.println(Outter.getMothodClass());