李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
嵌套类
Leefs
2019-11-22 PM
4298℃
2条
# 嵌套类 ### 前言 今天,小编给大家带来《Java编程思想》第10.7小节,嵌套类 ### 一、概念 如果不需要内部类对象与外围类对象之间有联系,那么可以将内部类声明为static。 这通常称为嵌套类。**普通的内部类对象隐式地保存了一个引用,指向创建它的外围类对象**。然而,当内部类是static的时候,就不是这样了。 > 1. 1.要创建嵌套类对象,并不需要外围类对象。 > 2. 2.不能从嵌套类的对象中访问非静态的外围类对象。 原文粘贴到这小编得暂停一下,对这个**引用**做一些说明: 小编有如下几个问题: 问题1:在内部类中是如何调用外部类中的变量的? 问题2:外部类中的变量和内部类中的变量是否可以重名,如果可以,又是怎样来区分的? 问题3:外部类该如何调用内部类中的变量? 一言不合就上代码: ```jvaa public class InterfaceTest01 { int i = 1;//重名变量测试 int m = 9; public void outershow(){//外部类方法 inner inn = new inner();//创建内部类对象调用内部类变量 n System.out.println("n-->inner="+inn.n); } public class inner{ int i = 20;//重名变量测试 int n = 30; public void innershow(){ System.out.println("i-->InterfaceTest01="+InterfaceTest01.this.i);//调用外部类同名变量i System.out.println("i-->inner="+i);//调用自身变量i System.out.println("m-->InterfaceTest01="+m);//直接调用外部类变量m } } public static void main(String[] args) { InterfaceTest01 inter = new InterfaceTest01(); InterfaceTest01.inner in = inter.new inner(); inter.outershow(); in.innershow(); } } ``` > 运行结果 ```java n-->inner=30 i-->InterfaceTest01=1 i-->inner=20 m-->InterfaceTest01=9 ``` 上方代码中很好的对上面的三个问题进行了解释。 1. 1.内部类中可以直接使用外部类的变量,包括经过private修饰的私有变量,通过`直接使用变量名`或者`this.变量名`都可以完成对变量的调用 2. 2.内部类和外部类是可以重名的,如果在内部类中调用与自身同名的外部类变量可以使用`外部类名称.this.变量名`完成调用 3. 3.外部类想要调用内部类中的变量必须要通过创建内部类对象来完成。 > 总结 > > 1. 1.在内部类中之所以能直接调用外部类的方法,是因为在内部类中隐藏了:外部类名.this > 2. 2.在外部类中调用内部类的成员时必须要创建内部类的对象,因为没有:内部类.this 不知道讲到这里大家对**引用**这个概念是否理解,同时大家可以参考小编之前的文章[使用.this与.new](https://lilinchao.com/archives/120.html)来进行更好的理解。 继续往下进行........... 嵌套类与普通的内部类还有一个区别。普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含所有这些东西: ```java public class Parcel11 { private static class ParcelContents implements Contents{ private int i = 11; @Override public int value() { return i; } } protected static class ParcelDestination implements Destination{ private String label; private ParcelDestination(String whereTo){ label = whereTo; } @Override public String readLabel() { return label; } public static void f(){} static int x = 10; static class AnotherLevel{ public static void f(){} static int x = 10; } } public static Destination destination(String s){ return new ParcelDestination(s); } public static Contents contents(){ return new ParcelContents(); } public static void main(String[] args) { Contents c = contents(); Destination d = destination("Tasmania"); System.out.println(c.value()); System.out.println(d.readLabel()); } } ``` > 运行结果 ```java 11 Tasmania ``` > 代码分析 1. 1.在`Parcel11`类中有两个静态内部类`ParcelContents`和`ParcelDestination`,同时有两个静态方法`destination()`和`contents()`. 2. 2.静态方法`destination()`和`contents()`返回两个静态内部类的对象 3. 3.在主函数中对两个静态方法分别进行调用和执行打印 在main()中,没有任何Parcel11的对象是必需的;而是使用选取static成员的普通语法来调用方法--这些方法返回对Contents和Destination的引用。 **总结** 就像你在本章前面看到的那样,在一个普通的(非static)内部类中,通过一个特殊的this引用可以链接到其外围类对象。嵌套类就没有这个特殊的this引用,这使得它类似于一个static方法。 ### 二、接口内部的类 正常情况下,不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分。你放到接口中的任何类都自动地是public和static的。因为类是static的,只是将嵌套类置于接口的命名空间内,这并不违反接口的规则。甚至 可以在内部类中实现其外围接口。就像下面这样: ```java public interface ClassInInterface { void howdy(); class Test implements ClassInInterface{ @Override public void howdy() { System.out.println("Howdy!"); } public static void main(String[] args) { new Test().howdy(); } } } ``` > 运行结果 ```java Howdy! ``` 如果你想要创建某些公共代码,使得它们可以被某个接口的所有不同实现所共用,那么使用接口内部的嵌套类会显得很方便。 在每个类中都写一个main()方法,用来测试这个类,这样做有一个缺点,那就是必须带着那些已编译过的额外代码。如果这对你是个麻烦,那就可以使用嵌套类来放置测试代码。 ```java public class TestBed { public void f(){ System.out.println("f()"); } public static class Tester{ public static void main(String[] args) { TestBed t = new TestBed(); t.f(); } } } ``` > 运行结果 ```java f() ``` 这生成一个独立的类`TestBed$Tester`(要运行这个程序,执行java`TestBed$Tester`即可,在Unix/Linux系统中必须转义\$ )。可以使用这个类来做测试,但是不必在发布的产品包含它,在将产品打包前可以简单地删除`TestBed$Tester.class`。 ### 三、从多层嵌套类中访问外部类的成员 一个内部类被嵌套多少层并不重要 -- 它能透明地访问所有它所嵌入的外围类的所有成员,如下所示: ```java class MNA{ private void f(){} class A{ private void g(){} public class B{ void h(){ g(); f(); } } } } public class MultiNestingAccess { public static void main(String[] args) { MNA mna = new MNA(); MNA.A mnaa = mna.new A(); MNA.A.B mnaab = mnaa.new B(); mnaab.h(); } } ``` 可以看到在MNA.A.B中,调用方法g()和f()不需要任何条件(即使它们被定义为private),这个例子同时展示了如何从不同的类里创建多层嵌套的内部类对象的基本语法。“.new”语法能产生正确的作用域,所以不必在调用构造器时限定类名。 由于小编要赶进度,想在本周结束前将内部类这一章给更新完,下周开始下一章的内容,所以将两篇的内容量压缩到了一篇,本篇的代码也相对比较简单,希望给大家在学习上带来一些帮助。
标签:
Java
,
Java编程思想
,
JavaSE
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/215.html
上一篇
Java匿名内部类(三)--再仿工厂方法
下一篇
为什么需要内部类
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
JavaScript
算法
Shiro
Hive
Linux
机器学习
pytorch
工具
Http
ClickHouse
Hbase
微服务
序列化和反序列化
Elastisearch
Livy
字符串
Python
ajax
Golang
Java阻塞队列
FastDFS
HDFS
数据结构和算法
人工智能
MyBatis-Plus
MySQL
Elasticsearch
Java编程思想
Typora
Nacos
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