什么是内部类?一个类就是用来模拟一个事物的,如果一个事物的内部包含另一个事物,这就产生了一个在外面一个在里面的包含关系。例如:我们的身体和器官之间的关系,单车与链条之间的关系。里面包含的,可以称之为“内部类”。这个包含关系通俗来说就是“一个类内部包含另一个 类”。
文章源自亦枫博客-https://yflad.cn/2064.html
1、内部类的定义
把一个类定义在某个类(某个类则称为“外部类”)中的,这个类就被称为内部类,内置类,嵌套类。文章源自亦枫博客-https://yflad.cn/2064.html
文章源自亦枫博客-https://yflad.cn/2064.html
Java内部类的分类
- 成员内部类
- 局部内部类(包含匿名内部类)
文章源自亦枫博客-https://yflad.cn/2064.html
内部类的位置
A:成员位置文章源自亦枫博客-https://yflad.cn/2064.html
可以被private修饰(Body,Heart) 可以被static修饰。(它访问的外部类的成员必须是静态的)文章源自亦枫博客-https://yflad.cn/2064.html
B:局部位置文章源自亦枫博客-https://yflad.cn/2064.html
- 可以直接访问外部类中的成员
- 也可以直接访问局部成员,但是局部成员要用final修饰。
注意:局部内部类不能用private和static修饰文章源自亦枫博客-https://yflad.cn/2064.html
文章源自亦枫博客-https://yflad.cn/2064.html
通过class文件我们就可以区分是否带有内部类,以及内部类的位置文章源自亦枫博客-https://yflad.cn/2064.html
Outer$Inner:成员内部类 Outer$1Inner:局部内部类
文章源自亦枫博客-https://yflad.cn/2064.html
什么时候会用到内部类呢?
假如有A类和B类,A类想直接访问B类的成员,B类访问A类成员的时候,需要创建A类对象进行访问,这个时候,就可以把A类定义为B类的内部类。文章源自亦枫博客-https://yflad.cn/2064.html
文章源自亦枫博客-https://yflad.cn/2064.html
成员内部类的访问特点:
- 内部类访问外部类,可以随意访问。因为内部类持有外部类的引用,格式为:外部类名.this
- 外部类要想访问内部类的成员,必须创建对象访问。
文章源自亦枫博客-https://yflad.cn/2064.html
成员内部类的语法:
public class 外部类的名称{ // 外部类的代码块; 修饰符 class 内部类的名称{ //成员内部类; } }
文章源自亦枫博客-https://yflad.cn/2064.html
成员内部类的访问格式:
A: 当内部类定义在外部类的成员位置,而且非私有,则可以在其他外部类中直接建立内部类对象文章源自亦枫博客-https://yflad.cn/2064.html
格式:外部类名.内部类名 变量名 = new 外部类对象.内部类对象 Outer.Inner in = new Outer().new Inner()
文章源自亦枫博客-https://yflad.cn/2064.html
B: 当内部类在外部类成员位置,且被static修饰时文章源自亦枫博客-https://yflad.cn/2064.html
1)外部其他类可直接访问静态内部类的非静态成员文章源自亦枫博客-https://yflad.cn/2064.html
格式:new 外部类名.内部类名().内部类成员 如:new Outer.Inner().function();
2)外部其他类可直接访问静态内部类的静态成员文章源自亦枫博客-https://yflad.cn/2064.html
格式:new 外部类名.内部类名.内部类成员 如:new Outer.Inner.function();
例如:
package cn.oop.d1_inner; /** * @Author: yflad (bat@yflad.cn) * @Blog: https://yflad.cn * @Date: 2019-01-05 * @Role: 内部类 */ public class D1_Inner { private String name; // 外部类的成员变量 public class Member { // 成员内部类 public void stus() { // 内部类的方法 System.out.println("这是成员内部类的方法"); System.out.println("我叫:" + name); // 正确写法! } } public void Student() { // 外部类的方法 System.out.println("外部类的方法"); new Member().stus(); // 外部类访问内部类的方法 } public String getName() { return name; } public void setName(String name) { this.name = name; } }
实现类:
package cn.oop.d1_inner; /** * @Author: yflad (bat@yflad.cn) * @Blog: https://yflad.cn * @Date: 2019-01-05 * @Role: */ public class D1_InnerTest { public static void main(String[] args) { D1_Inner stu = new D1_Inner(); // 外部类的对象 stu.Student(); System.out.println("====================="); D1_Inner.Member member = new D1_Inner().new Member(); // 内部类的对象 member.stus(); } }
输出结果:
拓展:内部类同名之间的访问
public class D2_InnerS { int num = 10; // 外部类的成员变量 public class Member { int num = 20; // 内部类的成员变量 public void stus() { // 内部类的方法 int num = 30; // 内部类方法的成员变量 System.out.println("内部类方法的成员变量: " + num); System.out.println("内部类的成员变量: " + this.num); // 内部类的成员变量 System.out.println("外部类的成员变量: " + D2_InnerS.this.num); // 外部类的成员变量 } } }
实现类:
public class D2_InnerSTest { public static void main(String[] args) { D2_InnerS.Member student = new D2_InnerS().new Member(); student.stus(); } }
输出结果:
小结:
- 内部类作为外部类的成员,可以访问外部类的私有成员或属性。
- 用内部类定义在外部类中不可访问的属性。这样就会在外部类中实现了比外部类的private还要小的访问权限。
- 成员内部类的引用方式必须为[code]外部类名.内部类名称[/code]。
- 当成员内部类拥有和外部类同名的成员变量或者方法时,默认情况下访问的是成员内部类的成员。可参考上面的拓展
注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。如上面提到的class文件区分
关于内部类和成员内部类的四种访问权限:
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。(来源:百度)
如果错误,欢迎指正补充!