本文关键词:
java内部类 内部类的分类 特点 定义方式 使用 外部类调用内部类 多层嵌套内部类 内部类访问外部类属性 接口中的内部类 内部类的继承 内部类的覆盖 局部内部类 成员内部类 静态内部类 匿名内部类
内部类定义
将一个类定义放到另一个类的内部,这就是内部类
内部类与组合是完全不同的概念
内部类指的是类的定义在内部
看起来像一种代码隐藏机制
但是,远不止于此,因为他了解外部类 并且能够通信
内部类的代码,可以操作创建它的外部类的对象
所以可以认为内部类提供了某种进入其外部类的窗口
内部类特点
内部类访问外部类不需要任何特殊条件,拥有外部类所有的访问权
也就是对于内部类访问外部类的元素这件事情上
他就相当于是外部类本身一样随便访问
内部类的创建依赖外部类对象
可以直接访问外部类的变量
也可以直接指明
外部类类名.this.变量名
this通常是多余的,可以省略
内部类不仅能够访问包含他的外部类,还可以访问局部变量
但是局部变量必须被声明为final
因为局部内部类会将调用的变量进行拷贝,为了保证一致性,所以变量必须为final
内部类就是隐匿在外部类内部的一个独立的个体,不存在is a like a
内部类的对象必定秘密的捕获了一个指向外部类对象的引用
然后以此访问外部类的成员,编译器处理了所有的细节,对我们来说都是透明的
public class O { class I{ O get() { return O.this; } } public static void main(String[] args) { O outer = new O(); O.I inner = outer.new I(); System.out.println(outer == inner.get()); } }
打印结果为:
true
内部类持有的外部类对象就是外部类对象本身,内存地址是相同的
外部类的作用域之外,可以使用 outerClass.innerClass 方式引用内部类
可以对同一个包中其他类隐藏
内部类可以声明为私有的
每个类都会产生一个.class文件,包含了类的元信息
如果内部类是匿名的,编译器会简单的产生一个数字作为标识符形如 Outer$1.class
否则就是形如 外部类$内部类.class ,虚拟机看来与其他类无差,这也是编译器做的工作
普通的类(外部类)只能用public修饰符修饰,或者不写修饰符 使用默认的,但是内部类可以使用private 与protected
内部类可以达到类似"多重继承"的效果,
每个内部类都能独立的继承自一个(接口的)实现
无论外部类是否已经继承了某个(接口的)实现
也就是说 单个外部类,可以让多个内部类以不同的方式实现同一个接口或者继承同一个类
一个外部类可以创建多个内部类,这是不是就达到了类似"多重继承"的效果呢
内部类分类
成员内部类
局部内部类
匿名内部类
静态内部类
成员内部类
成员内部类也叫实例内部类。每一个外部类对象都需要一个内部类的实例,内部类离不开外部类存在
既然是成员内部类,和成员属性成员方法地位上自然没有什么不同
每个外部类对象都有一个内部类对象,自然持有外部类的引用
Outer outer = new Outer(); Outer.Inner inner = outer.new Inner();//注意是对象.new
局部内部类
局部内部类不能用public或者private或者protected访问说明符,作用域被限定在了声明这个局部内部类中了
很好理解,局部的就跟方法变量一样,限定在了{}之中,自然就不需要设置访问说明符了,而且你可以想下,也只有类以及类的成员有访问修饰符,局部变量有访问修饰符么
局部类可以对外面完全的隐藏起来,即使是外部类的其他的代码也不能访问他
局部内部类虽然被限定在局部代码块{} 里面,但是他也是可以访问外部类的属性的,不要被分类迷惑了
匿名内部类
匿名内部类就是局部内部类的进一步隐藏,局部内部类定义了之后在局部区域内仍旧可以创建多个对象
匿名内部类声明一个类之后就只能创建一个对象了,因为他并没有类名字
形式为:
new xxxClass (){ //或者new xxxInterface()//.......}
表示创建一个类的对象,这个类是xxxClass 子类或者实现了xxxInterface 接口的类
也可以说匿名内部类就是创建了一个匿名类的子类对象
构造方法名字和类名是相同的,匿名内部类显然是没有构造方法的,因为连名字都没有
既然没有构造方法想要构造参数,就只能把参数传递给外部的构造器,通过外部类的构造器绕一圈,本身内部类可以访问外部类所有的属性,去把值操作起来
当然外部类自然可以搞点属性根据业务逻辑单独给内部类用
如果是实现接口,不能带任何的参数的,因为接口都没有构造方法的呀
不过还可以通过初始化代码块达到类似的初始化效果,想必大家还记得初始化代码块是什么吧
不过也仅仅是达到类似的效果,而且,相当于只有一个"构造方法",因为即使你写了多个初始化代码块,还不是构造对象的时候一起执行嘛
构造了一个匿名内部类,内部类没有更新重写增加任何的方法 设置了一个初始化块 {} ,初始化块会在每个对象构造的时候执行 代码块中调用add方法增加对象 静态内部类 如果使用内部类只是为了将一个类隐藏到一个类的内部 并不需要内部类引用外部类的对象 可以将内部类声明为static,以便取消产生的引用 也只有内部类可以声明为static 静态内部类的对象除了没有对生成他的外部类的对象的引用特权外,其他的内部类一样 通过 外部类 . 内部类 来访问 刚才已经说了显然,静态内部类不会持有外部类的引用 静态的创建形式:
也就是:
fun(new ArrayList<String>(){
{
add("a");
add("b");
add("c");
}
}
);
Outer.Inner inner = new Outer.Inner();
共同學(xué)習(xí),寫(xiě)下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章
100積分直接送
付費(fèi)專(zhuān)欄免費(fèi)學(xué)
大額優(yōu)惠券免費(fèi)領(lǐng)