内部类

内部类的基本概念

  所谓的内部类也就是在一个类的内部进行其他类结构的嵌套操作。

为什么要使用内部类?

  这就要引用一句十分著名的一本书叫《Think in java》中的一句名言了——每个内部类都能独立的继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都是没有影响的。

  因为内部类拥着类的一些基本特征,所以在实际问题中我们会遇到一些接口无法解决或者难以解决的问题,此时我们可以使用内部类继承某个具体的或者抽象的类,间接解决类无法多继承引起的一系列问题。

内部类的优点

优点:

  • 内部类与外部类可以方便的访问彼此的私有域(包括私有方法和私有属性)
  • 内部类是另外一种封装,对外部的其他类隐藏(出了外围类,其他类不可访问)
  • 内部类可以实现java的单继承局限
  • 内部类可以使用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
  • 创建内部类对象的时刻并不依赖于外围对象的创建。

内部类的分类

从广义上讲,java内部类可以分成四大类:成员内部类,静态内部类,匿名内部类,局部内部类(方法内部类),一个一个来

成员内部类

  • 成员内部类可以无条件访问外部类所有成员属性和成员方法(包括private成员和static成员)
  • 成员内部类内部不允许任何ststic变量或者方法,正如方法中不能有任何的静态属性(成员对象与方法相关,静态属性和类有关),但可以定义常量。
  • 当成员内部类拥有和外部类同名的成员变量或者方法的时,默认情况下访问的是内部类的成员和方法,如果需要访问外部类的同名成员,需要以一下的形式进行访问
    • 外部类.this.成员变量
    • 外部类.this.成员方法
  • 在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过这个指向这个对象的引用来访问。
  • 成员内部类是依附外部类的,要创建成员内部类的对象,前提是必须存在一个外部类的对象。
    • 第一种方式:

      Outter outter = new Outter();
      Outter.Inner inner = outter.new Inner();
      //必须通过Outter对象来创建
    • 第二种方式:

      Outter.inner inner = outter.getinnerinstance();
  • 内部类可以拥有private访问权限、protected访问权限、public访问权限、默认访问权限以及包访问权限。如用private修饰,则只能在外部类的内部访问了。
 public class Outer {

     private int age = ;
String name = "Coco";
public class Inner{
String name = "Jayden";
public void show() {
System.out.println(Outer.this.name);
System.out.println(name);
System.out.println(age);
}
}
public Inner getInnerClass() {
return new Inner();
}
public static void main(String[] args) {
Outer o = new Outer();
Inner in = o.new Inner();
in.show();
}
}

运行之后的结果是:

需要提醒的是编译上面的程序后,会发现产生了两个class文件

静态内部类

  • 也是定义在另一个类里面的类,只不过在类前面加上一个static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,但可以通过 new 外部类().成员 的方式访问 。
  • 静态内部类与非静态内部类有些不同,没有保存指向创建它的外部类的引用。这就是说明:
    • 静态内部类的创建不需要依赖外部类可以直接创建,可以直接创建 内部类 对象名 = new 内部类();。
    • .静态内部类不可以使用任何外部类的非static类(包括属性和方法),但可以存在自己的成员变量。
  • 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
  • 如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
 public class Outer{
private int age = ;
static String name = "Coco";
public static class Inner{
String name = "Jayden";
public void show(){
System.out.println(Outer.name);
System.out.println(name);
}
}
public static void main(String[] args){
Inner i = new Inner();
i.show();
}
}

运行结果如下:

方法内部类(局部内部类)

  • 方法内部类不允许使用访问权限修饰符(public、private、protected)均不允许
  • 方法内部类对外部是完全隐藏的,除了创建这个类的方法可以访问外,其他地方均不能访问(其他方法或者类都不知道有这个类的存在)。
  • 方法内部类如果想要使用方法形参,该形参必须使用final声明(JDK8形参变为隐式final声明)
  • 无法创建静态信息
  • 可以直接访问方法内的局部变量和参数(有限制),但是不能更改
  • 可以随意的访问外部类的任何信息。
     public class Outer {
    
         // 属性和方法
    private int outerVariable = ;
    // 外部类定义的属性
    private int commonVariable = ;
    // 静态的信息
    private static int outerStaticVariable = ; // 成员外部方法
    public void outerMethod() {
    System.out.println("我是外部类的outerMethod方法");
    } // 静态外部方法
    public static void outerStaticMethod() {
    System.out.println("我是外部类的outerStaticMethod静态方法");
    } // 程序的入口
    public static void main(String[] args) {
    Outer outer = new Outer();
    outer.outerCreatMethod();
    } // 成员方法,内部定义局部内部类
    public void outerCreatMethod(int value) {
    // 女性
    boolean sex = false;
    // 局部内部类,类前不能有访问修饰符
    class Inner {
    private int innerVariable = ;
    private int commonVariable = ; // 局部内部类方法
    public void innerShow() {
    System.out.println("innerVariable:" + innerVariable);
    // 局部变量
    System.out.println("是否男性:" + sex);
    System.out.println("参数value:" + value);
    // 调用外部类的信息
    System.out.println("outerVariable:" + outerVariable);
    System.out.println("内部的commonVariable:" + commonVariable);
    System.out.println("外部的commonVariable:" + Outer.this.commonVariable);
    System.out.println("outerStaticVariable:" + outerStaticVariable);
    outerMethod();
    outerStaticMethod();
    }
    }
    // 局部内部类只能在方法内使用
    Inner inner = new Inner();
    inner.innerShow();
    }
    }

    运行后的结果是:

