Java关于内部类的学习_雨欲语的博客-程序员秘密

技术标签: Java学习  

内部类顾名思义就是指在类里面的类,内部类分为以下四种:

①成员内部类

②局部内部类

③匿名内部类

④静态内部类

问题来了,为什么要使用内部类呢?

每个内部类都能够独立地继承一个(接口的)实现,无论外围类是否已经继承(接口的)实现,对其都不影响。内部类能够十分好的解决多重继承的问题。创建内部类的对象的时候,并不依赖于外围类对象的创建,内部类就是一个独立的实体。内部类除了其的外围类,其它类都不能够访问它。

内部类可以很轻松地访问外围类的属性等,就算外围类属性等用的private修饰,这是因为在创建一个外围类的内部类的对象时,此时内部类对象会捕获指向外围类对象的引用,只要我们在访问外围类的属性等时,就会用这个引用来选择外围类的属性等。

内部类是个编译时的概念,只要编译成功,它就与其的外围类属于两个不同的类(还有一定的联系)。会生成两个.class文件。外围类.class和外围类$内部类.class。

一、成员内部类:

成员内部类是最普通的内部类,也就是在一个类里面定义一个类。成员内部类使用外围类的成员方法、成员变量等无条件限制,无论是用private修饰的还是static修饰的。

如果成员内部类的方法名或者成员变量同名,那么,会发生隐藏现象,要使用如下方法来访问:外围类.this.成员方法---外围类.this.成员变量。

内部类访问外围类的成员方法、变量无限制,但是外围类访问内部类的成员方法、变量却不能随心所欲了,但是值得注意的是:外围类访问成员内部类的方法,必须先创建一个成员内部类的对象,再通过这个对象来访问,成员内部类是依托外部类而存在的,如果要创建成员内部类的对象,前提是必须存在一个外围类的对象。

package com.qianfeng.innerClass;

import com.qianfeng.innerClass.MemberInnerClass.InnerClass;

/**
 * 成员内部类
 * @author littledyf
 *
 */
public class MemberInnerClass {
	private String a;
	//外围类的方法
	public void outMethod(){
		System.out.println("我是外部类的方法...");
	}
	//与内部类同名的外围类的方法
	public void method(){
		System.out.println("我是外部类的同名方法...");
	}
	//通过getxxxx来访问成员内部类
	public InnerClass getInnerClass(){
		return new InnerClass();
	}
	//成员内部类
	public class InnerClass{
		public void innerMethod(){
			//使用外围类的属性,无条件使用,不管是private还是static
			a = "我是内部类使用外围类的属性";
			System.out.println(a);
			//使用外围类的的方法
			outMethod();
			//使用外围类的同名方法要使用如下形式,因为同名,会发生隐藏现象
			MemberInnerClass.this.method();
			
		}
		//与外围类同名的成员内部类的方法
		public void method(){
			System.out.println("我是内部类的同名方法...");
		}
		
	}
}
package com.qianfeng.innerClass;

import org.junit.Test;

/*
 * 测试成员内部类
 */
public class MemberInnerClassTest {
	
	@Test
	public void t(){
		/**
		 * 外围类访问成员内部类的方法,必须先创建一个成员内部类的对象,再通过这个对象来访问
		 * 成员内部类是依托外部类而存在的,如果要创建成员内部类的对象,前提是必须存在一个外围类的对象
		 */
		//外围类访问成员内部类的第一种访问方式
		System.out.println("第一种方式访问...");
		MemberInnerClass mic1 = new MemberInnerClass();
		MemberInnerClass.InnerClass ic = mic1.new InnerClass();
		ic.innerMethod();
		ic.method();
		System.out.println("-----------分割线-----------");
		//外围类访问成员内部类的第二种访问方式
		System.out.println("第二种方式访问...");
		MemberInnerClass mic2 = new MemberInnerClass();
		MemberInnerClass.InnerClass ic1 = mic2.getInnerClass();
		ic1.innerMethod();
		ic1.method();
	}
}

 

二、局部内部类

 

局部内部类是定义在方法中的或者一个作用域里的内部类,局部内部类的访问仅限于方法内或者该作用域内。

局部内部类不能被public、private、static等修饰符修饰。

局部内部类访问作用域的局部变量,该局部变量需要用final修饰。

外部类不能访问局部内部类,只能在方法体中访问局部内部类,且访问必须在内部类定义之后,即创建局部内部类的对象只能在局部内部类的作用域里,且要在内部类定义之后。

局部内部类访问外部类中同名的方法或者变量时,如下:OutClass.this.method()----OutClass.this.变量。

package com.qianfeng.innerClass;
/**
 * 局部内部类
 * @author littledyf
 *
 */
