嵌套类
一个类定义在别的类的内部
//A定义在B中 嵌套
public class B {
class A {
...
}
}
//类A和B是并列的 没有属从关系
class A {
}
public class B {
}
嵌套类的种类
1静态嵌套类
层级和包围类的成员变量/方法一样
public class Outer1 {
String name;
satic class Inner1 {
String name;
}
}
1
第三方需要通过外部包围类才可以访问到静态嵌套类
Outer1.Inner1 obj = new Outer1.Inner1();
静态嵌套类的语法总结:
2
需要加修饰符static
3
$\color{red}{可以定义静态成员和非静态成员}$
4
$\color{red}{不能直接访问包围类的非静态成员}$ 可以直接访问包围类的静态成员
5
$\color{red}{可通过包围类的对象进行访问非静态成员}$
6
外界可以通过静态嵌套类名访问其静态成员 通过对象访问
7
$\color{red}{外界需要通过包围类才可以访问到静态嵌套类 并创建其对象 不需要包围外部类的实例}$
public class Outer1 {
String name;
static class Inner1 {
String name
}
}
2普通内部类
非static的类 定义在某个类的成员变量位置
定义后 在类中均可以使用
public class Outer3 {
pubic class Bird extends Animal implaments Flyable {
public void fly () {
...
}
public void eat() {
...
}
}
public Bird obj = new Bird();
public void f1() {
obj.fly();
}
}
1
可以继承其他类或者实现其他接口
2
可以用private/package private/protected/public 控制外界网文
3
非静态的类 不能包含静态成员变量和静态方法 除了常量final static ...
4
和外部包围类的实例相关 一个普通内部类实例
肯定是在一个外部包围类的实例中
而且可以访问
外部保卫类的所有成员
5
$\color{red}{在第三方蕾中 需要先创建外部包围类实例 才能创建普通内部类的实例 不允许单独的普通内部类对象存在!}$
public class Outer2 {
String name;
public class Inner2 {
String name;
}
}
总结匿名内部类和局部内部类
1
二者都定义在外围类中的成员级别
2
静态嵌套类不依赖于外围类对象 但是只能访问外围类的静态成员
3
普通内部类不许以来于外围类对象 不能单独存在 但是可以访问外围类的所有成员
3局部内部类
1
定义在代码块中的非静态的类 如方法 for循环 if语句…
2
定义后即可创建对象并使用
3
只活在这个代码块中 代码块结束后 $\color{red}{外界无法使用该类}$
public void f1() {
String name = "Def";
class Inner2 () {
public void f2() {
...
}
}
}
Inner2 obj1 = new Inner2();
obj1.f2();
4
可以继承其他类或者实现其他接口
5
非静态的类 不能包含静态成员变量和静态方法 除了常量final static ...
6
可以访问外部包围类的成员
7
如果定义在静态方法中 只能访问包围类的静态成员
8
局部内部类不能是一个接口 即接口不能定义在代码块中
public class Outer3 {
String name;
public void f1() {
class Inner3 {
String name;
}
}
}
4匿名内部类
1
$\color{red}{没有正式类名}$ 的内部类 必须继承一个父类/实现一个弗雷接口
2
在实例化以后 迅速转型为父类/父f接口
3
这种类型的对象只能new一个对象 之后以new的对象名进行操作
4
可以在普通语句和成员变量赋值的时候使用内部类
Runnable r = new Runnable() {
public void run () {
...
}
};
new Thread(r).start();
5
没有类名 没有$\color{red}{构造函数}$ 可以使用父类的构造函数
6
可以$\color{red}{继承,改写,补充}$父类/父类接口
7
内部不可以$\color{red}{新定义}$静态成员(方法 + 变量) 常量除外final static int a = 5;
8
可以访问外部包围类的变量和方法 包括private修饰的
9
$\color{red}{如果定义在静态方法中 也只能访问外部包围类的静态成员}$
10
由于没有类名 $\color{red}{外部包围类和其他类都无法访问匿名内部类}$
public class Outer4 {
String name;
public void f1() {
new Thread (new Runnable() {
public void run() {
System.out.println("hello!");
}
}).start();
}
}
总结匿名内部类和局部内部类
二者几乎相似 局部内部类可以重复使用 匿名内部类不可以 但匿名内部类更为简洁
为什么需要嵌套类?
1
不同的访问权限要求 更细的访问控制
2
简洁 避免过多的类定义
嵌套类和其他类的关系
1
嵌套类访问外部包围类
2
外部包围类访问嵌套类
3
第三方类访问嵌套类
四种嵌套类的使用场景对比
1
匿名内部类:如果需要定义额外的方法和变量则使用它
2
局部内部类:在一个方法内需要创建一个新的类型 并重复使用他
3
普通内部类:和局部内部类相似 在一个类中定义 可以重复使用 可以访问外部类的成员
但不需要访问外部类的方和的形参和内部变量
4
静态嵌套类:在一个类中定义 可以重复使用 并需要访问外部类的静态成员