匿名内部类

  • 一般使用匿名内部类的方法来编写时间监听代码
  • 匿名内部类也是不能有访问修饰符和static修饰符的
  • 匿名内部类是唯一一种没有构造器的类
  • 是一种没有名字的方法内部类,因此特征和方法和方法内部类是一致的。
  • 匿名内部类必须继承一个抽象类或者一个借口

定义一个借口

public interface IAnimal {

    void speak();
}

匿名内部类的使用

 public class Outer {

     public static IAnimal getInnerInstance(String speak) {
return new IAnimal() {
@Override
public void speak() {
// TODO Auto-generated method stub
System.out.println(speak);
}};
}
public static void main(String[] args) {
Outer.getInnerInstance("小猫喵喵喵").speak();
}
}

内部类与外部类的关系

  • 对于非静态的内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的。
  • 内部类可以直接访问外部类的元素(包括私有域)—外部类在内部类之前创建,创建内部类时会将外部类的对象传入
  • 外部类可以通过内部类的引用间接访问内部类元素 – -要想访问内部类属性,必须先创建内部类对象
  • 内部类是一个相对独立的个体,与外部类没有关系。

内部类的运行原理

。。饿了。。吃饭先。。

Java内部类的基本解析的更多相关文章

  1. 【转】Java 内部类种类及使用解析

    Java 内部类种类及使用解析 内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Ja ...

  2. 【转】Java HashMap 源码解析(好文章)

    ­ .fluid-width-video-wrapper { width: 100%; position: relative; padding: 0; } .fluid-width-video-wra ...

  3. Java中的Html解析:使用jsoup

    包:jsoup-1.10.2.jar import java.io.File; import java.io.IOException; import org.jsoup.Jsoup; import o ...

  4. Java内部类final语义实现

    本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...

  5. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  6. 转:在java中使用dom4j解析xml

    JAVA 使用Dom4j 解析XML Java DOM4J Parser - Parse XML Document Dom4j下载及使用Dom4j读写XML简介 在java中使用dom4j解析xml ...

  7. 黑马----JAVA内部类

    黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...

  8. java 内部类 *** 最爱那水货

    注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...

  9. java内部类和匿名内部类

    内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...

随机推荐

  1. 8086 IO读写操作

    如图所示,通过8086来读写io口,实现流水灯以及开关.本电路是基于8086最小模式下的三总线结构添加的,三总线结构原理较为复杂本篇就不对其原理进行介绍了,大家可以自行查阅相关引脚的功能从而实现. 本 ...

  2. bzoj2431 || 洛谷P1521 求逆序对

    考虑一下插⼊法 n<=100n<=100n<=100 f[i][j]f[i][j]f[i][j]表⽰111~iii的全排列有j个逆序对的⽅案数 f[i][j]=Σf[i−1][j−k ...

  3. Excel催化剂开源第40波-Excel插入图片做到极致的效果

    不知道是开发人员的自我要求不高还是用户的使用宽容度足够大,在众多Excel插入图片的版本中,都没有考虑到许多的可大幅度提升用户体验的细节处理. Excel催化剂虽然开发水平有限,但也在有限的能力下,尽 ...

  4. DataNode的工作机制

    DataNode的工作机制 一个数据块在DataNode以文件的形式在磁盘上保存,分为两个文件,一个是数据本身, 一个是元数据信息(包括数据的长度,校验和,时间戳) 1.DataNode启动后,向Na ...

  5. [leetcode] 8. String to Integer (atoi) (Medium)

    实现字符串转整形数字 遵循几个规则: 1. 函数首先丢弃尽可能多的空格字符,直到找到第一个非空格字符. 2. 此时取初始加号或减号. 3. 后面跟着尽可能多的数字,并将它们解释为一个数值. 4. 字符 ...

  6. k8s1.9.0安装--环境准备

    一.预先准备环境 1. 准备服务器 这里准备了三台centos虚拟机,每台一核cpu和2G内存,配置好root账户,并安装好了docker,后续的所有操作都是使用root账户.虚拟机具体信息如下表: ...

  7. LinkedList实现类

    List还有一个LinkedList的实现,它是一个基于链表实现的List类,对于顺序访问集合中的元素进行了优化,特别是当插入.删除元素时速度非常快.因为LinkedList即实现了List接口,也实 ...

  8. Java初中级程序员面试题宝典

    Java基础部分 &与&&区别? &和&&都是逻辑运算符,都是判断两边同时真则为真,否则为假:但是&&当第一个条件不成之后,后面的条件都 ...

  9. TCP传输协议如何进行拥塞控制?

    拥塞控制 拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象.这种现象跟公路网中 ...

  10. 【JDK】JDK源码分析-Collection

    Java 集合框架(Java Collections Framework, JCF)包含很多平时开发中的常用类,例如 List.Set.ArrayList.HashMap.HashSet 等,因此打算 ...