内部类(JAVA)

内部类

允许一个类定义在另一个类的内部,前者称为内部类,后者称为外部内

1.内部类可以使用外部类的私有数据(因为是外部类的成员,同一个类的成员之间可以互相访问)

2.外部类想要访问内部类中的成员时,需要内部类.成员内部类对象.成员

1.非静态内部类

没有使用static修饰的成员内部类是非静态内部类

1.不是说一个源程序中只能有一个public类?怎么内部类可以用public?

“在同一个源程序中只能有一个public类”应该理解为只有一个public类的名字与源码文件名一致。

特点:

1.当在非静态内部类的方法内访问某个变量时候,系统会优先查找该方法内是否存在该名字的局部变量,若存在,则使用,若不存在,那么再在方法所在的内部类中查找,找到则使用,若没找到,则再在该内部类所在的外部类中继续查找,找到则用,否则报找不到错误。

2.外部类属性/内部类属性与内部类里的方法的局部变量同名,那么可以用this或外部类名.this来限定区分

3.非静态内部类可以访问外部类的Private成员,反之不成立。非静态内部类的成员,只能在非静态(实例)内部类里使用,并不能被外部类直接使用。若外部类需要访问非静态内部类,则必须显示创建非静态内部类对象来访问其实例成员。

4.根据静态成员不能访问非静态成员的规则,外部类的静态方法,静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义的变量,创建实例等,总之不允许在外部类的静态成员中直接使用非静态内部类

5.不允许在非静态内部类里定义静态成员(方法,变量等),即非静态内部类里不能有静态方法、属性、初始化块

    public static void main(String[] args) {
        OutClass outClass = new OutClass();
        outClass.outPrint();
    }

public class OutClass {

    private String o1 = "外部类的实例变量";
    private static String o2 = "外部类的静态变量";

    //private:表示本内部类只能在外部类里面使用,其他外面都不能调用此内部类
    private class inClass{

        private String o1 = "内部类的实例变量o1";

        private String i1 = "内部类的实例变量i1";

        //**************特点:4,5
//        //报错:非静态内部类,不能申明静态属性
//        private static String o2 = "外部类的静态变量";

        public void print(){

            //**********特点1,2
            String o1 = "内部类局部变量o1";
            // 通过 外部类类名.this.varName 访问外部类实例变量
            System.out.println("外部类的实例变量值:"+ OutClass.this.o1);

            // 通过 this.varName 访问内部类实例的变量
            System.out.println("内部类的实例变量值:" + this.o1);

            // 直接访问局部变量
            System.out.println("局部变量的值:" + o1);

        }

    }

    public void outPrint(){

        System.out.println("外部类的实例变量值:"+ o1);
        
        //报错:未定义这个变量
//      System.out.println("外部类的实例变量值:"+ i1);
        
		//*********特点3:非实例内部类必须先实例化才能使用
        inClass inClass = new inClass();
        System.out.println("内部类:" + inClass.o1);

        inClass.print();

    }

}


image-20210124134446992

2.静态内部类

使用static修饰的成员内部类是非静态内部类

特点:

1.根据静态成员不能访问非静态成员的规则,外部类的静态方法,静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义的变量,创建实例等,总之不允许在外部类的静态成员中直接使用非静态内部类

2.静态内部类可以包含有静态方法、属性、初始化块,但静态内部类不能访问外部类的实例成员,即使静态内部类的实例方法也不能访问外部类的实例成员

public class OutClass1 {

    private String o1 = "外部类成员变量o1";
    private static String o2 = "外部类静态变量o2";

    static class inClass{
        void print(){
            //报错:o1变量找不到
            System.out.println("inClass-o1:"+o1);
            //o2可以使用
            System.out.println("inClass-o1:"+o2);
        }
    }
}

3.外部类依然不能直接访问静态内部类成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可使用静态内部类的对象作为调用者来访问静态内部类的实例成员。

public class OutClass2 {

    private static String o2 = "外部类静态变量o2";

    static class InClass{
        private static String o2 = "内部类静态变量o2";
    }

    void print(){

        System.out.println(o2);
        //内部类类.成员
        System.out.println(InClass.o2);
        //内部类对象.成员
        System.out.println(new InClass().o2);

    }

    public static void main(String[] args) {
        OutClass2 outClass2 = new OutClass2();
        outClass2.print();
    }

}

image-20210124154324418

3.局部内部类

若把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。局部内部类不能在外部类以外的地方使用,那么局部内部类也无需使用访问控制符合static修饰

特点:

