内部类(inner class)的简单介绍
本文主要介绍内部类(inner class)的一些基本应用,将从内部类的分类角度,首先对每一个具体内部类进行介绍。主要包括普通的内部类【common inner class】、局部内部类[local inner class]、嵌套内部类【nested innner class】、匿名内部类【anonymous inner class】、然后比较一下局部内部类[local inner class]和匿名内部类【anonymous inner class ]的区别,进而知道在具体情况下该选择内部类,即到底用local inner class还是anonymous inner class。最后介绍内部类的应用。
一:首先对每一个具体内部类进行介绍
1.普通的内部类【common inner class】
定义:在一个类里面直接定义一个类:
一些详细情况看代码:
package com.qls.comonInnerClass; public class A {
/**
* 从B C D E 这四个普通内部类中可以看出类前面的修饰符可以是
* private protected default(也就是什么修饰符没有的D) public. 而在局部内部类中修饰类的只能是:
* abstract 或final 或者什么修饰符都没有。
* 注意的问题如下:
* 1.通常情况下:外部类会有一个返回内部类引用的一个方法如getB()这个方法。
* 2.如何在内部类中用this指代外部类引用?【答:外部类名.this 参考第19行代码。】
* 以及如何创建内部类的一个实例?【答:x.new B() 其中x是外部类的一个实例,B为一个内部类。
* 若是直接写new B()会报错。参考第38、39两行代码。】
* 上述两个注意点对其他的内部类也适用。
* @author 秦林森
*
*/
private class B {
public A outer(){
return A.this;//A.this是指代A的一个引用。
}
}
protected class C{ }
class D{ }
public class E{ }
/**
* 返回内部类的引用:
*/
B getB(){
return new B();
}
public static void main(String[] args) {
A a = new A();
B b = a.new B();
}
}
局部内部类【local innner class】
定义:把类定义在方法里面,或者是方法中的某一个区域中。
代码如下:
package com.qls.localInnerClass2;
/**
* 定义:the creation of an entire class within the scope of a method,or Nesting a class within
* a scope of a method.
* This is called a local inner class.
* 注意情况如下:
* 1.局部内部类【local inner class】如果想要修饰的话,只有abstract 和final可以,
* 其余的如(public protected)等都不可以。
* 2.在局部内部类中只能访问包含该内部类的范围(enclosing scope)的final变量。若不是则会报错。
*
* @author 秦林森
*
*/
public class A {
public void ouyangfeng(){
//把类D定义在方法ouyangfeng()的某个区域中。
if(3>2){
class D{ }
}
final class B{ }
} public void sixi(final String s){
int e=1;
final int c=8;
class C{
/**
* 在局部内部类或者匿名内部类中只能访问包含该内部类的范围(enclosing scope)的final变量。
* 若不是则会报错。
* 如int f=e;编译器报错。
*/
String str=s;
int d=c;
// int f=e;//编译器报错。
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub } }
匿名内部类:没有名字的内部类。
下面的代码介绍了以下的内容:
1.匿名内部类实现一个接口,
2.匿名内部类实现一个没有默认构造方法的抽象类
3.匿名内部类和局部内部类一样把参数定义成final,完成字段初始化
4.匿名内部类用普通代码块{}完成初始化,弥补了匿名内部类没有构造方法的缺陷。
代码如下:
package com.qls.anonymouseInnerClass;
/**
* 匿名内部类(anonymous inner class)一般用在return 语句中。
* 注意情况如下:
* 匿名内部类由于没有名字,自然而然也就没有构造方法,其他三种内部类都有构造方法。
* 没有构造方法怎么给对象赋值进行初始化呢?【答:用普通的代码块{},在这个代码块里面实行初始化。】
* @author 秦林森
*
*/
interface B{
void ouyangfeng();
}
abstract class C{
private int i;
public C(int i) {
this.i=i;
}
public abstract int value(); }
public class A {
public B getB(){
//new B(){};就是匿名内部类:用默认的构造方法
return new B() { @Override
public void ouyangfeng() {
// TODO Auto-generated method stub
System.out.println("ouyangfeng is chief village of sixi ");
}
};
}
public C getC(final int i){
//匿名内部类用一个带参数的构造方法
return new C(i) {
//用普通代码块实现初始化:
{
//这里写两个输出语句作为演示。
System.out.println("泗溪");
System.out.println("ouyangfeng");
System.out.println(value());//输出value的值
}
@Override
public int value() {
// TODO Auto-generated method stub
return i;//从这里可以看出要想引用i,必须把i定义成final。这和局部内部类一样。
}
}; }
public static void main(String[] args) {
// TODO Auto-generated method stub
new A().getC(4);//输出泗溪、ouyangfeng、4 } }
嵌套内部类:
package com.qls.nestedClass;
/**
* 如果你不想让内部类的对象和外部类的对象有如何联系的话,你就可以把内部类定义成static
* 嵌套内部类(Nested inner class)的定义:类中关键词static修饰的内部类。
* 注意情况如下:
* 1.在嵌套内部类中不能访问外部类的非静态变量。
* 2.创建内部类变量时,你不想通过创建外部类变量才能创建内部类变量时,你可以把这个内部类定义成static
* 即嵌套内部类。
* 3.在接口interface中定义的内部类默认都是public static 的,所以在接口中的内部类必是嵌套内部类。
* @author 秦林森
*
*/
interface D{
void hello();
class Test implements D{ @Override
public void hello() {
// TODO Auto-generated method stub
System.out.println("hello");
}
public static void main(String[] args) {
/**
* 由于Test类默认是public static 的,所以创建Test对象时,不需要通过外部类D,
* 所以直接new Test()即可创建Test类中的一个对象。
* 话又说回来了,如果在接口中的类不是public static 的那么这个内部类也就是普通的内部类
* 在创建Test的对象时,也就需要外部类的对象。关键D是接口,你怎么new 呢?
* 所以在的类只能是static 的。
*/
new Test().hello();//输出hello
}
}
}
public class A {
int a=9;
public static class B{
// int b=a;编译报错
void f(){
System.out.println("f()");
}
}
public static void main(String[] args) {
/**
* 从这里你看到了,可以对B直接new ,访问B中的函数f().
* 但是如果B没有static这个关键字,即B是普通内部类时,必须这样才能访问到f()
* new A().new B().f();
*/
new B().f();
}
}
二:比较一下局部内部类[local inner class]和匿名内部类【anonymous inner class ]的区别
1.匿名内部类没有构造犯法,二局部内部类有构造方法。
2.如果在一个外部类有两个或两个以上的方法,返回的都是某个接口或者抽象类的引用,建议把写一个局部内部类。若写成匿名内部类时,代码会显得特别冗长。反之如果一个时,建议用匿名内部类。
代码如下:
package com.qls.anonymouseInnerClass;
interface Six{
void six();
}
public class Ouyangfeng {
private class SixTest implements Six{ @Override
public void six() {
// TODO Auto-generated method stub } }
public Six f(){
return new SixTest();
}
public Six g(){
return new SixTest();
}
}
三:内部类的应用:
用内部类实现java的多重继承。
package com.qls.anonymouseInnerClass;
class D{ }
abstract class E{ }
class F extends D{
//这是实现多重继承的核心代码。这里是用一个匿名内部类实现
E makeE(){
return new E() {
};
}
}
public class MultipleInherit {
public static void takesD(D d){ }
public static void takesE(E d){ }
public static void main(String[] args) {
// TODO Auto-generated method stub
F d = new F();
takesD(d);
takesE(d.makeE());
} }
最后简要介绍一下让一个类继承另一个类中的内部类?以及怎么让一个类中的内部类继承另一个类的内部类呢?
首先是:让一个类继承另一个类中的内部类
代码如下:
package com.qls.anonymouseInnerClass; import com.qls.anonymouseInnerClass.WithInner.Inner; class WithInner{
class Inner{
private int a;
public Inner(int a) {
this.a=a;
}
public Inner() {
// TODO Auto-generated constructor stub
}
}
}
public class InheritInner extends Inner{
public InheritInner(WithInner withInner) {
// TODO Auto-generated constructor stub
/**
* 这句话必须要写。否则编译器会报错。即:外部类的一个对象.super().
* 这里的super(),比奥斯Inner的一个默认构造方法。
* 如果Inner中比如有这样一个构造方法:public Inner(int a)
* 你现在也可以写成:把withInner.super();改为withInner.super(1);编译器是不会报错的。
* 如果没有默认构造方法public Inner() 则这题必须写成:withInner.super(1);的形式。
*/ withInner.super();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
WithInner withInner = new WithInner();
InheritInner inheritInner = new InheritInner(withInner);
} }
让一个类中的内部类继承另一个类的内部类
代码如下:
package com.qls.anonymouseInnerClass;
/**
* 朱元璋家住凤阳,刘伯温家住青田
* @author 秦林森
*
*/
class ZhuYuanZhang{
class FengYang{
private String location; public FengYang(String location) {
this.location = location;
} }
}
class LiuBoWei{
class QingTian extends ZhuYuanZhang.FengYang{
private String location;
public QingTian(ZhuYuanZhang zhuYuanZhang, String location) {
zhuYuanZhang.super(location);//这句话必须要写。或者会报错,
this.location=location;
}
public void accurate(){
System.out.println("一统江山刘伯温 ,家在"+location);
}
}
}
public class Test { public static void main(String[] args) {
// TODO Auto-generated method stub
new LiuBoWei().new QingTian(new ZhuYuanZhang(), "青田").accurate();
} }/*Output:
一统江山刘伯温 ,家在青田*///:~
内部类(inner class)的简单介绍的更多相关文章
- angular1.x的简单介绍(二)
首先还是要强调一下DI,DI(Denpendency Injection)伸手获得,主要解决模块间的耦合关系.那么模块是又什么组成的呢?在我看来,模块的最小单位是类,多个类的组合就是模块.关于在根模块 ...
- dubbo学习过程、使用经验分享及实现原理简单介绍
一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不 ...
- 【Dubbo基础】dubbo学习过程、使用经验分享及实现原理简单介绍
一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不 ...
- 算法笔记_071:SPFA算法简单介绍(Java)
目录 1 问题描述 2 解决方案 2.1 具体编码 1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...
- [原创]关于mybatis中一级缓存和二级缓存的简单介绍
关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...
- 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍
一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...
- 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍
一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...
- yii2的权限管理系统RBAC简单介绍
这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...
- Linux的简单介绍和常用命令的介绍
Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...
随机推荐
- pycharm快捷键一览
编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性)Ctrl + Alt + Space 快速导入任意类Ctrl + Shift + Enter 语句完成Ctrl + P ...
- html基础之遗忘篇
a链接: ①a的href指向压缩文件可以下载压缩文件. ②a链接的打开方式可以在head内使用<base target="_blank">来整体控制打开方式. 字符实体 ...
- 第一次认识lambda匿名函数
lambda 为了解决一些简单的需求而设计的"一句话"函数 语法 lambda 参数:返回值 1.可以多个参数,参数间用逗号隔开 2.匿名函数不管多复杂,只能写一行 3.返回值和正 ...
- Form表单提交,js验证
Form表单提交,js验证 1, Onclick() 2, Onsubmit() Button标签 input (属性 submit button )标签 Input type=button ...
- 《算法》第四版 IDEA 运行环境的搭建
<算法>第四版 IDEA 运行环境的搭建 新建 模板 小书匠 在搭建之初,我是想不到会出现如此之多的问题.我看了网上的大部分教程,都是基于Eclipse搭建的,还没有使用IDEA搭建的教程 ...
- java多线程批量读取文件(七)
新公司入职一个多月了,至今没有事情可以做,十来个新同事都一样抓狂,所以大家都自己学习一些新东西,我最近在看zookeeper,感觉蛮不错的,和微服务的zuul以及eureka功能类似,只是代码复杂了一 ...
- P1219 N皇后
P1219 N皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序 ...
- Android 渗透小知识点
客户端用于 ADB 通信的默认端口始终是 5037,设备使用从 5555 到 5585 的端口 adb devices用于显示所有已连接设备, 有时候会出现一些问题, 这时候需要使用adb kill- ...
- idea录制宏
录制一个热部署的快捷键 1.打开Edit-->Macros-->statr Macro Recording 打开之后idea右下角就会出现一个小圆点 然后就可以开始录制自己想要的快捷键 按 ...
- Android 意图通用类 IntentUrl
1.整体分析 1.1.源代码如下,可以直接Copy. public class IntentUtil { /** * 打开链接 * 根据设置判断是用那种方式打开 * * @param context ...