java嵌套类型 无法隐藏外层类型_java内部类深入详解 内部类的分类 特点 定义方式 使用...

java内部类 内部类的分类 特点  定义方式 使用   外部类调用内部类 多层嵌套内部类  内部类访问外部类属性  接口中的内部类  内部类的继承  内部类的覆盖  局部内部类 成员内部类 静态内部类 匿名内部类

内部类定义

将一个类定义放到另一个类的内部,这就是内部类

内部类与组合是完全不同的概念

内部类指的是类的定义在内部

看起来像一种代码隐藏机制

但是,远不止于此,因为他了解外部类 并且能够通信

内部类的代码,可以操作创建它的外部类的对象

所以可以认为内部类提供了某种进入其外部类的窗口

内部类特点

内部类访问外部类不需要任何特殊条件,拥有外部类所有的访问权

也就是对于内部类访问外部类的元素这件事情上

他就相当于是外部类本身一样随便访问

内部类的创建依赖外部类对象

可以直接访问外部类的变量

也可以直接指明

外部类类名.this.变量名

this通常是多余的,可以省略

内部类不仅能够访问包含他的外部类,还可以访问局部变量

但是局部变量必须被声明为final

因为局部内部类会将调用的变量进行拷贝,为了保证一致性,所以变量必须为final

内部类就是隐匿在外部类内部的一个独立的个体,不存在is a  like a

内部类的对象必定秘密的捕获了一个指向外部类对象的引用

然后以此访问外部类的成员,编译器处理了所有的细节,对我们来说都是透明的