1.对于局部内部类,它们的上一级程序单元是方法,而不是

public class OutClass7 {

    private String name = "外部类";

    void show(final String str){

        class InClass{
            private String name = "内部类";
            void print(){
                System.out.println("name = " + name + str);
            }
        }

        //整个生命周期在方法里
        InClass inClass = new InClass();
        inClass.print();

    }

    public static void main(String[] args) {
        OutClass7 outClass7 = new OutClass7();
        outClass7.show("demo");
    }
}

image-20210124170230778

3.1 匿名内部类

匿名内部类适合创建只需要一次使用的类,匿名内部类不能重复使用。没有类名的局部内部类

特点:

1.匿名内部类必须继承一个父类,或实现一个借接口,但最多只能继承一个父类或者实现一个接口,并且需要实现所有抽象方法

2.匿名内部类不能是抽象类。因为系统创建匿名内部类的时候,会立即创建匿名内部类对象,而抽象类不能直接创建。

3.匿名内部类不能定义构造器。因为匿名内部类米有类名,所以无法定义构造器

//定义一个接口
interface Parent{
    public String getName();
}

public class OutClass5 {

    public void MyName(Parent parent){
        System.out.println("我的名字"+parent.getName());
    }

    public static void main(String[] args) {
        //匿名内部类,实现一个接口
        new OutClass5().MyName(new Parent() {
            @Override
            public String getName() {
                return "parent";
            }
        });
    }
}

4.若匿名内部类需要访问外部类的局部变量,则需要使用final修饰外部类的局部变量,否则会报错

5.匿名内部类中不能存在任何的静态成员变量和静态方法

4.使用内部类

4.1 在外部类内部使用内部类

1.在外部类里使用内部类,和平常使用普通类方式一样

2.不要在外部类的静态成员(比如静态方法或静态代码块)中使用非静态内部类(静态成员不能访问非静态成员)

public class OutClass6 {

   static class InClass{
       private String name = "内部类";
       void print(){
           System.out.println("name = " + name);
       }
    }

    public static void main(String[] args) {
        //在外部类里使用,无需通过外部类.内部类这种,直接就可以像普通类的操作那样直接用就行了
        InClass inClass = new InClass();
        inClass.print();
    }
}

4.2 在外部类以外使用非静态内部类

1.若希望外部类以外的地方访问内部类,则内部类不能使用private修饰

  1. 省略修饰控制符的内部类,只能被与外部类同属于一个包的其他类所访问
  2. 使用protected修饰的内部类,只能被同一个包或者子类所访问
  3. 使用public修饰的内部类,可以被任何地方的其他类访问

2.因为非静态内部类的对象必须寄存于外部类的对象中,所以创建非静态内部类对象时,必须先创建其外部类的对象,即非静态内部类的构造器必须通过其外部类对象来调用

public class OutClass3 {

    private static String o2 = "外部类静态变量o2";

    class InClass{
        private String o2 = "内部类静态变量o2";
    }
    public static void main(String[] args) {
        OutClass3.InClass in = new OutClass3().new InClass();
        //o2之所以能访问,是因为private在同一个内里是可以互相访问的,但若是在其他类中,则不能访问
        System.out.println(in.o2);
		/*
		上面代码可改为如下三行代码:
		使用OutterClass.InnerClass的形式定义内部类变量
		Out.In in;
		创建外部类实例,非静态内部类实例将寄存在该实例中
		Out out = new Out();
		通过外部类实例和new来调用内部类构造器创建非静态内部类实例
		in = out.new In("测试信息");
		*/
    }

}

4.3 在外部类以外使用静态内部类

1.因为静态内部类是外部类类相关的,因此创建内部类对象时无需创建外部类的对象

public class OutClass4 {

    private static String o2 = "外部类静态变量o2";

   static class InClass{
        // 定义一个静态内部类,不使用访问控制符,
        // 即同一个包中其他类可访问该内部类
        public InClass()
        {
            System.out.println("静态内部类的构造器");
        }
    }
    public static void main(String[] args) {
        OutClass4.InClass in = new OutClass4.InClass();
		/*
		上面代码可改为如下两行代码:
		使用OutterClass.InnerClass的形式定义内部类变量
		StaticOut.StaticIn in;
		通过new来调用内部类构造器创建静态内部类实例
		in = new StaticOut.StaticIn();
		*/
    }

}

静态类

参考:
java内部类作用
java内部类深入详解 内部类的分类 特点 定义方式 使用
java 内部类的好处和缺点(下)
java内部类作用
详解 Java 内部类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值