📄 11_inner_class_day06.txt
字号:
内部类:
封装的一种
例子:链表中的节点.节点这个类定义再链表这个类的内部.并且可以把节点的访问范围定义成私有,那么只有再链表内部可以看到节点这个类.
实际开发中,有A B两个类型,A类对象是寄生在B类对象内部的.
种类
成员式
成员内部类
定义在成员变量的位置的类.
静态内部类
在类定义时把类声明成静态.
局部式
局部内部类
在方法内部定义的类.
匿名内部类
也在方法内部定义,但是不写类的名字.
成员式
使用
public class OuterA{
private String name="hehe";
private static String name2="xixi";
public class InnerA{//成员内部类
public void m2(){
String name="heihei";
System.out.println("name="+name);
System.out.println("name="+OuterA.this.name);//访问外部类的属性
System.out.println("name2="+name2);
}
}
public static class InnerB{
public void m3(){
//System.out.println("name="+name);静态内部类内部不能访问非静态成员.
System.out.println("name2="+name2);
}
}
}
public class InnerClassTest{
public static void main(String[] args){
OuterA out=new OuterA();
OuterA.InnerA inn//内部类型的访问语法.可以把外部类当成内部类的一层包结构.
=out.new InnerA();//用外部类对象 . new 内部类对象.
OuterA.InnerB innb=new OuterA.InnerB();
}
}
成员内部类
和类里面的成员一样.
我们把成员内部类当成外部类的一个成员,访问成员是需要有外部类的对象.
访问成员内部类需要外部类型,要想生成成员内部类对象就要先生成一个外部类对象.
静态内部类
和类里面定义的静态成员一样,对于静态成员的访问,可以在没有生成对象之前访问静态内部类.
修饰附 static final abstract
成员式内部类 y y y
局部式内部类 n y不继承 y
访问限制修饰符 public protected default private
顶层类 y n y n
成员式内部类 y y y y
局部式内部类 n n n n//局部变量没有访问权限
作用:
让一个类访问另外一个类的私有属性可以使用内部类.
成员内部类本质
System.out.println("name="+name);
System.out.println("name="+this.name);//这是错误的.
this.name表示访问的内部类自己的,上面一条语句是访问外部类的name.
如果内部类里面没有name属性.直接写就可以访问到外部类的name
如果内部类里面也有name属性.那么需要写成 外部类.this.name 访问外部类的属性.
外部类.this 表示外部类当前对象.就是创建内部类对象的那个外部类对象.
每个内部类对象都有一个内部类对象和它关联.
通过以上特点分析得到:
编译器会为成员内部类定义一个属性
//private OuterA out;
public InnerA(/*OuterA out*/){
//this.out=out;
}
实际上编译器会为每个内部创建一个私有的外部类对象的引用.
如果自己写了构造方法,那么编译器会把构造方法改成:
public InnerA(/*OuterA out,*/String name){
//this.out=out
......;
}
在使用的时候OuterA.this编译器会把这个代码替换成 InnerA的属性out.
在创建内部类对象的时候编译器会该程
OuterA.InnerA inn=out.new InnerA();
//OuterA.InnerA inn=new InnerA(out);
描述:
对于任何一个成员内部类,系统都会个它加上一个私有的外部类的引用,并且在内部类的所有构造方法的参数列表里面加上一个外部类的变量.并且在方法内部默认的把外部类属性赋值给私有的属性.这些都是默认的.
所以内部类也是一个彻头彻尾的编译器行为
所以最终在编译之后,内部类和外部类都是一样的.并且.class文件也是两分.
所有的语法都是由编译器来保证的.它的语法都是可以转换成我们熟悉的语法.
成员内部类对于外部类对象绑定起来.
静态内部类
可以认为和外部类没有太大的关系,只是一种寄居的关系.
可以只用外部类对象直接的访问内部类对象.
局部式:
public class OuterB{
public MyInter m1(){
class InnerC implements MyInter{
public void m4(){
System.out.println("InnerC.m4");
}
public void m3(){
System.out.println("InnerC.m3");
}
}
//return new InnerC;
return new MyInter(){//生成一个MyInter的实现类.
public void m4(){
System.out.println("InnerC.m4");
}
public void m3(){
System.out.println("InnerC.m3");
}
};
}
public void m2(){
//InnerC inn;
}
}
interface MyInter{
void m3();
void m4();
}
public class InnerClassTest{
public static void main(String[] args){
OuterB outb=new OuterB();
Object o=outb.m1;//虽然得到了InnerC的对象但是依然无法使用,多态的第一条定理.
}
}
局部内部类.
局部内部类只在定义它的方法体里面有效.
所以.相对来讲没有办法在方法外部得到局部内部类的对象.
即使在本类内部其他方法里面都没有办法使用局部内部类.
外太空没有人类的定义,不知道由什么样的属性和方法.
局部内部类式定义在方体内部的类,所以这个类只在方法体内部有效,如果希望能在外部使用那么需要:
1.在局部内部类的方法里面返回局部内部类.
但是只能用Object来接收.
2.后来在外部定义了一个接口,让局部内部类实现这个接口.
通过接口的引用就可以调用接口定义的方法.
这就是接口的回调.
怎么样让局部内部类的定义变得有意义.
这时发现其实内部类的名子没有意义,外部的人根本不关心.
这就引出了匿名内部类.
把生成对象和定义类的两个工作合二为一.
内部类隐含的一些特征.
局部内部类
局部内部类只能访问方法中final的局部变量。
语句再局部类内部访问方法中的局部变量这是一个错误。
再方法内的类的定义再调用方法的时候是不会指定类的定义里面的代码的。如果把局部内部类的对象,那么方法内部的局部变量的空间就被释放了,在类的内部对局部变量的访问也就是错误的。
细节,如果在局部内部类里面访问方法中的局部变量,编译器会在内部类里面多加入一个属性,这个属性和局部变量的定义完全相同: private final int b=20;
变量为什么不能拷贝,因为局部变量是一个瞬态的概念,那么希望能访问到这个值,如果在局部内部类里面再去修改这个变量,但是这个变量已经不存在了。那么这个修改是不可行的。流星和照片
内部类的意义:
1.更小层次的封装。
比包结构更小层次的封装,在一个类的内部声明的类,可以给内部的这个类设置访问权限。
2.内部类可以访问外部类的私有成员。
3.匿名内部类可以方便的实现运行时的接口回调。
如果有一个接口,希望生成接口的实现类,并且得到实现类的对象,那么使用匿名内部类的方式是最方便的。而且这种接口回调是在运行时的特征。
它还经常的被应用在事件编程中。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -