内部类
内部类
一、基本概念
-
基本介绍:
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员(五大成员:属性、方法、构造器、代码块、内部类),内部类最大特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
-
基本语法
class Outer{//外部类 class Inner{//内部类 } } class Other{//外部其他类 }
-
内部类的分类
- 定义在外部类局部位置上(比如方法内/代码块)
- 局部内部类(有类名)
- 匿名内部类(无类名,重点!!!!)
- 定义在外部类的成员位置上:
- 成员内部类(没用static修饰)
- 静态内部类(使用static修饰)
- 定义在外部类局部位置上(比如方法内/代码块)
二、局部内部类的使用
说明:局部内部类是定义在外部类的局部位置,比如方法中,并且有类名,也可以在代码块中,本质仍然是个类。
- 可以直接访问外部类的所有成员,包括私有的;
- 不能添加访问修饰符,因为他的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final 修饰,因为局部变量也可以使用final;
- 作用域:仅仅在定义它的方法或代码块中;
- 局部内部类 访问 外部类的成员【访问方式:直接访问】;
- 外部类 访问 局部内部类的成员【访问方式:创建对象,再访问(注意:必须在作用域内)】;
- 外部其他类,不能访问局部类(因为局部类地位是一个局部变量);
- 如果外部类和局部内部类的成员重名时,默认遵守就近原则,如果想访问外部类的成员,使用(外部类名.this.成员)去访问,(外部类名.this)本质就是外部类的对象;
tip:内部类是延时加载的,也就是说只会在第一次使用时加载。不使用就不加载,所以可以很好的实现单例模式。
三、匿名内部类的使用
-
要点
- 本质是类
- 内部类
- 该类没有名字,类名由系统分配
-
匿名内部类的基本语法
new 类或接口(参数列表){
//类体
};
- 匿名内部类使用细节
-
匿名内部类的语法比较奇特,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面代码分析可以看出这个特点,因此可以调用匿名内部类方法。
-
可以直接访问外部类的所有成员,包含私有的
-
不能添加访问修饰符,因为它的地位就是一个局部变量。
-
作用域:仅仅在定义它的方法或者代码块中。
-
匿名内部类 ----访问----->外部类成员【访问方式:直接访问】
-
外部其他类---不能访问---->匿名内部类(因为 匿名内部类地位是一个局部变量)
-
如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵守就近原则,如果相访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
-
匿名内部类使用一次就不能再使用,会被立马销毁,但是创建的对象还能使用。
-
匿名内部类的构造方法:因为匿名内部类没有名字这个特殊性质,所以我们无从给它指定构造方法,构造方法必须和类名同名,类名都没有,构造方法就无从谈起了。但是匿名内部类可以通过直接调用父类的构造方法实现初始化,当然要求父类构造方法对它父类中定义的成员变量进行初始化。
-
四、 成员内部类的使用
说明:成内部类是定义在外部类的成员位置,并且没有static修饰。
-
可以直接访问外部类的所有成员,包含私有的。
class Outer01{//外部类 private int n1 = 10; public String name = "张三"; class Inner01{ public void say(){ System.out.println("Outer01 的 n1 = " + n1 + "Outer01 的 name = " + name); } } }
-
可以添加任意的访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
-
作用域:和外部类的其他成员一样,为整个类体。
-
成员内部类 --- 访问----> 外部类的成员(比如属性)【访问方式:直接访问,外部类名.this.成员当然也可以】。
-
外部类 ---访问---->内部类【访问方式:创建对象,再访问】。
-
外部其他类---访问---->成员内部类。
-
如果外部类和内部类的成员重名时,内部类访问的话,默认遵守就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
五、静态内部类的使用
说明:静态内部类是定义在外部类的成员位置,并且有static修饰。
-
可以直接访问外部类的所有静态成员,包含私有的但不能直接访问非静态成员。
-
可以添加任意访问修饰符,因为他的地位就是个成员。
-
作用域:同其他的成员,为整个类体。
-
静态内部类---访问----> 外部类(比如:静态属性)【访问方式:直接访问所有静态成员】。
class Outer10{ private int n1 = 10; private static String name = "张三"; public static class Inner10{ public void say(){ System.out.println(name); } } }
-
外部类-----访问----->静态内部类 访问方式:创建对象,再访问
class Outer10{ private int n1 = 10; private static String name = "张三"; public static class Inner10{ public void say(){ System.out.println(name); } } public void m1(){ Inner10 inner10 = new Inner10(); inner10.say(); } }
-
外部其他类----访问----->静态内部类
public class StaticInnerClass01 { public static void main(String[] args) { //外部其他类 使用静态内部类 //方式1 //因为静态内部类,是可以通过类名直接访问(前提是满足访问权限) Outer10.Inner10 inner10 = new Outer10.Inner10(); inner10.say(); System.out.println("============="); //方式2 //编写一个方法,可以返回静态内部类的实例 Outer10.Inner10 inner101 = outer10.getInner10(); inner101.say(); //编写静态一个方法,可以返回静态内部类的实例 System.out.println("**************"); Outer10.Inner10 inner10_ = Outer10 .getInner10_(); inner10_.say(); } } class Outer10{ private int n1 = 10; private static String name = "张三"; public static class Inner10{ public void say(){ System.out.println(name); } } public void m1(){ Inner10 inner10 = new Inner10(); inner10.say(); } public Inner10 getInner10(){ return new Inner10(); } public static Inner10 getInner10_(){ return new Inner10(); } }
-
如果外部类和静态内部类的成员重名时,静态内部类访问时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问。
tip: 如果一个类要被声明为static的,只有一种情况,就是静态内部类。