javase 17 内部类

17 内部类

一般情况,我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类的内部定义,称为内部类。形式如下:内部类的修饰符: public , default

public class Outter{
    // 外部类
    class Inner{
        // 成员内部类 
    }
    public void test(){
        class Inner1{ 
            // 局部内部类
        } 
    } 
}

内部类的作用:

  1. 内部类可以很好的实现细节隐藏。 一般的非内部类,是不允许有 private 与 protected 权限的,但内部类可以。

  2. 内部类拥有外围类的所有元素的访问权限,利用这个特性可以实现java中的多继承

  3. 可以避免修改接口而实现同一个类中两种同名方法的调用

内部类的分类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名,内部类和静态内部类。

内部类的共性:
内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和符号 。内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的 。内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量。

成员内部类

​ 成员内部类可以访问外部类的所有成员变量和方法(无论静态、非静态、私有、非私有),自身没有静态成员。
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。

局部内部类

将内部类移到了外部类的方法中,然后在外部类的方法中再生成一个内部类对象去调用内部类方法。局部内部类和成员内部类的区别在于局部内部类的访问仅限于方法内。

在方法中定义和使用,不能被 public, protected, private 和 static 修饰(像局部变量一样) 只能访问方法中定义的 final 类型的局部变量(初始化之后便不能更改), final 可以不写,编译之后会变为final。只能在方法内部使用。

匿名内部类

定义类的最终目的是创建一个类的实例,但是如果某个类以及它的实例只是用一次,则可以将类的定义与类的创建,放到与一起完成,或者说在定义类的同时就创建一个类 , 以这种方法定义的没有名字的类成为匿名内部类。 用于只创建这个类的一个对象的场合(不必命名),通常是作为方法的参数,隐式地继承了一个父类或者实现了一个接口。或直接使用接口引用指向匿名子类对象。

①匿名内部类可以继承一个类或实现一个接口,这里的 ClassOrInterfaceName是匿名内部类所继承的类名或实现的接口名。但匿名内部类不能同时实现一个接口和继承一个类,也不能实现多个接口。如果实现了一个接口,该类是 Object 类的直接子类,匿名类继承一个类或实现一个接口,不需要 extends 和 implements关键字。
②由于匿名内部类没有名称,所以类体中不能定义构造方法,由于不知道类名也不能使用关键字来创建该类的实例。实际上匿名内部类的定义、构造、和第一次使用都发生在同样一个地方。此外,以下是一个表达式,返回的是一个对象的引用,所以可以直接使用或将其复制给一个对象变量,如:

TypeName obj=new Name(){
    /*此处为类体*/
}
//同样,也可以将构造的对象作为调用的参数。例:
someMethod(new Name(){ 
    /*此处为类体*/ 
});

局部内部类:像局部变量一样,不能被public, protected, private和static修饰。

静态内部类

当使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围对象,可以将内部类声明为 static 。如果用 static 将内部类静态化,那么内部类就只能访问外部类的静态成员变量,不能直接访问外部类的实例变量、实例方法,只有通过对象引用才能访问。其次,因为内部类被静态化,因此 Out.In 可以当做一个整体看,可以直接new 出内部类的对象(静态内部类不通过外部类实例进行创建对象)生成静态内部类对象的方式为:

Outter.Inner inner = new Outter.Inner();// 里面的类不用new
内部类的基本结构

内部类其实严重破坏了良好的代码结构,但为什么还要使用内部类呢?
因为内部类可以随意使用外部类的成员变量(包括private)而不用生成外部类的对象,这也是内部类的唯一优点。

内部类中的变量访问形式

内部类在没有同名成员变量和局部变量的情况下,内部类会直接访问外部类的成员变量;若有同名情况时,直接访问会导致内部类中的局部变量将外部类的成员变量覆盖,访问内部类本身的成员变量可用 this.属性名 ,访问外部类的成员变量需要使用 Out.this.属性名 。

创建内部类实例
Out.Inner inner=new Out().new Inner(); 
//或 
Out out=new Out() Out.Inner inner=out.new Inner();
成员内部类私有化

如果一个内部类只希望被外部类中的方法操作,那么可以使用 private 声明内部类,此时我们必须在 Out 类里面生成 In 类的对象进行操作,而无法再使用Out.In in = new Out().new In() 生成内部类的对象也就是说,此时的内部类只有外部类可控制;如同是,我的心脏只能由我的身体控制,其他人无法直接访问它。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值