内部类

内部类的基本概念

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

为什么要使用内部类?

  这就要引用一句十分著名的一本书叫《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. 浅谈ActiveMQ与使用

    一.什么是消息中间件 消息中间件顾名思义实现的就是在两个系统或两个客户端之间进行消息传送 二.什么是ActiveMQ ActiveMQ是一种开源的基于JMS(Java Message Servie)规 ...

  2. 图像识别sift+bow+svm

    本文概述 利用SIFT特征进行简单的花朵识别 SIFT算法的特点有: SIFT特征是图像的局部特征,其对旋转.尺度缩放.亮度变化保持不变性,对视角变化.仿射变换.噪声也保持一定程度的稳定性: SIFT ...

  3. python面向对象编程小程序- 选课系统

    选课系统 花了一晚上写的,可能还存在不足 1.程序框架 2.文件夹建立 D:/选课系统 |___api | |___common_api.py |___bil | |___common.py |___ ...

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

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

  5. linux中type 、file、stat三者的区别

    1.type 用来查看命令类型,以区别是内部命令还是外部命令 示例:[root@localhost ~]# type cd cd 是 shell 内嵌    [root@localhost ~]# t ...

  6. random,time,sys,os

    import random print(random.random()) #(0,1)大于0且小于1之间的小数 print(random.randint(1,3)) #大于等于1且小于等于3之间的整数 ...

  7. 入门训练-4. Fibonacci数列

    问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n ...

  8. C#加密解密(AES)

    using System; namespace Encrypt { public class AESHelper { /// <summary> /// 默认密钥-密钥的长度必须是32 / ...

  9. 洛谷 P3387 题解

    题面 裸跑一遍SPFA,统计每个点的入队次数: 如果该点的入队次数>=总点数,那么该点便是一个负环上的点: 重点!!!: 1.不是“YES”,是“YE5”: 2.不是“NO”,是“N0”:(是零 ...

  10. 【iOS】UIImage 等比率缩放

    这两天处理引导页面的时候遇到了图片略大的问题,上网查找后找到了解决方法.用的是 UIImage 的等比率缩放,虽然不难,但之前没接触过,故记之. 代码如下: - (UIImage *)scaleIma ...