Java基础教程:内部类

Java基础教程:内部类

内部类

  内部类,是指在一个类的内部定义的类。就像下面这样:

public class EnclosingClass {
  . . .
  public class NestedClass {
  . . .
 
  }
}

  内部类拥有访问外部类所有元素(包括private、static)的访问权。当某个外部类的对象创建了一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用。然后,在你访问此外围类的成员时,就是用那个引用来选择外围类的成员。

  内部类是个编译时的概念,一旦编译成功后,它就与外围类属于两个完全不同的类(当然他们之间还是有联系的)。对于一个名为OuterClass的外围类和一个名为InnerClass的内部类,在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$InnerClass.class。

  

使用.this和.new

  如果你需要在内部类中生成对外部类对象的引用,可以在外部类的名字后面紧跟圆点和this。

public class EnclosingClass {

    public class NestedClass {
        EnclosingClass getOuterClass(){
            return EnclosingClass.this;
        }
    }

}

  如果我们需要创建某个内部类对象,必须要利用外部类的对象通过.new来创建内部类

public class EnclosingClass {

    public class NestedClass {
        EnclosingClass getOuterClass(){
            return EnclosingClass.this;
        }
    }

    public static void main(String[] args) {
        EnclosingClass outerClass = new EnclosingClass();
        EnclosingClass.NestedClass innerClass = outerClass.new NestedClass();
    }
}

局部内部类

  局部内部类指的是在方法、构造器、初始化块中声明的类,在结构上类似一个局部变量。因此局部内部类时不能使用访问修饰符的。

public class OuterClass {
    static int a = 10;
    int b =10;
    //静态域中的局部内部类
    static {
        class LocalClass1{
            int val = a; //定义在静态环境中的内部类,只能访问外部类的静态成员
        }
    }
    //实例初始化块中的局部内部类
    {
        class LocalClass2{
            int val = a; //定义在实例环境中的内部类,可以访问外部类的所有成员
            int num = b;
        }
    }
    //构造器中的局部内部类
    public OuterClass(){
        class LocalClass3{ }
    }
    //方法中的局部内部类
    public void test(){
        class LocalClass4{}
    }
}

匿名内部类

  匿名内部类与局部内部类很相似,只不过匿名内部类是一个没有给定名字的内部类,在创建这个匿名内部类后,便会立即用来创建并返回此内部类的一个对象引用。

  匿名内部类只能继承一个类或实现一个接口,不能再继承其他类或其他接口。只能用于创建一次对象实例。

class MyOuterClass {
    private int x = 5;
    void createThread() {
        final int a = 10;
        int b = 189;
        // 匿名内部类继承Thread类,并重写Run方法
        Thread thread = new Thread("thread-1") {
            int c = x;  //访问成员变量
            int d = a;  //final的局部变量
            int e = b; //访问没有用final修饰的局部变量
            @Override
            public void run() {
                System.out.println("这是线程thread-1");
            }
        };
        // 匿名内部类实现Runnable接口
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程运行中");
            }
        };
    }
}

嵌套类

  如果不需要内部类对象与其外围类对象之间有联系,可以将内部类声明为static。这通常称为嵌套类。普通的内部类对象隐式地保存了一个引用,指向创建它的外围类对象。嵌套类因为是static,所以不依赖于外围类对象实例而独立存在,嵌套类的可以访问外围类中的所有静态成员,包括private的静态成员,但是它不能使用任何外围类的非static成员变量和方法

public class EnclosingClass {
    private static Integer num = 10;
    private Integer num1 = 20;

    static class staticClass{
        public void test(){
            System.out.println(num); //OK
            System.out.println(num1); //ERROR
        }
    }
  public static void main(String[] args) {
     EnclosingClass.StaticClass staticClass = new EnclosingClass.StaticClass();
  }
}

  同时,嵌套类是所有内部类中独立性最高的,其创建对象、继承(实现接口)、扩展子类等方式与外部类没有多大区别。

参考链接

原文地址:https://www.cnblogs.com/MrSaver/p/11113183.html

时间: 2024-10-12 13:11:40

Java基础教程:内部类的相关文章

Java基础教程 - 组合

