[Java]内部类

内部类(innerclasses)

内部类的定义

在一般情况下,我们将类定义为一个独立的单元,而在有些情况下,我们会将一个类定义在另一个类的内部,这样的类就成为内部类

内部类一般分为四种:成员内部类、局部内部类、匿名内部类、静态内部类


成员内部类

  • 成员内部类可以简单理解为成外部类的一个属性
  • 因此它可以访问该类的所有属性或方法,尽管它们的权限级别高(private)
  • 实例化成员内部类时显然需要通过外部类的帮助
  • 内部类同样可以拥有自己的属性和方法
  • 当内部类的某一属性和外部类的某一属性同名时,在访问时由于就近原则,为内部类的属性
  • 若在上条情况下想要调用外部类的同名属性,应该如此访问:外部类名.this.属性名

例如:

class Hello{
    //如何实例化内部类
    
    //方法一
    OutClass outClass = new OutClass();
    OutClass.InClass inClass1 = outClass.new InClass();
    //先创建外部类的对象,再通过该对象new内部类的对象
    
    //方法二
    OutClass.InClass inClass2 = new OutClass().new InClass();
    //思路与方法一一致,但缩略了为外部类对象命名的过程
}

class outClass{
    public int outNum1;
    private int outNnum2;
    public int num;
    
    public void outFunc(){
        System.out.println("outClass.outFunc");
    }
    
    class inClass{
        public int num;
        
        public void inFunc1(){
            System.out.println(outNum1 + "--" + outNum2);
            //可以成功访问
        }
        
        public void inFunc2(){
            System.out.println(num);
            //输出值为inClass的num
            
            System.out.println(this.num);
            //因为当前对象为inClass,所以输出值仍为inClass的num
            
            System.out.println(outClass.this.num);
            //可通过该方法调用外部类的同名属性
        }
    }
}

局部内部类

  • 局部内部类定义在外部类的一个方法中
  • 因此局部内部类的作用域仅在该方法中,即只能在该方法体中实例化该类
  • 局部内部类可以访问外部类的全部属性和方法
  • 局部内部类可以拥有自己的属性和方法
  • 当局部内部类有和外部类同名的属性时,其情况和访问方法与成员内部类一致
  • 当局部内部类访问了该方法中的一个变量,则默认该变量为静态变量(final),所以该变量只能赋值一次
  • 上条的原因为:可能会存在该方法执行完毕,而该类仍在访问该方法的变量的情况(多线程)

例如:

class Hello{
    public int num;
    private int helloNum;
    
    public void func(){
        int funcNum = 1;  //默认该变量被final修饰,所以i的值不能再修改
        
        class funcClass{
            public int num;
            
            public funcClassFunc(){
                System.out.println(helloNum);
                //可以成功访问
                
                System.out.println(num + "--" + this.num);
                //两个都为funcClass的num
                
                System.out.println(Hello.this.num);
                //为Hello的num
                
                System.out.println(i);
                //可以访问外部方法中的变量
                //但为了避免外部方法执行完毕而该类仍在执行的情况,
                //所以默认该变量为静态变量
            }
        }
    }
}

静态内部类

  • 静态内部类就是在成员内部类的基础上增加了static修饰词
  • 静态内部类只能访问外部类的静态属性和静态方法
  • 静态内部类直接隶属于外部类,因此可通过外部类直接创建对象而不必先创建外部类的对象

例如:

class Hello{
	public static void main(String[] args){
        
        OutClass.InClass inClass = new OutClass.InClass();
        //跳过创建外部类对象,直接通过外部类创建内部类对象
    }
}

class OutClass{
    public int num1;
    public static int num2;
    
    static class InClass{
        public void func(){
            // System.out.println(num1);
            // 静态内部类只能访问外部类的静态属性,故错误
        	System.out.println(num2);  //输出num2
        }
    }
}

匿名内部类

  • 一些情况下,某个类以及它的对象只使用一次,则可以将类的定义和对象的创建一起完成,这样没有名字的类就叫做匿名内部类
  • 由于匿名内部类没有名字,所有类体中不能定义构造方法
  • 匿名内部类通常用于创建一个接口或一个抽象类的对象(因为接口和抽象类无法实例化对象)
  • 匿名内部类只能继承一个类或实现一个接口,不能继承一个类的同时实现一个接口,也不能同时实现两个或以上的接口
  • 匿名内部类继承一个内或实现一个接口时不需要extendsimplements关键字

例如:

class Hello{
    public static void main(String[] args){
        
        AbsClass absClass = new AbsClass(){  
            //必须重写所继承抽象类的抽象方法
            public void absFunc(){
                System.out.println("继承抽象类")}
        }//该花括号内则为匿名内部类的类体
    
        InterFace inter = new InterFace(){
        	//必须重写所实现接口的方法
            public void interFunc(){
                System.out.println("实现接口");
            }
        }
        
    }
}

abstract class AbsClass{
    public abstract void absFunc();
}

interface InterFace{
    void interFunc();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值