内部类

内部类的基本概念

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

为什么要使用内部类?

  这就要引用一句十分著名的一本书叫《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. UVA514 铁轨 Rails:题解

    题目链接:https://www.luogu.org/problemnew/show/UVA514 分析: 入站序列是1-n,入站后判断如果等于出站序列的当前值,则直接出站.否则就在栈里待着不动.模拟 ...

  2. vue2.0 富文本组件(基于wangeditor)

    1. 本组件基于 wangeditor http://www.wangeditor.com/ 如有侵权 请告知, 2. 效果图 3. 依赖安装 package.json 中 devDependenci ...

  3. easypermissions的基本使用

    转载请注明出处 http://blog.csdn.net/pyfysf/article/details/78204395 Android 6.0(API 级别 23)开始,在应用运行时向其授予权限,而 ...

  4. 查询表格——建立动态表格,使用ajax输入查询条件将后台数据查询出来以表格的形式展示出来

    建立动态表格,使用ajax将前台查询条件传给后台,并将查询结果以表格的形式展示出来. 页面的展示效果如下图所示: 第一步:查询条件的部分: 代码如下: <div class="text ...

  5. [LeetCode] 6. ZigZag Conversion (Medium)

    原题链接 把字符串按照 ↓↗↓……的顺序,排列成一个 Z 形,返回 从左到右,按行读得的字符串. 思路: 建立一个二维数组来按行保存字符串. 按照 ↓↗↓……的方向进行对每一行加入字符. 太慢了这个解 ...

  6. MySql 命令(命令行)

    1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...

  7. Maven重新下载未下载完成的jar包

    使用maven下载jar包,经常会遇到下载失败的情况,如果失败的jar包过多,或是不清楚到底有那些jar包在下载过程中出现了问题.可通过maven命令重新批量下载未成功的jar包. 1,打开cmd , ...

  8. Codeforces Round #479 (Div. 3) D. Divide by three, multiply by two

    传送门 D. Divide by three, multiply by two •题意 给你一个数 x,有以下两种操作,x 可以任选其中一种操作得到数 y 1.如果x可以被3整除,y=x/3 2.y= ...

  9. VS Code 安装 LeetCode 插件

    练习算法绕不开的一个网站就是力扣,很多小伙伴为了拿到大厂 offer,刷题都刷到吐了. 然而如果直接在 LeetCode 上写代码,那是很痛苦的一件事,那就相当于用 txt 写代码一样,没有 IDE ...

  10. Android UI绘制流程及原理

    一.绘制流程源码路径 1.Activity加载ViewRootImpl ActivityThread.handleResumeActivity() --> WindowManagerImpl.a ...