1. 什么是组合? 如果一个类的对象和另一个类满足"has-a"关系的话,我们就可以在一个类中,把另一个类的对象作为其对象成员. 什么是"has-a"关系,举个例子:现在有一个类LapTop.class,还有一个是Moniter.class.好显然,Laptop "has-a" Moniter,也就是说,他们是满足"has-a"关系的.这时候,我们就可以把Moniter作为Laptop的一个数据成员. class Laptop

Java基础教程:面向对象编程

Java基础教程:面向对象编程 Java语言概述 Java语言特点 1.Java为纯面向对象的语言,它能够直接反映现实生活中的对象.总之,Everything is object! 2.平台无关性.Java为解释型语言,编译器会把Java代码变成"""中间代码",然后在JVM上解释执行. 3.Java提供了很多内置的类库,这些类库简化了开发人员的程序设计工作,同时缩短了项目开发时间. 4.Java语言提供了对Web应用的支持. 5.Java语言提供了较好的安全性和健

Java基础教程:面向对象编程[2]

Java基础教程:面向对象编程[2] 三大特性 封装 封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法.封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问. 使用封装我们可以对成员变量进行更精确的控制,同时隐藏信息,实现细节等. 方法: public class Person{ private String name; private int age; ? public int getAge(){ return age;

Java基础教程:JDBC编程

Java基础教程:JDBC编程 快速开始 什么是JDBC JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC API 库包含下面提到的每个任务,都是与数据库相关的常用用法. 制作到数据库的连接. 创建 SQL 或 MySQL 语句. 执行 SQL 或 MySQL 查询数据库. 查看和修改所产生的记录. 从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以用 J

Java基础教程:HashTable与HashMap比较

Java基础教程:HashTable与HashMap比较 1.  关于HashMap的一些说法: a)  HashMap实际上是一个"链表散列"的数据结构,即数组和链表的结合体.HashMap的底层结构是一个数组,数组中的每一项是一条链表. b)  HashMap的实例有俩个参数影响其性能: "初始容量" 和 装填因子. c)  HashMap实现不同步,线程不安全.  HashTable线程安全 d)  HashMap中的key-value都是存储在Entry中的

Java基础教程:多线程基础(2)——线程间的通信

Java基础教程:多线程基础(2)--线程间的通信 使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控与监督. 线程间的通信 思维导图 等待中 等待/通知机制 不使用等待/通知机制 我们可以使用使用sleep()与 whle(true) 死循环来实现多个线程间的通信. 虽然两个线程实现了通信,但是线程B必须不断的通过while语句轮训机制来检测某一个条件,这样会浪费CPU资源. 如果轮询间隔较小,更浪费时间间隔.如果轮训

Java基础教程(25)--I/O流

??I/O流表示输入源或输出目标.流可以表示许多不同类型的源和目标,例如磁盘文件.设备.其他程序等. ??流支持许多不同类型的数据,包括字节.原始数据类型.字符和对象等.有些流只传递数据; 有些流则可以操纵和转换数据. ??无论各种流的内部是如何工作的,所有流都提供相同的简单模型:流是一系列数据.程序使用输入流从源头获取数据,一次一项: ??程序使用输出流将数据写入目的地,一次一项: ??在本文中,我们会看到流可以处理各种各样的数据,无论是基本数据还是复杂对象.先来几张IO流的全家福: ??In

Java基础教程:枚举类型

Java基础教程:枚举类型 枚举类型 枚举是将一具有类似特性的值归纳在一起的方法.比如,我们可以将周一到周日设计为一个枚举类型.彩虹的七种颜色设计为一个枚举类型. 常量实现枚举 我们通过定义常量的方式来实现,如下: Public static class RainbowColor { // 红橙黄绿青蓝紫七种颜色的常量定义 public static final int RED = 0; public static final int ORANGE = 1; public static fina

《Java基础教程完整版》电子版书正式发布,欢迎大家免费下载

截止目前,Java系列教程已更新完毕.内容覆盖了:JavaSE基本知识点.UML建模.单元测试等.希望对想学习Java语言的朋友能够提供帮助.在编写的过程中,难免会出现一些错误,希望大家能多多提些意见. 由于本书都是从笔者CSDN博客中摘抄过来的,基本没有经过什么正规的校验,所以难免会出现一些不对的地方.欢迎各位大牛对本书提出批评. 作者博客:http://blog.csdn.net/lhy_ycu 作者邮箱:[email protected] 笔者声明:该电子书由ITeye提供电子书DIY功能