Java面向对象编程篇4——内部类
1、内部类的概念
当一个类的定义出现在另外一个类的类体中时,那么这个类叫做内部类 (Inner),而这个内部类所在的类叫做外部类(Outer)。
类中的内容:成员变量、成员方法、构造方法、静态成员、构造块和静态代码块、内部类
2、内部类的意义
当一个类存在的价值仅仅是为某一个类单独服务时,那么就可以将这个 类定义为所服务类中的内部类,这样可以隐藏该类的实现细节并且可以 方便的访问外部类的私有成员而不再需要提供公有的get和set方法。
3、内部类的分类
3.1、成员内部类
直接将一个类的定义放在另外一个类的类体中
访问修饰符 class 外部类的类名 {访问修饰符 class 内部类的类名 {内部类的类体;}
}
public class Outer {//成员变量private int outerNum = 1;//内外重复的变量private int commonNum = 2;//静态成员变量private static int staticOuterNum = 3;/*** 成员方法*/public void outerMethod() {System.out.println("我是外部类的outerMethod方法");}/*** 静态方法*/public static void staticOuterMethod() {System.out.println("我是外部类的staticOuterMethod静态方法");}class Inner{//成员变量private int innerNum = 1;//内外重复的变量private int commonNum = 20;public void innerShow() {//当和外部类冲突时,直接引用属性名,是内部类的成员属性System.out.println("内部的commonNum:" + commonNum);//内部类访问外部属性System.out.println("outerNum:" + outerNum);//当和外部类属性名重叠时,可通过外部类名.this.属性名System.out.println("外部的commonNum:" + Outer.this.commonNum);System.out.println("staticOuterNum:" + staticOuterNum);//访问外部类的方法outerMethod();staticOuterMethod();}}public void outershow() {Inner inner = new Inner();inner.innerShow();}public static void main(String[] args) {Outer outer = new Outer();outer.outershow();}
}
外部类使用
public class Test {public static void main(String[] args) {Outer outer = new Outer();outer.outershow();System.out.println("=======================");Outer.Inner inner = new Outer().new Inner();inner.innerShow();}
}
- 成员内部类可以是任何的访问修饰符
- 成员内部类的内部不能有静态信息
- 内部类也是类,该继承继承,该重写重写,该重载重载,this和super随便用(可以解决多继承问题)
- 外部类如何访问内部类信息,必须new之后访问
- 内部类可以直接使用外部类的任何信息,如果属性或者方法发生冲突,调用外部类.this.属性或者方法
- 其他类访问内部类需Outer.Inner inner = new Outer().new Inner();
3.2、静态内部类
使用static关键字修饰的内部类,隶属于类层级
访问修饰符 class 外部类的类名 {访问修饰符 static class 内部类的类名 {内部类的类体;}
}
public class Outer {//成员变量private int outerNum = 1;//内外重复的变量private int commonNum = 2;//静态成员变量private static int staticOuterNum = 3;static {System.out.println("Outer的静态块被执行了……");}/*** 成员方法*/public void outerMethod() {System.out.println("我是外部类的outerMethod方法");}/*** 静态方法*/public static void staticOuterMethod() {System.out.println("我是外部类的staticOuterMethod静态方法");}static class Inner{static {System.out.println("Outer.Inner的静态块执行了……");}//成员变量private int innerNum = 1;//内外重复的变量private int commonNum = 20;private static int staticInnerVariable = 30;/*** 成员方法*/public void innerShow() {System.out.println("innerNum:" + innerNum);System.out.println("内部的commonNum:" + commonNum);System.out.println("staticOuterNum:"+staticOuterNum);staticOuterMethod();}/*** 静态方法*/public static void innerStaticShow() {//被调用时会先加载Outer类staticOuterMethod();System.out.println("staticOuterNum"+staticOuterNum);}}public static void callInner() {System.out.println("staticInnerNum"+Inner.staticInnerVariable);Inner.innerStaticShow();}public static void main(String[] args) {callInner();}
}
外部使用静态内部类
public class Test {public static void main(String[] args) {Outer.callInner();System.out.println("====================");Outer.Inner.innerStaticShow();System.out.println("====================");Outer.Inner inner = new Outer.Inner();inner.innerShow();}
}
- 静态内部类可以包含任意的信息
- 静态内部类的方法只能访问外部类的static关联的信息
- 利用 外部类.内部类 引用=new 外部类.内部类(); 然后利用引用.成员信息(属性、方法)调用。
- 访问内部类的静态信息,直接外部类.内部类.静态信息
3.3、局部内部类
直接将一个类的定义放在方法体的内部
访问修饰符 class 外部类的类名 {访问修饰符 返回值类型 成员方法名(形参列表) {class 内部类的类名 {内部类的类体;}}
}
public class Outer {//成员变量private int outerNum = 1;//内外重复的变量private int commonNum = 2;//静态成员变量private static int staticOuterNum = 3;static {System.out.println("Outer的静态块被执行了……");}/*** 成员方法*/public void outerMethod() {boolean flag=false;System.out.println("我是外部类的outerMethod方法");class Inner{//成员变量private int innerNum = 1;//内外重复的变量private int commonNum = 20;/*** 成员方法*/public void innerShow() {System.out.println("flag:" + flag);System.out.println("innerNum:" + innerNum);System.out.println("内部的commonNum:" + commonNum);System.out.println("外部的commonNum:" + Outer.this.commonNum);System.out.println("staticOuterNum:"+staticOuterNum);staticOuterMethod();}}new Inner().innerShow();}/*** 静态方法*/public static void staticOuterMethod() {System.out.println("我是外部类的staticOuterMethod静态方法");}public static void main(String[] args) {new Outer().outerMethod();}
}
- 局部内部类,类前不能有访问修饰符
- 局部内部类只能在方法内使用
- 无法创造静态信息
- 可以直接访问方法内的局部变量和参数,但是不能更改
- 可以随意的访问外部类的任何信息
- 匿名内部类的方法中用到的局部变量都必须定义为final
3.4、匿名内部类
就是指没有名字的内部类
接口/父类类型 引用变量名 = new 接口/父类类型() { 方法的重写 };
接口
public interface Animal {void speak();
}
使用
public class Outer {public static void main(String[] args) {//接口/父类类型 引用变量名 = new 接口/父类类型() { 方法的重写 };Animal animal=new Animal() {@Overridepublic void speak() {System.out.println("喵喵喵");}};animal.speak();}
}
- 匿名内部类是没有访问修饰符的
- 使用匿名内部类时,这个new之后的类首先是要存在的,其次我们要重写new后的类的某个或某些方法
- 匿名内部类访问方法参数时也有和局部内部类同样的限制
- 匿名内部类没有构造方法