一、为何使用内部类
内部类提供了更好的封装,只有外部类才可以访问,有时候我们不需要外部访问当前类的一些属性和方法,那么可以将这部分定义成内部类,对外隐藏实现;
内部类可以继承类或接口,实现多重继承;
内部类可以直接访问外部类的方法和属性,即使是private的;
二、内部类和外部类之间的联系
1.>两者是两个独立的实体,并没有is-a这种关系
在编译后,可以发现外部类和内部类会分别生成一个class文件:outClass.class和OutClass$InnerClass.class文件;
2.>内部类可以直接访问外部类的属性,但外部类则不可以直接访问内部类的属性
例子
package com.example.springbootDemo.service.innerClassTest; public class OuterClass { private String outName; private int outAge; public String getOutName() { return outName; } public void setOutName(String outName) { this.outName = outName; } public int getOutAge() { return outAge; } public void setOutAge(int outAge) { this.outAge = outAge; } public class InnerClass { private int innerAge; public InnerClass() { outName = "this is outerClass property"; outAge = 20; } public void display() { System.out.println(outName + "and outAge is" + outAge); } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); InnerClass innerClass = outerClass.new InnerClass(); innerClass.display(); System.out.println(outerClass.getOutAge()); System.out.println(outerClass.getOutName()); } }
返回结果
this is outerClass propertyand outAge is20
20
this is outerClass property
上面的例子可以看出,内部类可以直接访问外部类的private属性和方法;因为在创建外部类的同时,内部类会自动获取一个外部类的引用,所以内部类访问外部的元素是直接通过持有的外部类的引用来访问的。可以通过OutClass.this来获取这个外部引用;例如
package com.example.springbootDemo.service.innerClassTest; public class OuterClass { private String outName; private int outAge; public String getOutName() { return outName; } public void setOutName(String outName) { this.outName = outName; } public int getOutAge() { return outAge; } public void setOutAge(int outAge) { this.outAge = outAge; } public class InnerClass { private int innerAge; public InnerClass() { outName = "this is outerClass property"; outAge = 20; } public void display() { System.out.println(OuterClass.this.getOutName()); } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); InnerClass innerClass = outerClass.new InnerClass(); innerClass.display(); } }
3>外部类不可以直接访问内部类的属性和方法,但是却可以通过内部类的引用,间接的访问内部类的属性和方法
package com.example.springbootDemo.service.innerClassTest; public class OuterClass { private String outName; private int outAge; public void display() { InnerClass innerClass = new InnerClass(); innerClass.display(); } public class InnerClass { private int innerAge; public InnerClass() { outName = "this is outerClass property"; outAge = 20; } public void display() { System.out.println(outName + "and outAge is:" + outAge); } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); outerClass.display(); } }
三.内部类的种类
1>成员内部类
成员内部类是比较常见的内部类,是外部类的一个成员存在,可以无限制访问外部类的所有属性和方法;反之,外部类要访问内部类的属性和方法,则必须new一个内部类,通过这个引用来访问;
有两点需要注意:
1.成员内部类中不能存在任何static的方法和属性
public class InnerClass { private int innerAge; private static int a = 10;下面的语句会报错显示;
2.成员内部类是依附于外部类的,只有先有外部类的实例才可以有内部类
2>匿名内部类
匿名内部类是没有名字的方法内部类,必须继承一个抽象类或者实现一个接口,不做过多说明;
3>静态内部类
在java中static关键字不仅可以修饰方法,属性,代码块,其实还可以修饰内部类,使用static修饰的内部类称为是静态内部类;静态内部类区别与成员内部类的一个最大的区别是,成员内部类在创建外部类的时候会自动创建一个指向外部类的引用,但是静态内部类却没有。所以
静态内部类的创建不依赖于外部类,可以直接创建;
静态内部类不可以使用外部类的任何非静态的属性和方法,因为外部类的非静态的属性和方法是依附于某个外部类的对象的,而静态内部类却并不需要外部类就可以创建;