本文主要介绍内部类(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)的简单介绍的更多相关文章

  1. angular1.x的简单介绍(二)

    首先还是要强调一下DI,DI(Denpendency Injection)伸手获得,主要解决模块间的耦合关系.那么模块是又什么组成的呢?在我看来,模块的最小单位是类,多个类的组合就是模块.关于在根模块 ...

  2. dubbo学习过程、使用经验分享及实现原理简单介绍

    一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不 ...

  3. 【Dubbo基础】dubbo学习过程、使用经验分享及实现原理简单介绍

    一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不 ...

  4. 算法笔记_071:SPFA算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...

  5. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  6. 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍

    一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...

  7. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  8. yii2的权限管理系统RBAC简单介绍

    这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...

  9. Linux的简单介绍和常用命令的介绍

    Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...

随机推荐

  1. pycharm快捷键一览

    编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性)Ctrl + Alt + Space 快速导入任意类Ctrl + Shift + Enter 语句完成Ctrl + P ...

  2. html基础之遗忘篇

    a链接: ①a的href指向压缩文件可以下载压缩文件. ②a链接的打开方式可以在head内使用<base target="_blank">来整体控制打开方式. 字符实体 ...

  3. 第一次认识lambda匿名函数

    lambda 为了解决一些简单的需求而设计的"一句话"函数 语法 lambda 参数:返回值 1.可以多个参数,参数间用逗号隔开 2.匿名函数不管多复杂,只能写一行 3.返回值和正 ...

  4. Form表单提交,js验证

    Form表单提交,js验证 1,  Onclick() 2, Onsubmit() Button标签 input (属性 submit  button )标签 Input type=button    ...

  5. 《算法》第四版 IDEA 运行环境的搭建

    <算法>第四版 IDEA 运行环境的搭建 新建 模板 小书匠 在搭建之初,我是想不到会出现如此之多的问题.我看了网上的大部分教程,都是基于Eclipse搭建的,还没有使用IDEA搭建的教程 ...

  6. java多线程批量读取文件(七)

    新公司入职一个多月了,至今没有事情可以做,十来个新同事都一样抓狂,所以大家都自己学习一些新东西,我最近在看zookeeper,感觉蛮不错的,和微服务的zuul以及eureka功能类似,只是代码复杂了一 ...

  7. P1219 N皇后

    P1219 N皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序 ...

  8. Android 渗透小知识点

    客户端用于 ADB 通信的默认端口始终是 5037,设备使用从 5555 到 5585 的端口 adb devices用于显示所有已连接设备, 有时候会出现一些问题, 这时候需要使用adb kill- ...

  9. idea录制宏

    录制一个热部署的快捷键 1.打开Edit-->Macros-->statr Macro Recording 打开之后idea右下角就会出现一个小圆点 然后就可以开始录制自己想要的快捷键 按 ...

  10. Android 意图通用类 IntentUrl

    1.整体分析 1.1.源代码如下,可以直接Copy. public class IntentUtil { /** * 打开链接 * 根据设置判断是用那种方式打开 * * @param context ...