本文主要介绍内部类(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. ES6笔记04-class的基本语法

    JavaScript 语言中,生成实例对象的传统方法是通过构造函数. ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类. clas ...

  2. scrapy--json(360美图)

    之前开始学习scrapy,接触了AJax异步加载.一直没放到自己博客,趁现在不忙,也准备为下一个爬虫做知识储存,就分享给大家. 还是从爬取图片开始,先上图给大家看看成果,QAQ. 一.图片加载的方法 ...

  3. JDK学习---深入理解java中的LinkedList

    本文参考资料: 1.<大话数据结构> 2.http://blog.csdn.net/jzhf2012/article/details/8540543 3.http://blog.csdn. ...

  4. C++机试笔记

  5. Android面试收集录7 AsyncTask详解

    1.Android中的线程 在操作系统中,线程是操作系统调度的最小单元,同时线程又是一种受限的系统资源,即线程不可能无限制地产生, 并且 **线程的创建和销毁都会有相应的开销.**当系统中存在大量的线 ...

  6. 0x01.被动信息收集

    被动信息收集 基于公开渠道,不与目标系统产生直接交互,尽量避免留下痕迹(不进行大量扫描,正常交互范围) 信息收集内容 IP段 域名 邮件地址(定位邮件服务器,分为个人搭建和公网邮件系统) 文档图片数据 ...

  7. HDU 1384 Intervals(差分约束)

    Intervals Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  8. (D)spring boot使用注解类代替xml配置实例化bean

    bean经常需要被实例化,最常见的就是new一个呗,Bean bean = new Bean(),方便好用还快捷. 然而在我们刚开始学习写i项目的时候却发现,new不好用哦,并且也不报错,根本不知道怎 ...

  9. asp.net 常用几种下载方式

    protected void Button1_Click(object sender, EventArgs e) { /* 微软为Response对象提供了一个新的方法TransmitFile来解决使 ...

  10. es6实现简单模板编译

    现在有各种框架,其中一个主要模块就是关于template.最火的vue.react等框架,在这一块上也是是下足了功夫.我也想写一个自己的模板编译工具,所以就做了个简单的实现,主要是使用es6的反引号编 ...