java学习——内部类的简单整理

  内部类就是在一个类中定义一各类,而这个类被称为内部类。内部类共有四种:成员内部类,静态内部类,局部内部类,匿名内部类。

一、使用内部类的好处
  1.内部类可以很好的实现隐藏,一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
  2.内部类拥有外围类的所有元素的访问权限
  3.可以实现多重继承
  4.可以避免修改接口而实现同一个类中两种同名方法的调用。

二、简单介绍各种内部类
成员内部类。
  成员内部类是最普通的内部类,其定义形式如下:

public class OuterClass {
    private int a = 9;                     //外部类成员变量

    private void fun() {                   //外部类成员函数
        System.out.println("out");

    }

    class IntClass {
        private int b = 5;                   //内部类成员变量

        private void test() {                   //内部类成员变量
            System.out.println("a=" + a);       //调用外部类成员变量
            System.out.println("b=" + b);       //调用内部类成员变量

            fun();                          //调用外部类成员函数

        }
    }

    public static void main(String[] argv) {
        OuterClass o=new OuterClass();      //建立外部类对象
        o.fun();                       //调用外部类成员函数
        //o.test();                       //报错
        IntClass i=o.new IntClass();          //建立内部类对象
//IntClass i=OuterClass.new IntClass();          //报错
        i.test();                         //调用内部类成员函数

    }
}

运行的结果为
在这里插入图片描述
  1 内部类与外部类是两个独立完整的类,在运行是生成各自的.class文件,如上述代码回生成OuterClass.class, IntClass.class文件。
  2 内部类相当于内部类的的一个成员变量的位置,可以使用任意访问控制符,如 public 、 protected 、 private 等
  3 内部类中,可以随意访问外部类的成员方法与成员变量(不受访问控制符的影响),但内部类不可以访问内部类的成员变量与成员方法。
  其原因为:
  内部类持有外部类的引用。
   (1)编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象(this)的引用;
   (2)编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为内部类中添加的成员变量赋值;
   (3)在调用内部类的构造函数初始化内部类对象时,会默认传入外部类的引用。
  4 内部类的实例一定绑定在外部类的实例上,存在外部类对象,才能出现内部类对象。
   实例化内部类的方法:
    内部类 对象名 = 外部类对象.new 内部类( );(不能使用外部类名称来实例化内部类对象)
  5 要调用内部类的方法只能通过实例内部类对象来调用。

·局部内部类

interface OutInterface{
     void fun();
}
public class OutClass1 {
    public OutInterface doit() {

        class IntClass implements OutInterface {
            public void fun() {
                System.out.println("实现接口方法");
            }
        }
        return new IntClass();
    }
    public static void main(String[] argv) {
        OutClass1 o = new OutClass1();
        OutInterface oi = o.doit();
        oi.fun();

    }
}

其运行结果为:
在这里插入图片描述

  1 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
  2 由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
  3 可以访问当前代码量的常量及外部类所有成员

·匿名内部类

interface OutInterface{
        void fun();
    }
public class OutClass2 {
    public OutInterface doit() {

        return new OutInterface() {
            public void fun() {
                System.out.println("实现接口方法");
            }
        };
    }

public static void main(String[] argv) {
            OutClass2 o = new OutClass2();
            OutInterface oi = o.doit();
            oi.fun();

        }
    }

  1 匿名内部类是没有名称的,所以匿名内部类没有构造函数,不能定义静态成员,编译时会产生“外部类名$序号”为名称的.class文件。
  2 必须继承一个接口或者继承一个类
  3 只可以创建一个实例(通过构造块实现),不能用访问控制符,static,final,abstract修饰
  4 只能使用外部类方法中的常量形参。

·静态内部类

public class OutClass {
    static int a = 9;
    static int b = 10;
    void fun() {
        System.out.println("out");
    }
    static class IntClass {
        int b = 5;

        public void test() {
            System.out.println(a);
            System.out.println(OutClass.b);
            System.out.println(b);
            new OutClass().fun();
        }
        public static void main(String[] argv) {
            IntClass i = new IntClass();
            i.test();
        }
    }
}

其运行结果为:
在这里插入图片描述
  1 创建静态内部类的对象时,不需要外部类的对象,可以直接创建:
内部类 对象名= new 内部类();
  2 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。
  3 如果外部类的静态成员与内部类的成员同名,可通过 类名.静态成员 访问外部类的静态成员;

三、内部类向上转型为接口

interface OutInerface{
    public void fun();
}
public class OutClass {
    OutClass() {
        System.out.println("new OutClass");
    }
    public IntClass doit() {
        return new IntClass();
    }
    private class IntClass implements OutInerface {
        IntClass() {
            System.out.println("new IntClass");
        }
        public void fun() {
            System.out.println("实现接口方法");
        }
    }
    public static void main(String[] argv) {
        OutClass o = new OutClass();
        OutInerface oi = o.doit();
        oi.fun();
    }
}

其运行结果为:

在这里插入图片描述
   定义一个接口,可以在一个类中定义多个内部类以不同的方法实现该接口。通过内部类实现接口,为继承外部类的子类只留下接口与方法,隐藏了方法的实现细节。

四、this的使用
当内部类与外部类成员变量或者方法相同方式,可用this进行区别调用。

public class OutClass {
    private int a = 9;
     void fun() {
        System.out.println("out");
    }
    class IntClass {
        private int a = 5;
         void test(int a) {
            int x =a;                     //形参a
            int y = this.a;                 //内部类变量a
            int z = OutClass.this.a;          //外部类变量a
            System.out.println(x + "  " + y + "  " + z );
        }
        private void fun() {
            System.out.println("int");
        }
    }
        public static void main(String[] argv) {
            OutClass o = new OutClass();
            o.fun();
            IntClass i = o.new IntClass();
            i.test(1);
            i.fun();
        }
}

其运行结果
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值