AAffA0nNPuCLAAAAAElFTkSuQmCCpublic class O {    

class I{

O get() {            return O.this;

}

}

public static void main(String[] args) {

O outer = new O();

O.I inner = outer.new I();

System.out.println(outer == inner.get());

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

打印结果为:true

内部类持有的外部类对象就是外部类对象本身,内存地址是相同的

外部类的作用域之外,可以使用  outerClass.innerClass  方式引用内部类

可以对同一个包中其他类隐藏

内部类可以声明为私有的

每个类都会产生一个.class文件,包含了类的元信息

如果内部类是匿名的,编译器会简单的产生一个数字作为标识符形如 Outer$1.class

否则就是形如  外部类$内部类.class   ,虚拟机看来与其他类无差,这也是编译器做的工作

普通的类(外部类)只能用public修饰符修饰,或者不写修饰符 使用默认的,但是内部类可以使用private 与protected

内部类可以达到类似"多重继承"的效果,

每个内部类都能独立的继承自一个(接口的)实现

无论外部类是否已经继承了某个(接口的)实现

也就是说 单个外部类,可以让多个内部类以不同的方式实现同一个接口或者继承同一个类

一个外部类可以创建多个内部类,这是不是就达到了类似"多重继承"的效果呢

内部类分类成员内部类

局部内部类

匿名内部类

静态内部类

成员内部类

成员内部类也叫实例内部类。每一个外部类对象都需要一个内部类的实例,内部类离不开外部类存在

既然是成员内部类,和成员属性成员方法地位上自然没有什么不同

每个外部类对象都有一个内部类对象,自然持有外部类的引用Outer outer = new Outer();

Outer.Inner inner = outer.new Inner();//注意是对象.new

局部内部类

局部内部类不能用public或者private或者protected访问说明符,作用域被限定在了声明这个局部内部类中了

很好理解,局部的就跟方法变量一样,限定在了{}之中,自然就不需要设置访问说明符了,而且你可以想下,也只有类以及类的成员有访问修饰符,局部变量有访问修饰符么

局部类可以对外面完全的隐藏起来,即使是外部类的其他的代码也不能访问他

局部内部类虽然被限定在局部代码块{} 里面,但是他也是可以访问外部类的属性的,不要被分类迷惑了

匿名内部类

匿名内部类就是局部内部类的进一步隐藏,局部内部类定义了之后在局部区域内仍旧可以创建多个对象

匿名内部类声明一个类之后就只能创建一个对象了,因为他并没有类名字

形式为:new xxxClass  (){    //或者new xxxInterface()//.......}

表示创建一个类的对象,这个类是xxxClass  子类或者实现了xxxInterface 接口的类

也可以说匿名内部类就是创建了一个匿名类的子类对象

构造方法名字和类名是相同的,匿名内部类显然是没有构造方法的,因为连名字都没有

既然没有构造方法想要构造参数,就只能把参数传递给外部的构造器,通过外部类的构造器绕一圈,本身内部类可以访问外部类所有的属性,去把值操作起来

当然外部类自然可以搞点属性根据业务逻辑单独给内部类用

如果是实现接口,不能带任何的参数的,因为接口都没有构造方法的呀

不过还可以通过初始化代码块达到类似的初始化效果,想必大家还记得初始化代码块是什么吧

不过也仅仅是达到类似的效果,而且,相当于只有一个"构造方法",因为即使你写了多个初始化代码块,还不是构造对象的时候一起执行嘛

小技巧,匿名内部类的参数传递fun(new ArrayList(){{add("a");add("b");add("c");}});也就是:

AAffA0nNPuCLAAAAAElFTkSuQmCCfun(new ArrayList(){    

{

add("a");

add("b");

add("c");

}

}

);

AAffA0nNPuCLAAAAAElFTkSuQmCC

构造了一个匿名内部类,内部类没有更新重写增加任何的方法

设置了一个初始化块  {}  ,初始化块会在每个对象构造的时候执行

代码块中调用add方法增加对象

静态内部类

如果使用内部类只是为了将一个类隐藏到一个类的内部

并不需要内部类引用外部类的对象

可以将内部类声明为static,以便取消产生的引用

也只有内部类可以声明为static

静态内部类的对象除了没有对生成他的外部类的对象的引用特权外,其他的内部类一样

通过  外部类 . 内部类   来访问

刚才已经说了显然,静态内部类不会持有外部类的引用

静态的创建形式:

Outer.Inner inner = new Outer.Inner();

内部类的继承

内部类的构造器必须连接到指向外部类对象的引用

但是在继承的时候

那个指向外部类对象的"隐匿的"引用必须被初始化

而在派生类中不再存在可连接的默认对象

所以你要解决这个问题,否则的话就会出错

说的就是要包含指向外部类的引用

必须是带参数的,而且参数类型是外部类 在这里面调用super

AAffA0nNPuCLAAAAAElFTkSuQmCCpublic class InnerInherit extends OutClass.Inner {

InnerInherit(OutClass out){

out.super();

}    public static void main(String[] args){

OutClass out = new OutClass();

InnerInherit ii = new InnerInherit(out);

}

}class OutClass {    class Inner{

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

可以看得到,虽然只是继承内部类

但是想要生成一个构造器,不仅仅是需要传递一个外部类的引用

必须在构造器中使用:

enclosingClassReference.super();

说白了就是,内部类的对象依赖外部类的对象

内部类的子类的对象,也仍旧是依赖外部类的对象的

内部类的加载时机

AAffA0nNPuCLAAAAAElFTkSuQmCCpackage test.b;public class Outer {

Outer(){

System.out.println("Outer构造方法");

}

{

System.out.println("Outer初始化代码块");

}     static{

System.out.println("Outer静态代码块");

}

class Inner{

Inner(){

System.out.println("Inner构造方法");

}

{

System.out.println("Inner初始化代码块");

}

}

public static void main(String[] args) {

Outer outer = new Outer();

System.out.println("----------");         //Outer.Inner inner = outer.new Inner();

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

打印结果:Outer静态代码块

Outer初始化代码块

Outer构造方法

----------

显然,内部类没有被初始化,放开注释

打印结果:Outer静态代码块

Outer初始化代码块

Outer构造方法

----------

Inner初始化代码块

Inner构造方法

所以可以说内部类是懒加载的 用到了才加载初始化

而且,可以创建多个内部类的实例Outer.Inner inner1 = outer.new Inner();

Outer.Inner inner2 = outer.new Inner();

Outer.Inner inner3 = outer.new Inner();

Outer.Inner inner4 = outer.new Inner();

这是可以的,完全没问题,每个实例有自己的状态信息,与外部类对象信息独立

内部类的覆盖情况

两个类之间的继承和他们各自的内部类没有关系,不存在覆盖的情况

两个类之间的继承关系  比如  B extends A  ,每个类中都有C这个内部类

他们两者中的C是没有什么关系的

示例:

类A  拥有内部类C 并且有一个C的对象,构造方法中初始化

类B继承A,并且B中也有一个内部类C

AAffA0nNPuCLAAAAAElFTkSuQmCCpublic class A {    private C c;

A(){

System.out.println("A  constructor");

c = new C();

}

protected class C{

C(){

System.out.println("A ....C  constructor");

}

}

public static void main(String[] args) {

}

}public class B extends A{

B(){

System.out.println("B  constructor");

}     class C{

C(){

System.out.println("B ....C  constructor");

}

}

public static void main(String[] args) {        new B();

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

创建类B new B();

打印信息:A  constructor

A ....C  constructor

B  constructor

创建B的对象,需要调用父类的构造方法

所以会打印A  constructor  然后构造方法中创建C对象,然后是A ....C  constructor   显然,这并不是B类中的C

所以说:

两个类之间的继承,不存在内部类被覆盖的情况

虽然B继承了A  A有C  B也有C

但是两个内部类是完全独立的两个实体

各自在各自的命名空间中

上面的例子中创建一个对象,有父类,调用父类的构造方法,父类的构造方法调用父类的C的构造方法,也找不到任何方法会要调用子类的C

主函数修改下:

AAffA0nNPuCLAAAAAElFTkSuQmCCpublic static void main(String[] args) {    //new B();

A a = new B();

System.out.println("#############");

B b = new B();

System.out.println("#############");

a.new C();

System.out.println("#############");

b.new C();

System.out.println("#############");

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

打印结果为:A  constructor

A ....C  constructor

B  constructor

#############

A  constructor

A ....C  constructor

B  constructor

#############

A ....C  constructor

#############

B ....C  constructor

#############

上面两段很正常,都是创建B对象,自然步骤一样

当创建a.new C(); 的时候使用的是A的C

当创建b.new C(); 的时候使用的是B的C

显然,

创建内部类对象时,到底是父类中的还是子类中的

是由:  .new 前面的类型决定的,也就是定义的类型,而不是实际指向的类型

多层嵌套的内部类

多层嵌套的内部类,他能透明的访问所有他所嵌入的外围类的所有成员

AAffA0nNPuCLAAAAAElFTkSuQmCCpublic class NestedClass {    private String NestedClassName = "NestedClass";     

public class NestedClass1{         private String NestedClass1Name = "NestedClass1";        public class NestedClass2{             private String NestedClass2Name = "NestedClass2";            public class NestedClass3{                 public void print() {

System.out.println("NestedClassName:   "+NestedClassName);

System.out.println("NestedClass1Name:   "+NestedClass1Name);

System.out.println("NestedClass1Name:   "+NestedClass2Name);

}

}

}

}     public static void main(String[] args) {

NestedClass nestedClass = new NestedClass();

NestedClass.NestedClass1 nestedClass1 = nestedClass.new NestedClass1();

NestedClass.NestedClass1.NestedClass2 nestedClass2 = nestedClass1.new NestedClass2();

NestedClass.NestedClass1.NestedClass2.NestedClass3 nestedClass3 = nestedClass2.new NestedClass3();

nestedClass3.print();

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

打印信息NestedClassName:   NestedClass

NestedClass1Name:   NestedClass1

NestedClass1Name:   NestedClass2

从代码中可以看的出来,多层内部类和一层内部类创建格式是一样的

外部类名.内部类名 对象名 = 外部类对象.new 内部类名();

这个外部类指的就是他的外部,如果他的外部仍旧是别人的内部类,那就依次往外找就好了

从打印信息可以看得出来,不管有几层,内部类,可以访问到他外面的所有的类的属性信息

接口中的内部类

一般情况下

接口中不允许放置任何代码,但是嵌套类可以作为接口的一部分

你放到接口中的任何类都自动的是public 和 是 static 的

因为类是static,只是将嵌套类置于接口的命名空间内,并不违反接口的规则

你甚至可以接口中的内部类实现外部接口

如果你想要创建某些公共代码,使得他们可以被某个接口的所有不同实现所共用

那么使用接口内部的嵌套类会显得很方便

示例:

AAffA0nNPuCLAAAAAElFTkSuQmCCpublic class Test {    public static void main(String[] args) {         // 接口中的内部类都是默认 public static 的

Fly bird = new Fly.DemoFly();

bird.fly();

Fly bigBird = new BigBird();

bigBird.fly();

}

}interface Fly {    public void fly();    class DemoFly implements Fly {

@Override         public void fly() {

System.out.println("一般的鸟都这么飞~");

}

}

}class BigBird implements Fly {

@Override     public void fly() {

System.out.println("大鸟都这么飞~");

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

打印信息:一般的鸟都这么飞~

大鸟都这么飞~

可以看得出来,直接通过内部类,接口的静态内部类,可以提供一个默认的实现

这就是提供了编程接口的同时,又提供了一个默认的实现,多给力

内部类中不能有静态属性以及静态方法以及静态代码块class A{

class B{        private static int a= 0;//IDE会提示报错的      }

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

非静态的内部类型,不能声明静态的filed 除非标记为常量,也就是用final声明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367691.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java.io.FileNotFoundException: generatorConfig.xml (系统找不到指定的文件。)

在使用MyBatis的逆向工程生成代码时,一直报错java.io.FileNotFoundException: generatorConfig.xml (系统找不到指定的文件。),如图 文件结构如下: 代码如下: import java.io.File; import java.util.ArrayList; import java.util…

java机器学习库_Amazon Deep Java Library——Java 机器学习工具箱

近年来,人们对机器学习的兴趣稳步增长。具体来说,现在,企业在各种各样的场景中使用机器学习进行图像识别。它在汽车工业、医疗保健、安全、零售、仓库、农场和农业的自动化产品跟踪、食品识别,甚至通过手机摄像头进行实时翻译等方…

阻抗计算

si9000也可以算 一般有点差异,板厂可以微调 加上滤油,实际阻抗会降低2-3欧 影响最大的是层厚 先选择最薄的芯板,注意差分线的阻抗匹配,间距越小,阻抗小, 转载于:https://www.cnblogs.com/IotI/p/8587277.h…

javascript mqtt 发布订阅消息

js client使用paho-mqtt&#xff0c;官网地址&#xff1a;http://www.eclipse.org/paho/&#xff0c;参考http://www.eclipse.org/paho/clients/js/官网给出例子Getting Started&#xff0c;写出下面简单的测试代码。 <!DOCTYPE html> <html> <head> <met…

用C++调用tensorflow在python下训练好的模型(centos7)

本文主要参考博客https://blog.csdn.net/luoyexuge/article/details/80399265 [1] bazel安装参考:https://blog.csdn.net/luoyi131420/article/details/78585989 [2] 首先介绍下自己的环境是centos7&#xff0c;tensorflow版本是1.7&#xff0c;python是3.6&#xff08;anacond…

ActiveMQ producer同步/异步发送消息

http://activemq.apache.org/async-sends.html producer发送消息有同步和异步两种模式&#xff0c;可以通过代码配置&#xff1a; ((ActiveMQConnection)connection).setUseAsyncSend(true); producer默认是异步发送消息。在没有开启事务的情况下&#xff0c;producer发送持久化…

示例介绍:JavaFX 8打印

我有一段时间没有写博客了&#xff0c;我想与其他人分享有关JavaFX的所有信息&#xff08;我的日常工作和家庭可能是借口&#xff09;。 对于那些是本博客的新手&#xff0c;我是JavaFX 2 Introduction by Example&#xff08;JIBE&#xff09;的作者&#xff0c; Java 7 Recip…

int64 java_为什么json 不能使用 int64类型

json 简介jsON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集 。 JSON采用完全独立于语言的文本格式&#xff0…

Spring MVC自定义验证注释

在上一教程中&#xff0c;我展示了如何使用注释来验证表单 。 这对于简单的验证非常有用&#xff0c;但是最终&#xff0c;您需要验证一些现成的注释中没有的自定义规则。 例如&#xff0c;如果您需要根据输入的出生日期来验证用户已超过21岁&#xff0c;或者可能需要验证用户的…

前期

转载于:https://www.cnblogs.com/joker157/p/8618091.html

0基础能学mysql数据库吗_mysql学习入门:零基础如何使用mysql创建数据库表?

零基础如何自学Mysql创建数据库&#xff0c;是Mysql学习者必经之路&#xff0c;Mysql是受欢迎的关系数据库管理系统,WEB应用方面MySQL是很好的RDBMS应用软件之一。如何使用Mysql创建数据库表&#xff0c;打开Mysql学习进阶大门&#xff0c;就是今天MYSQL学习教程丁光辉博客认为…

vue跨域解决及打包

打包之前需要修改如下配置文件&#xff1a; 配置文件一&#xff1a;build>>>utils.js (修改publicPath:"../../" , 这样写是处理打包后找不到静态文件&#xff08;图片路径失效&#xff09;的问题) 配置文件二&#xff1a;config>>>index.js(修改a…

Bootstrap中实现图片圆角效果

Bootstrap 对图片的支持。Bootstrap 提供了三个可对图片应用简单样式的 class&#xff1a; .img-rounded&#xff1a;添加 border-radius:6px 来获得图片圆角。.img-circle&#xff1a;添加 border-radius:500px 来让整个图片变成圆形。.img-thumbnail&#xff1a;添加一些内边…

Bootstrap中的条纹进度条使用案例

创建一个条纹的进度条的步骤如下&#xff1a;1.添加一个带有 class .progress 和 .progress-striped 的 <div>2.接着在上面的 <div> 内&#xff0c;添加一个带有 class .progress-bar 和 class progress-bar-* 的空的 <div>。其中&#xff0c;* 可以是succes…

LM拟合算法

一、 Levenberg-Marquardt算法 &#xff08;1&#xff09;ya*e.^(-b*x)形式拟合 clear all % 计算函数f的雅克比矩阵&#xff0c;是解析式 syms a b y x real; fa*exp(-b*x); Jsymjacobian(f,[a b]); % 拟合用数据。参见《数学试验》&#xff0c;p190&#xff0c;例2 % data_1…

java的前生今世_HBaseGC的前生今世-身世篇

网易视频云是网易倾力打造的一款基于云计算的分布式多媒体处理集群和专业音视频技术&#xff0c;提供稳定流畅、低时延、高并发的视频直播、录制、存储、转码及点播等音视频的PAAS服务&#xff0c;在线教育、远程医疗、娱乐秀网易视频云是网易倾力打造的一款基于云计算的分布式…

CapeDwarf – Java EE上的Google App Engine

我有很多爱好。 从早期的Java EE规范一路走来&#xff0c;并通过Java EE 7进行了“云”之旅&#xff0c;我很好奇看到新宣布的CapeDwarf项目有哪些库存&#xff0c;可以在内部引入Google的平台即服务&#xff0c;提供“ Google App Engine ” 。 到目前为止的故事 我确实使用了…

第二周读书笔记——《构建之法》

【对一些实例的看法】 “我写了二叉树的遍历算法实现&#xff0c;在这里&#xff0c;二叉树是数据结构&#xff0c;遍历的实现细节是算法。C程序就是结果。但是这个程序有什么实际用处呢&#xff1f;在Java和其他一些语言中&#xff0c;似乎没有指针&#xff0c;那我可以不必了…

java springmvc 数据库事务_事务的简单回顾_JavaEE框架(Maven+SpringMvc+Spring+MyBatis)全程实战教程_Java视频-51CTO学院...

SpringMVCSpring MVC属于SpringFrameWork的后续产品&#xff0c;已经融合在Spring Web Flow里面。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色&#xff0c;这种分离让它们更容易进行定制。SpringSpring是一个开源框架&#xff0c;Spring是于2003 年兴起的…

前端 ---jQuery的补充

15-jQuery补充 jquery内容补充 jquery除了咱们上面讲解的常用知识点之外&#xff0c;还有jquery 插件、jqueryUI知识点 jqueryUI 官网&#xff1a; https://jqueryui.com/ jqueryUI 中文网&#xff1a; http://www.jqueryui.org.cn/ jquery插件内容包含 官网demo&#xff1a; h…