美文网首页java基础
java面向对象三——内部类

java面向对象三——内部类

作者: LeoFranz | 来源:发表于2019-06-25 20:41 被阅读0次

内部类的定义和分类

使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。

  • 对于成员内部类,在外部创建内部类对象的标准格式为:
    Outer.Inner oi = new Outer().new Inner();

成员内部类可以理解为一种特殊成员,一般是不会直接暴露给外部使用的,需要用private保证封装性,然后在外部类中设置访问接口。

public void method() {
    if(condition) {
        Inner in = new Inner();
        in.function();
    }
}
  • 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
  • 内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
  • 内部类提供了更好的封装,除了该外围类,其他类都不能直接访问(即便是静态内部类,访问时也至少加上类名前缀)

非静态内部类实例创建时候必须依赖外部类的实例,其寄生在外部类实例中,所以非静态内部类会隐式地保存一个外部类的引用

一、非静态内部类
  • 非静态内部类不能包含静态成员,因为此类内部类相当于一个类的特殊成员,不会随着类加载而存在,需要随着对象的创建才能使用;而根据static的语义,其标识的内容是跟随类加载而存在,不需要对象的创建就能被访问。如果非静态内部类中存在静态成员,static声明和内部类依赖对象的属性就会产生冲突。
  • 可以无缝访问外部类成员,外部类如果想访问内部类需要创建对象(局部内部类无法在方法外被访问)

1.成员内部类

  • 成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。
  • 外部类访问内部类成员需要通过内部类实例实现
  • 内部类访问成员变量,当内外部类变量同名时候,需要用外部类.this和this作为限定来区分,内部类中访问同名成员时系统优先访问内部类中的成员

2、匿名内部类

  • 适合创建那种只需要一次使用的类,好处就是使用完后就可以当做垃圾回收,而且没有栈内变量指向它。
  • 不能定义构造器,因为没有类名。
  • 匿名内部类中如果有访问方法中的局部变量,就必须设置为final,因为局部变量在方法结束后就销毁,但局部内部类对象还在堆中等待垃圾回收(不够及时),仍然在引用那个变量,这样就会产生不可预料后果。所以我们需要将变量设置为final,使其在内部类对象中被存储为一个常量拷贝。这样即使变量被回收了,在内部类中也能使用。Java8 后取消了这个限制,但依然会隐式添加final。
  • 匿名内部类的语法同样可以运用到普通类中

3、局部内部类

  • 仅仅作用在方法中,其他程序单元不能访问局部内部类。
  • 不能加任何修饰符
  • 使用局部方法中的局部变量时候需要将该变量设置成final,原因同上。
二、静态内部类

它的创建是不需要依赖于外围类的。
它不能使用任何外围类的非static成员变量和方法,只能通过创建外部类对象可以访问。
接口内部类只能是静态内部类,默认使用了public static修饰符
标准访问格式为:
Outer.Inner inner = new Outer.Inner();
不能通过外部类对象进行访问或创建,我的理解是这样就表明外部类对象会被内部类对象引用。

总结区别

非静态内部类

  • 创建条件 需要基于外部类实例创建,会隐式包含外部类的引用(内存泄漏)
  • 内容特征 不能包含静态成员
  • 访问条件 可以访问外部类包括私有在内的所有成员,外部访问内部类需要创建对象调用
    静态内部类
  • 创建条件 不需要外部类实例创建,没有对外部类的引用
  • 内容特征 自身可以包含静态和非静态成员
  • 访问条件 不能使用外部类的非静态成员,外部类可以通过类名直接访问其中静态成员,也可以直接创建静态内部类对象进行访问。

使用内部类

1.在外部类中使用内部类
基本和使用普通类无差别,唯一注意的是不要在外部类的静态成员中直接调用非静态内部类,因为非静态内部类的调用首先要保证在外部类对象中创建实例

2.在外部类之外使用非静态内部类
必须在使用前创建外部类的实例,

OuterInstance.new InnerInstance()
或者
Out.In in = new Out().new In();

有个方法可以保证在创建非静态内部类时必定创建了外部类的实例

public class SubClass extends Out.In {
       public SubClass(Out out) {
              out.super();//通过传入out对象显示地调用in的构造器
}
}

3.在外部类以外使用静态内部类
Outer.StaticInner staticIn = new Outer.StaticInner();

相关文章

  • Java基础语法:面向对象概述

    Java面向对象学习的三条主线: 1. Java类及类的成员:属性,方法,构造器;代码块,内部类 2. 面向对象的...

  • 面向对象1

    java面向对象的3条主线 1.java类及类的成员、属性、方法、构造器、代码块、内部类2.面向对象三大特征:封装...

  • java面向对象笔记

    面向对象三要素 抽象 接口 面向对象(局部内部类访问局部变量的问题) 匿名内部类

  • 面向对象编程学习的主线

    学习面向对象内容的三条主线 1. Java 类及类的成员:属性、方法、构造器;代码块、内部类 2. 面向对象的三大...

  • java面向对象三——内部类

    内部类的定义和分类 使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经...

  • 面向对象总结

    面向对象思想 类与对象 定义类格式: 面向对象的三大特征 封装 继承 多态: 抽象类 接口 内部类 匿名内部类: ...

  • Java面向对象,权限修饰符,内部类

    day10笔记【Java面向对象,权限修饰符,内部类】 1_面向对象(package关键字的概述及作用)(了解) ...

  • java SE目录

    java SE目录 java基础(一)java基础(二)关键字面向对象(一)面向对象(二)面向对象(三)集合(一)...

  • Java&Android 基础知识梳理(0) - Jav

    Java 基础知识大纲 一、面向对象 二、Object类相关 三、重要关键字 四、内部类 五、抽象类 & 接口 六...

  • java总结

    Java是一门面向对象编程语言. java知识点梳理 java面向对象的特点java面向对象的三个基本特性: 封...

网友评论

    本文标题:java面向对象三——内部类

    本文链接:https://www.haomeiwen.com/subject/xfptcctx.html