public class PartInnerClass {
	//与局部内部类同名的变量s1
	private String s1 = "我是外部类与局部内部类同名的变量s1";
	//外部类变量s2
	private String s2 = "我是外部类用private修饰的变量s2";
	//与局部内部类同名的method1
	public void method1(){
		System.out.println("我是外部类的method1");
	}
	//与局部内部类同名的method2
	public void method2(){
		System.out.println("我是外部类的method2");
	}
	//有局部内部类的method3
	public void method3(){
		//方法中用final修饰的变量
		final String s3 = "我是局部类外部方法中用final修饰的变量s3";
		class InnerClass{
			private String s1 = "我是局部内部类中与外部类同名的变量s1";
			public void method1(){
				//局部内部类可以直接访问外部类的变量,即使是private和static
				System.out.println(s2);
				//局部内部类访问外部方法的变量需要有final修饰
				System.out.println(s3);
				//局部内部类和外部类有同名的变量和方法时
				System.out.println(s1);//实际就是this.s1
				System.out.println(PartInnerClass.this.s1);
				method2();
				PartInnerClass.this.method2();
			}
			public void method2(){
				System.out.println("我是局部内部类的method2");
			}
		}
		InnerClass ic = new InnerClass();
		ic.method1();
	}
}
package com.qianfeng.innerClass;

import org.junit.Test;

/**
 * 测试局部内部类
 * @author littledyf
 *
 */
public class PartInnerClassTest {
	@Test
	public void t(){
		PartInnerClass pic = new PartInnerClass();
		pic.method3();
	}
}

 

 三、匿名内部类

匿名内部类不能有访问修饰符和static修饰符的。匿名内部类也就是没有名字的内部类。因为没有名字,所以匿名内部类只能使用一次,通常用来简化代码编写。

匿名内部类是唯一一种没有构造器的类,因为没有构造器,所以其的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候,系统自动起名为OutClass$1.class。一般来说,匿名内部类用于继承其它类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或者重写。

匿名内部类不能定义任何静态成员、方法和类。因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。)一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。

package com.qianfeng.innerClass;
/**
 * 匿名内部类的使用
 * @author littledyf
 *
 */
public class AnonymityInnerClass {
	public void Method(){
		AnonymityInnerClassOther aico = new AnonymityInnerClassOther(){
			public void print(){
				System.out.println("我是匿名内部类");
			}
		};
		aico.print();
	}
	
}

package com.qianfeng.innerClass;
/**
 * 匿名内部类将通过重写其方法来获得实现
 * @author littledyf
 *
 */
public class AnonymityInnerClassOther {
	public void print(){
		System.out.println("我是已经存在的类,让匿名内部类来重写实现");
	}
}
package com.qianfeng.innerClass;

import org.junit.Test;

/**
 * 测试匿名内部类
 * @author littledyf
 *
 */
public class AnonymityInnerClassTest {
	@Test
	public void t(){
		AnonymityInnerClass aic = new AnonymityInnerClass();
		aic.Method();
	}
	
}

匿名内部类对于接口和抽象方法的实现也是跟上面差不多。实现抽象方法重写时,不需要在里面用abstract修饰。

四、静态内部类。

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。

静态内部类的创建不依赖外部类。使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象,不需要依赖外部类。静态内部类不能访问外部类的非静态成员和非静态方法。因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41061437/article/details/81326860

智能推荐

zimbra邮箱服务器搭建及错误_weixin_34259232的博客-程序员秘密

zimbra硬件要求,25G硬盘(最好10G),8G内存(4G也可),ubuntu14.04系统,/分区硬盘够大,最好做逻辑卷可以扩容。1.vim /etc/hostnamemail.o8mm.com2.vim /etc/hosts192.168.0.35mail.o8mm.com mail3.vim /etc/dnsmasq.confserver=192.168.0....

在线视频_onlyzhaozhen的博客-程序员秘密

在线视频[code="java"]http://www.red5.org/[/code]Red5总结 做网站开发已经几年有余了,最近终于忙完了自己的青青豆,以前始终没有抽出时间自己写点什么,偶尔拿起偶尔放下,终究是空,希望自己多多坚持,也希望博友的多多支持,分享自己一些积累的经验! 前一段时间公司鉴于首页不错的流量,希望增加一些格外的收入或者做些视频推广,需...

C语言最重要的知识点【入门干货】_c语言重要内容_yzcn的博客-程序员秘密

