认识内部类
内部类是定义在另一个类内部的类,它就像外部类的一个 “成员”
可以访问外部类的所有成员,而外部类也能访问内部类的成员。
为了更好的了解到内部类我们可以举个例子理解:外部类是 “房子”,内部类是 “房子里的房间”—— 房间属于房子,能使用房子里的所有东西,房子也能控制房间的使用。
内部类的分类
1.实例内部类
publicclassHouse{publicStringaddress="China";publicvoidinhome(){System.out.println("欢迎进来");}publicintarea=100;classRoom{publicStringname="主卧";publicvoidshow(){System.out.println("房子地址:"+address);System.out.println("房子面积:"+area+"㎡");System.out.println("房间名称:"+name);//内部类可以直接访问外部类成员inhome();//内部类可以直接访问外部类的方法}}}由此我们可以看出来内部类可以直接访问外部类的成员变量和方法
既然内部类可以访问外部类,那么外部类如何去访问内部类呢
publicclassHouse{publicStringaddress="China";publicvoidinhome(){System.out.println("欢迎进来");}publicintarea=100;classRoom{publicStringname="主卧";publicvoidshow(){inhome();System.out.println("房子地址:"+address);System.out.println("房子面积:"+area+"㎡");System.out.println("房间名称:"+name);}}//在外部类实现一个方法用来调用内部类publicvoidenterhome(){Roomroom=newRoom();// 外部类内部创建内部类对象,语法和普通类一样room.show();System.out.println("进入"+room.name);}}在测试类中实现调用内部类成员
//在外部类 的外部 创建内部类的方法publicclassTest{publicstaticvoidmain(String[]args){Househouse=newHouse();//1.先创建外部类House.Roomroom=house.newRoom();// 2. 通过外部类对象创建内部类对象(房间),语法:外部类.内部类 变量名 = 外部类对象.new 内部类();room.show();house.enterhome();}}2.静态内部类
用static修饰的内部类,属于外部类本身,而非外部类对象。
只能访问外部类的静态成员,创建时无需外部类对象。
publicclassEarth{publicstaticStringname="earth";publicintradius=6371;publicstaticclassMoon{publicStringMoomname="月球";publicvoidshow(){System.out.println("围绕着"+Earth.name);//可以直接引用静态的外部类的成员//System.out.println("Earth的半经"+Earth.radius);//不能访问非静态的外部类成员}}}用static修饰的内部类,属于外部类本身,而非外部类对象。
接下来我们尝试在外部类中调用内部类 的成员
publicclassEarth{publicstaticStringname="earth";publicintradius=6371;publicstaticclassMoon{publicStringMoomname="月球";publicvoidshow(){Earthearth=newEarth();earth.func();//内部类访问外部类的成员方法System.out.println("围绕着"+Earth.name);//可以直接引用静态的外部类的成员//System.out.println("Earth的半经"+Earth.radius);//不能访问非静态的外部类成员}//在外部类中调用内部类得先实例化publicvoidtestMoon(){Moonmoon=newMoon();moon.show();}}}最后就是在外部类的外面访问内部类
publicclassTest{publicstaticvoidmain(String[]args){// 关键:创建静态内部类对象,不用先new Earth()!// 语法:外部类.静态内部类 变量名 = new 外部类.静态内部类();Earth.Moonmoon=newEarth.Moon();moon.show();}}3局部内部类
定义在外部类的方法 / 代码块内部(类似局部变量)。
作用域仅限于当前方法 / 代码块,外部无法直接访问。
publicclassLoInnerClass{publicvoidfunc(){publicinta=10;System.out.println("使用了外部方法");}publicvoidtest(){System.out.println("a="+a);classinnerclass{//内部类调用外部类的方法publicvoidiusefunc(){func();}}}publicvoidousefunc(){test();//局部内部类中无法直接访问iusefunc()中的方法}}接下来我们尝试在外部类中调用内部类 的成员
publicclassTest2{publicstaticvoidmain(String[]args){LoInnerClassloInnerClass=newLoInnerClass();LoInnerClass.func();//外部类中也无法直接调用内部类中的方法}}4.匿名内部类
没有类名的内部类,通常用于快速创建 “只使用一次” 的类(比如实现接口、继承抽象类)。
本质是一个 “一次性” 的子类 / 实现类对象,语法上是表达式。
// 定义一个接口interfaceGreeting{voidsayHello();}publicclassTest{publicclassAnonymousInnerTest{publicstaticvoidmain(String[]args){// 匿名内部类:直接实现Greeting接口,无需定义具体类Greetinggreeting=newGreeting(){@OverridepublicvoidsayHello(){System.out.println("你好,内部类!");}};greeting.sayHello();// 输出:你好,内部类}}}默认情况下,匿名内部类无法被外部类调用,因此无法被外部类的外部调用
小结
1.写成员内部类的核心步骤:先定义外部类(含私有成员)→ 在外部类成员位置定义内部类(访问外部类成员)→ 编写外部类方法 / 测试代码使用内部类;
2.成员内部类的关键语法:外部类外部创建对象需用外部类对象.new 内部类(),内部类可直接访问外部类所有成员;
3.编写思维核心:先明确 “容器 - 组件” 的依赖关系,再分步实现、逐步验证,重点体现内部类的封装性和访问特性。
| 类别 | 内部类所在的位置 | 内部类如何访问外部类成员 | 内部类如何访问外部类方法 | 外部类如何访问内部类 | 外部类的外部访问内部类 |
|---|---|---|---|---|---|
| 实例内部类 | 外部类里面 | 直接访问 | 实例化然后使用对象调用 | 先创建一个外部方法,再将内部类实例化 | 先创建外部类的实例化,再通过外部类对象创建内部类对象 |
| 静态内部类 | 外部类里面(用static修饰) | 静态成员(方法)直接访问,非静态的成员不能访问 | 实例化然后使用对象调用 | 先创建一个外部方法,再将内部类实例化 | 通过外部类名.内部类名创建内部类对象 |
| 局部内部类 | 外部类中的方法中 | 直接调用 | 在内部类方法中调用 | 无法调用内部类 | 无法调用内部类 |
| 匿名内部类 | 外部类中 | 一般不使用后面的访问 | - | - | - |