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();
}
}
同时,嵌套类是所有内部类中独立性最高的,其创建对象、继承(实现接口)、扩展子类等方式与外部类没有多大区别。
参考链接
Java基础教程:内部类的更多相关文章
- Java基础教程——内部类
内部类 内部类(inner class)是定义在另一个类中的类 内部类的好处: |--1.隐藏机制:内部类封装性更好,隐藏在一个类之中,同一包中的其他类也不能访问 |--2.内部类可以访问外围类的私有 ...
- Java基础教程(12)--深入理解类
一.方法的返回值 当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...
- Java基础教程(18)--继承
一.继承的概念 继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- Java基础教程:网络编程
Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...
- Java基础教程(5)--变量
一.变量 1.变量的定义 正如上一篇教程<Java基础教程(4)--面向对象概念>中介绍的那样,对象将它的状态存在域中.但是你可能仍然有一些疑问,例如:命名一个域的规则和惯例是什么?除 ...
- Java基础教程:Lambda表达式
Java基础教程:Lambda表达式 本文部分内容引用自OneAPM:http://blog.oneapm.com/apm-tech/226.html 引入Lambda Java 是一流的面向对象语言 ...
- Java基础教程:泛型基础
Java基础教程:泛型基础 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚 ...
- Java基础教程:多线程基础(1)——基础操作
Java:多线程基础(1) 实现多线程的两种方式 1.继承Thread类 public class myThread extends Thread { /** * 继承Thread类,重写RUN方法. ...
随机推荐
- MySQL分区表 非分区索引 无法使用
在<高性能Mysql>这本书的‘如何使用分区’这一小章中,列举的常见问题中,有以下一个问题: 分区列和索引列不匹配 如果定义的索引列和分区列不匹配,会导致查询无法进行分区过滤.假设在列a上 ...
- IntelliJ IDEA 2017 MySQL5 绿色版 Spring 4 Mybatis 3 配置步骤详解(二)
前言 继续上一篇安装教程 首先是MySQL绿色版安装之后其他组件安装,如果篇幅较长会分为多篇深入讲解,随笔属于学习笔记诸多错误还望指出 共同学习. MySQL 5.7 绿色版 我本地安装的是 ...
- 模板 - 数学 - 数论 - Min_25筛
终于知道发明者的正确的名字了,是Min_25,这个筛法速度为亚线性的\(O(\frac{n^{\frac{3}{4}}}{\log x})\),用于求解具有下面性质的积性函数的前缀和: 在 \(p\) ...
- Java SpringBoot 实体类数据自动验证
package demo.dto; import org.hibernate.validator.constraints.Length; import javax.validation.constra ...
- js中的那些遍历
说到遍历,首先想到的是数组的遍历,方法不要太多,比如 for, forEach,map,filter,every,some等 下面来看下,用法 首先 定义一个数组: 1. for循环,需要知道数组的长 ...
- 深度学习面试题09:一维卷积(Full卷积、Same卷积、Valid卷积、带深度的一维卷积)
目录 一维Full卷积 一维Same卷积 一维Valid卷积 三种卷积类型的关系 具备深度的一维卷积 具备深度的张量与多个卷积核的卷积 参考资料 一维卷积通常有三种类型:full卷积.same卷积和v ...
- [转]重命名PostgreSQL数据库
初学PostgreSQL的朋友可能会有这样的疑惑:如何重命名已经建好的数据库?因为PostgreSQL默认的客户端pgAdmin III并没有地方可以让我们去修改某个现有的数据库的名称.遇到这个情况, ...
- PostgreSQL 增量备份详解以及相关示例
PostgreSQL 没有类似MySQL 的二进制日志, 但是有和MySQL 类似的REDO LOG,并且有MySQL 没有的REDO 归档功能.当然REDO 的归档已经MariaDB 和Percon ...
- HttpWebRequest Timeout
随着REST风格的流行,直接通过 HttpWebRequest 进行服务调用的客户端应用越来越多.这里总结一些可能需要费时调查的经验,希望能帮助大家. 1. 用完的HttpWebRequest要Abo ...
- 手写HashMap实践
1.什么是HashMap 2.源码分析 3.手写实现 4.不足 一.什么是HashMap hash散列 将一个任意长度通过某种算法(hash函数算法)换成一个固定值 map: 地图x,y 存储 总结: ...