一:嵌套类分类
• 嵌套类:Nested classes
–静态嵌套类:Static nested classes,即类前面有static修饰符
public class Outer1 {
String name;
static class Inner1{
String name;
}
}
–非静态嵌套类:Non-static nested classes, 又名内部类,Inner classes
• 普通内部类(亦翻译为:成员内部类)
public class Outer2 {
String name;
public class Inner2{
String name;
}
}
• 局部内部类(Local classes)
public class Outer3 {
String name;
public void f1(){//成员方法里面定义的类
class Inner3{
String name;
}
}
}
• 匿名内部类(Anonymous classes)
public class Outer4 {
String name;
public void f1(){
new Thread(new Runnable() {//实现Runnable接口的线程要传给Thread对象才能运行
@Override
public void run() {
System.out.println("Hello");
}
}).start();
}
}
– https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html//官方文档进一步了解
•
为什么需要嵌套类 ?
–
不同的访问权限要求,更细粒度的访问控制
–
简洁,避免过多的类定义
–
语言设计过于复杂,较难学
• 嵌套类学习重点
*嵌套类的语法
•
嵌套类和其他类的关系
–
嵌套类访问外部包围类
–
外部包围类访问嵌套类
–
第三方类访问嵌套类
二:嵌套类详细介绍以及应用
A:匿名内部类
•
匿名内部类: Anonymous classes
–
没有类名
的内部类,必须继承
一个
父类/实现
一个
父接口
–
在实例化以后,迅速转型为
父类/父接口
–
这种类型的对象,只能new一个对象,之后以对象名字操作
–
可在普通语句和成员变量赋值时使用内部类
Runnable r=new Runnable() {
@Override
public void run() {
System.out.println("该匿名类只能r这一个对象");
}
};
new Thread(r).start();
•
匿名内部类
–
没有正式类名
的内部类
•
编译器产生内部名字
:类名+$+数字编号
–
没有类名,
没有构造函数
,能用父类/父接口的构造函数(可带参数)
–
可以
继承、改写、补充
父类/父接口的方法
–
内部不可以
新定义
静态成员(变量+方法),常量除外
•
final
static int a = 5;
–
可以访问外部包围类的成员变量和方法(包括private)
–
如果定义在静态方法中,也只能访问外部包围类的静态成员
–
没有类名,
外部包围类和其他类也无法访问到匿名内部类//自己想怎搞怎搞
B:局部内部类
•
局部内部类:Local classes
–
定义在代码块中的非静态的类,如方法,for循环,if语句等
–
定义后,即可创建对象使用
–
只能活在这个代码块中,代码块结束后,
外界无法使用该类
public void f1(){
String name ="Lucy";
class Inner{
public void f2(){
System.out.println(name);//打印Lucy
}
}
}
•
局部内部类:Local classes
–
编译后名称:外部类名+$+序号+内部类名
–
可以继承其他类,或者实现其他接口
–
非静态的类,不能包含静态成员(变量和方法),除了常量 //和匿名内部类相同
–
可以访问外部包围类的成员 (包括private)
–
如果定义在静态方法中,只能访问包围类的静态成员
–
局部内部类不能是一个接口,即接口不能定义在代码块中
C:普通内部类(成员内部类)
•
普通内部类
–
非static的类,定义在某个类的成员变量位置
–
定义后,在类里面均可以使用
interface Flyable{
default void fly(){//java8新特性
System.out.println("default fly");
}
}
class Animal{ }
public class Outer {
public class Bird extends Animal implements Flyable{
private String name;
public Bird(){
super();
name="Lucy";
}
public String getName(){
return name;
}
@Override
public void fly() {
System.out.println("Bird fly");
}
}
public Bird obj=new Bird();//成员内部类可以直接使用。此处也可以将成员内部类(Bird)定义在外面,Outer类持有Bird类的一个句柄
public void f(){//Outer类的成员方法
obj.fly();
}
}
D:静态嵌套类
•
静态嵌套类
–
层级和包围类(enclosing class)的成员变量/方法一样
–
第三方需要通过外部包围类才可以访问到静态嵌套类
•
Outer1.Inner1 obj = new Outer1.Inner1();
•
静态嵌套类的语法总结
–
需要加修饰符static
–
可以定义静态成员和非静态成员
–
不能直接访问包围类的非静态成员,可直接访问包围类的静态成员
•
可通过包围类的对象进行访问非静态成员
–
外界可以通过静态嵌套类名访问其静态成员,通过对象访问其非静
态成员
–
外界需要通过包围类才可以访问到静态嵌套类,并创建其对象,不
需要外部包围类的实例
总结:
• 了解普通内部类和静态嵌套类
–两者都定义在外围类中的成员级别
–静态嵌套类不依赖于外围类对象,但是只能访问外围类的静态成员
–普通内部类必须依赖于外围类对象,不能单独存在,但是可以访问
外围类的所有成员