内部类包括四种形式,成员内部类,静态内部类(用static修饰),局部内部类,匿名内部类
概念:在一个类的内部再定义一个完整的类。
Class Outer{//外部类
class Inner{
//内部类(也会生成class 文件)
}
}
特点:1.编译之后可生成独立的字节码文件(比如上述代码会生成Outer$Inner.class Outer.class) 2.内部类可以直接访问外部类的私有成员,而不破坏封装 3.可为外部类提供必要的功能组件
1.在类的内部定义,与实例变量、实例方法同级别的类。 2.外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象(见代码)
//创建内部类对象之前,需要创建外部类对象
Outer outer = new Outer();
//创建内部类对象
Inner inner = outer.new Inner();
//一步到位
Inner inner = new Outer().new Inner();
- package com.mh.fdsf_1101;
- //外部类
- public class Outer {
- private String name="张三";
- private int age=30;
-
- //内部类
- class Inner{
- private String address = "北京";
- private String phone = "110";
-
- public void show() {
- //打印外部类的属性
- System.out.println(name);
- System.out.println(age);
- //打印内部类属性
- System.out.println(address);
- System.out.println(phone);
- }
- }
- }
-
-
-
- package com.mh.fdsf_1101;
-
- import com.mh.fdsf_1101.Outer.Inner;
-
- public class TestOuter {
- public static void main(String[] args) {
- //创建内部类对象之前,需要创建外部类对象
- Outer outer = new Outer();
- //创建内部类对象
- Inner inner = outer.new Inner();
-
- /**
- 一步到位
- Inner inner = new Outer().new Inner();
- */
-
- inner.show();
- }
- }
-
-
3. 当外部类,内部类存在重名属性时,会优先访问内部类属性。如需调用(外部类名称.this. 属性)
4.成员内部类不能定义静态成员但可以包含静态常量
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员(级别相当于外部类,为外部类提供功能)
详细使用方法和注意事项见代码注释
- package com.mehu.nbl;
-
- public class Outer {//外部类
- private String name="jk";
- private String age="0";
-
- //静态内部类与外部类相同
- static class Inner{
- private String address="hunan";
- private String phone = "666";
- //静态成员
- private static int count=1000;
-
- public void show() {
- //调用外部类属性,先创建外部类对象
- Outer outer = new Outer();
- //调用外部类对象属性
- System.out.println(outer.name);
- System.out.println(outer.age);
- //调用静态内部类的属性和方法
- System.out.println(address);
- System.out.println(phone);
- //调用静态内部类的静态属性
- System.out.println(Inner.count);
- }
- }
- }
-
-
-
- package com.mehu.nbl;
-
- public class TestOuter {
- public static void main(String[] args) {
- //直接创建静态内部类对象
- Outer.Inner inner = new Outer.Inner();//注意,Outer后没写括号仅表示一种包含关系
- //调用方法
- inner.show();
- }
- }
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。(详细用法和注意事项见代码注释)
- package com.mehu.chengyuanneibulei;
-
- public class Outer {//外部类
- private int age = 35;
- private String name ="刘德华";
-
- public void show() {
- String address ="cs";
-
- //局部内部类:注意不能加任何刚问修饰符
- class Inner{
- //局部内部类属性
- private String phone = "0";
- private String email ="xxxxxx";
-
- public void noval() {
- //访问外部类的属性
- System.out.println(name);
- System.out.println(age);
- //访问内部类属性
- System.out.println(phone);
- System.out.println(email);
- //访问局部类对象,jdk1.7要求,变量必须是常量.jdk1.8之后省略不写,自动添加
- System.out.println(address);
- }
- }
- //创建局部类对象,如果如果不创建将无法访问,注意创建位置在外部类中,内部类的后面。
- Inner inner = new Inner();
- inner.noval();
- }
- }
-
-
-
- package com.mehu.chengyuanneibulei;
-
- public class TestOuter {
- public static void main(String[] args) {
- Outer outer = new Outer();//注意不能直接创建Inner对象
- outer.show();//注意Outer类中一定要创建内部类对象
- }
- }
局部内部类访问外部类当前方法中的局部变量时,应无法保障变量的生命周期与自身相同,变量必须用final修饰(可省略,系统默认添加)。(见上述代码)
限制类(局部内部类)的使用范围
没有类名的局部内部类(一切特征都与局部内部类相同)。(其实匿名内部类的类名是系统默认给的,这里为TestUsb$1)
必须继承一个父类或者实现一个接口。(详细见代码)
- package com.mehu.nimingneibulei;
- //接口
- public interface Usb {
- void service();
- }
-
-
- package com.mehu.nimingneibulei;
-
- public class Mouse implements Usb{
-
- @Override
- public void service() {
- System.out.println("鼠标开始工作");
-
- }
-
- }
-
-
-
- package com.mehu.nimingneibulei;
-
- public class TestUsb {
- public static void main(String[] args) {
- //创建接口类型的变量
- Usb usb1 = new Mouse();
- usb1.service();
-
- //局部内部类
- class fan implements Usb{
-
- @Override
- public void service() {
- System.out.println("风扇开始工作了");
-
- }
-
- }
- //使用局部内部类创建对象
- Usb usb2 = new fan();
- usb2.service();
- //局部内部类如果只使用一次,创建对象后不再使用,就会显得多余
- //使用匿名内部类优化(相当于创建局部内部类)
- Usb usb = new Usb(){//Usb可以使抽象类,也可以是父类。可以在里面重写方法
- @Override
- public void service() {
- System.out.println("风扇开始工作了");
- }
- };
- usb.service();
- }
- }
匿名内部类相当于定义类,实现类,创建对象的语法合并,只能创建一个该类对象。
优点:减少代码量。
缺点:可读性较差。