C语言最重要的知识点总体上必须清楚的:1)程序结构是三种: 顺序结构 、选择结构(分支结构)、循环结构。2)读程序都要从main()入口, 然后从最上面顺序往下读(碰到循环做循环,碰到选择做选择),有且只有一个main函数。3)计算机的数据在电脑中保存是以 二进制的形式. 数据存放的位置就是 他的地址.4)bit是位 是指为0 或者1。 byte 是指字节, 一个字节 = 八个位.概念常考到的:1、编译预处理不是C语言的一部分,不占运行时间,不要加分号。C语言编译的程...

转录组测序和RNA-seq_rna-seq是二代测序吗_wangchuang2017的博客-程序员秘密

转录组测序和RNA-seq是一样的,他们的关系zhi如下:转录组测序的方法很多,而RNA-seq是当zhuan前转录组测序的一种测序方法,又称为二代测序,包括454,solexa等。RNA-seq即转录组测序技术,就是把mRNA,smallRNA,and NONcoding RNA等或者其中一些用高通量测序技术把它们的序列测出来。反映出它们的表达水平。 数字基因表达谱升级版(RNA-Seq)是用来研究某一生物对象在特定生物过程中基因表达差异的技术。该技术结合了转录组测序建库的实验方法与数字...

hdu1251_hdu - 1251_Ice_Crazy的博客-程序员秘密

/*分析:    第一次写字典树,看了看杭电课件,然后跟着映像写的,差不多,1a哦~,算是半个模板吧。                                                2012-07-04   */#include"stdio.h"#include"string.h"#include"stdlib

随便推点

pytorch 入门(1): pytorch库基本用法举例_知者智者的博客-程序员秘密

这一系列文章是对pytorch 入门教程的翻译和学习总结。英文原版可以从以下网址获得:https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html目标:理解Pytorch Tensor 库和神经网络 训练一个小的神经网络来分类图片。本手册假定你对numpy库有一个基本的了解。注意:确保你的测试环境已经安装了torch 和 torchvision 包Pytorch是什么?Pytoch...

什么是沙箱机制_沙箱机制什么意思_如山似水0_0的博客-程序员秘密

1.为什么需要沙箱机制?默认情况下,一个应用程序是可以访问机器上的所有资源的,比如CPU、内存、文件系统、网络等等。但是这是不安全的,如果随意操作资源,有可能破坏其他应用程序正在使用的资源,或者造成数据泄漏。为了解决这个问题,一般有下面两种解决方案:(1) 为程序分配一个限定权限的账号:利用操作系统的权限管理机制进行限制(2) 为程序提供一个受限的运行环境:这就是沙箱机制2.什么是沙箱机...

kmp算法中next和nextval计算方法和代码总结_赵秋然的博客-程序员秘密

此篇文章总结的 基于kmp中的模式串方式关于next图解如下举例:字符串 “ababaa”索引 0 1 2 3 4 5 字符 a b a b a a next 0 0 1 1 2 3 next定义写法从索引1位置开始计算,除去第i位置,从0到 i-1,前后缀中最长重复字符长度next[0]=0 默认0,没有前后缀next[1] =0,字符a...

Docker Compose水平扩展和负载均衡_Jeremy_Lee123的博客-程序员秘密

一、scale实现水平扩展docker-comose scale : Set number of containers for a service,实现水平扩展1.1、用到的三个文件docker-compose.yaml文件version: "3"services: redis: image: redis web: build: ...

计算机原理中阶符是指,计算机原理2010年7月真题(02384)_晴朗的树的博客-程序员秘密

计算机原理2010年7月真题及答案解析(02384)计算机原理2010年7月真题及答案解析(02384),该试卷为计算机原理自考历年真题试卷,包含答案及详细解析。一、单项选择题(本大题共 15 小题,每小题 2 分,共 30 分)在每小题列出的四个备选项中只有一个选项是符合题目要求的,请将其代码填写在题后的括号内。错选.多选或未选均无分。1.MTTR 是衡量计算机性能指标中的( )A.运算速度B....

UML类图中聚合和组合的区别详解(含代码)_描述聚合和组合的异同,画图举例说明怎么写_HNUchaowang的博客-程序员秘密

接上一篇文章:https://blog.csdn.net/HNUchaowang/article/details/108311858说一句题外话,就是讨论一下为什么要去学习什么类图呢?要去理解这么多关系呢?我觉得有如下两个作用吧:第一,最实在的,程序员肯定少不了写设计文档,设计文档肯定包含类图;第二,这个理解类与类之间的关系,是学习设计模式的基础。设计模式是什么,那就是相当于“降龙十八掌”和“独孤九剑”的武功秘籍啊,一招一式都是大佬多年来提炼的精髓。话不多说,切入正题。聚合(has-a)和组合(

推荐文章

热门文章

相关标签