java--内部类

内部类(内置类、嵌套类)

定义:指将一个类的定义放在另一个类的定义内部。

分类:静态内部类、成员内部类、局部内部类、匿名内部类。

特点
 
1)一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
 
2)内部类不为同一包的其他类所见,具有很好的封装性;
 
3)内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
 
4)匿名内部类可以很方便的定义回调。
 
5)外部类不能直接使用内部类属性,不能直接调用内部类的方法。外部类要访问内部类的成员,必须要建立内部类的对象,通过内部类对象类调用内部类资源。
 
6)内部是编译时的概念,一旦编译成功,内部类和外部类就会成为两个完全不同的类。
 
在java 里任何一个类,无论是以怎样的形式定义,在编译之后生成字节码文件之后,其必然是一个单独存在的类。
 
java加载任何一个类的时候都是会首先从加载其class文件开始,若一个类不存在对应的class文件,那么它必然无法被加载也无法被使用。
 
因此,内部类的成员变量/方法名可以和外部类的相同
 
7)内部类可以被继承,也可被覆盖。


静态内部类

不常用。(浪费内存)

定义:指在类内部的静态类。

特点:
 
static 修饰类只能修饰内部类。
 
静态内部类可以访问外部类所有的静态变量,不可访问外部类的非静态变量,但可以通过new 外部类().成员的方式访问。

举例 :

public class Outer {
    //定义外部类的成员变量
    int i = 1;

    //定义 静态内部类
    public static class Inner {
        //定义内部类的成员变量
        int i = 2;
        //静态内部类的方法
        public void visit() {
        //通过new 外部类().成员的方式访问外部类的非静态变量
            System.out.println("visit outer   variable:" + new Outer().i);
            System.out.println("visit inner   variable:" + i);
        }
    }

    public static void main(String[] args) {
        //创建静态内部类的对象时,不需要外部类的对象,可以直接创建
        //创建外部类对象
        //Outer o = new Outer();

        //不可以写成Inner i = o.new Inner(); 因为是静态内部类,不是成员内部类
        Inner i = new Inner();
        //通过内部类对象调用内部类方法
        i.visit();
    }
}

结果:
在这里插入图片描述

成员内部类(普通内部类)

定义:指在类内部,成员位置上的非静态类。

特点:
 
可以使用任意访问修饰符,如:public、private、protected等。
 
成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有,即不受访问修饰符影响。
 
普通内部类对象依赖外部类对象而存在,即在创建一个普通内部类对象时首先需要创建其外部类对象

举例:

public class Outer {

    private static  int radius = 1;
    private int count =2;

    //成员内部类
    class Inner {
        public void visit() {
            System.out.println("visit outer static  variable:" + radius);
            System.out.println("visit outer   variable:" + count);
        }
    }

    public static void main(String[] args) {
        //在创建内部类Inner对象时,要首先创建外部类Outer对象,不可以直接new一个内部类对象
        //外部类要想访问内部类的成员,必须创建对象访问。
        Outer o = new Outer();
        //下面这一步也可以写成:Outer.Inner i = o.new Inner();
        //内部类 对象名 = 外部类对象.new 内部类( );
        Outer.Inner i = o.new Inner();
        i.visit();
    }
}

结果:
在这里插入图片描述

局部内部类(方法内部类)

定义:局部内部类定义在外部类的方法中,只在该方法内可以用;

特点:
 
定义在实例方法中的局部类可以访问外部类的所有变量和方法
 
定义在静态方法中的局部类只能访问外部类的静态变量和方法。
 
不能使用访问控制符和static修饰符,因为局部类不能在外部类的方法以外的地方使用。

举例:

//外部类
public class Outer {

    private  int outer_a = 1;         //外部类的私有成员变量
    private static int STATIC_b = 2;    //外部类的静态 私有成员变量

    //外部类中的普通方法
    public void testFunctionClass(){
        int outer_c =3;     //外部类中的变量

        //局部内部类(方法内部类)
        class Inner {
            int inner_d = 4;    //局部内部类中的变量
            private void visit(){
                System.out.println("outer_a:" + outer_a);
                System.out.println("STATIC_b:" + STATIC_b);
                System.out.println("outer_c:" + outer_c);
                System.out.println("inner_d:" + inner_d);
            }
        }

        //创建方法内部类中的对象
        Inner  i = new Inner();

        //调用方法内部类中的方法
        i.visit();
    }

    //外部类中的静态方法
    public static void testStaticFunctionClass(){
        int outer_d =5;      //局部内部类中的变量
        class Inner {
            private void visit(){
                //System.out.println("outer_a:" + outer_a);   编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
                System.out.println("STATIC_b:" + STATIC_b);
                System.out.println("outer_d:" + outer_d);
            }
        }

        //创建方法内部类中的对象
        Inner  i = new Inner();

        //调用方法内部类中的方法
        i.visit();
    }

    public static void main(String[] args) {
        //创建外部类的对象
        Outer o = new Outer();

        //调用外部类的方法
        //o.visit();错误,编译不通过
        o.testFunctionClass();

        o.testStaticFunctionClass();

    }

}

结果:
在这里插入图片描述

匿名内部类

常用。

定义:没有名字的内部类。

特点:
 
1)没有访问修饰符
 
2)没有构造方法
 
3)定义匿名内部类的前提是,内部类必须是继承一个类或者实现接口,格式为 new 父类 / 接口(){ //匿名内部类实现部分 )}
 
也就是说,匿名内部类最终提供给我们的是一个匿名子类的对象

举例:

public class Outer {

    public Outer() {
        //this.getClass().getSimpleName()方法以String的形式返回此类的简单名称。如果此类是匿名的,则此方法返回空字符串。
        System.out.println("创建 " + this.getClass().getSimpleName() + " 对象");
    }

    // 自定义接口
    interface Interface01 {
        void visit(Object obj);
    }

    //创建一个实现类,书写visit()方法的具体实现过程
//    public class Interface01Impl implements Interface01{
//        @Override
//        public void visit() {
//            System.out.println("I'm a impl class...");
//        }
//    }

    private void anonymousClassTest() {
        //如果实现类Interface01Impl全程只使用一次,为了这一次的使用去创建一个类过于麻烦
        // 在这个过程中会新建一个匿名内部类对象,
        // 这个匿名内部类实现了 Interface01 接口并重写 visit 方法
        Interface01 interface01  = new Interface01() {
            // 可以在内部类中定义属性,但是只能在当前内部类中使用,
            // 无法在外部类中使用,因为外部类无法获取当前匿名内部类的类名,
            // 也就无法创建匿名内部类的对象
            int i = 1;

            @Override
            public void visit(Object obj) {
                System.out.println("对象 " + obj + " 被访问");
            }
        };


        // new Object() 过程会新建一个匿名内部类,继承于 Object 类,
        // 并重写了 toString() 方法
        interface01.visit(new Object() {
            @Override
            public String toString() {
                return "obj1";
            }
        });
    }

    public static void main(String[] args) {
        Outer o = new Outer();
        o.anonymousClassTest();
    }
}

结果:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值