在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类

  • 内部类和外层封装它的类之间存在逻辑上的所属关系
  • Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。 Inner class的名字不能与包含它的类名相同;
  • Inner class可以使用包含它的类的静态和实例成员变量,也可以使用它所在方法的局部变量
  • 内部类跟方法和成员变量一样,都是类的一个成员。所以像final,abstract,private,static,protected可以用来修饰内部类(比如外部类不能声明为private)。内部类享有和内部成员同样的待遇

为什么使用内部类?

如果这个类没有定义在外部的必要,即使此类仅供外部类的方法来调用,而不会被其他外部类调用。

package com.atguigu.java;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* 内部类:
* 1. 在类的内部定义的类成为内部类
* 2. 内部类相当于类的一个成员, 可以修饰类的成员的 private, static, final, abstract 都可以修饰内部类
* 3. 声明、使用内部类的实例.
* 3.1 非静态内部类的创建, 先创建外部类的实例, 再通过 外部类名.new 创建内部类的实例.
* OuterClass oc = new OuterClass();
* OuterClass.InnerClass in = oc.new InnerClass();
*
* 3.2 静态内部类的创建: 不再需要外部类的实例.
* OuterClass.StaticInnerClass sic = new OuterClass.StaticInnerClass();
*
* 4. 内部类引用外部类的成员:
*
* 5. ** 匿名内部类对象: 使用某一个接口通常是 先创建接口的实现类, 再创建其实现类的对象.
* 还可以, 直接创建其实现类对象.
*
* InvocationHandler invocationHandler = new InvocationHandler() {
* @Override
* public Object invoke(Object proxy, Method method, Object[] args)
* throws Throwable {
* return null;
* }
* };
*
*
*/
public class OuterClass { int age; static class StaticInnerClass{
void test(){
//System.out.println(age);
}
} static String name = "-1"; //内部类
class InnerClass{
String name = "0"; public void test(){
String name = "1"; System.out.println(name); //
System.out.println(this.name); //
System.out.println(OuterClass.this.name); //-1
}
} }
package com.atguigu.java;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class TestInnerClass { public static void main(String[] args) { OuterClass.StaticInnerClass sic = new OuterClass.StaticInnerClass(); OuterClass oc = new OuterClass();
OuterClass.InnerClass in = oc.new InnerClass();
in.test(); Proxy.newProxyInstance(null, null, new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}); InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}; } }

匿名内部类

使用匿名内部类课使代码更加简洁、紧凑,模块化程度更高。内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到。

就是匿名内部类的两种实现方式:

第一种,继承一个类,重写其方法;

第二种,实现一个接口(可以是多个),实现其方法。下面通过代码来说明:

不使用内部类

abstract class Person {
public abstract void eat();
} class Child extends Person {
public void eat() {
System.out.println("eat something");
}
} public class Demo {
public static void main(String[] args) {
Person p = new Child();
p.eat();
}
}

运行结果:eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用

但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?

这个时候就引入了匿名内部类

abstract class Person {
public abstract void eat();
} public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
}

运行结果:eat something

可以看到,我们直接将抽象类Person中的方法在大括号中实现了

这样便可以省略一个类的书写

  • 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写
  • 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。匿名内部类就是重写父类或接口的方法。
  • 匿名内部类是没有名字的,所以我们没办法获得其类型,而只能把它当作超类或接口类型来使用。

参考:内部类 http://www.cnblogs.com/tech-bird/p/3650069.html

匿名内部类http://www.cnblogs.com/tech-bird/p/3651551.html

java的内部类及匿名内部类的更多相关文章

  1. 十一、Java基础---------内部类与匿名内部类

    内部类分为普通内部类(有名)和匿名内部类.普通内部类分为成员内部类.局部内部类.静态内部类(嵌套内部类).顾名思义,内部类就是定义在一个类内部的类.什么时候都会使用内部类呢?当我们定义一个类,发现内部 ...

  2. java语言内部类和匿名内部类

    内部类 在类定义也有类,在该类上的内部被称为一个内部类. 访问功能: 1,内部类可以直接访问外部类成员,它包含私有成员 2,外部类需要访问内部类的成员将需要建立一流的内部对象. 一般用于类的设计. 分 ...

  3. Java中的内部类(成员内部类、静态内部类、局部内部类、匿名内部类)

    Java中的内部类(成员内部类.静态内部类.局部内部类.匿名内部类) 神话丿小王子的博客主页 我们先看这样一段话:人是由大脑.肢体.器官等身体结果组成.而组成我们人体的心脏它也有自己的属性和行为(血液 ...

  4. java之内部类(InnerClass)----非静态内部类、静态内部类、局部内部类、匿名内部类

    提起java内裤类(innerClass)很多人不太熟悉,实际上类似的概念在c++里面也有,那就是嵌套类(Nested Class),关于这俩者的区别,在下文中会有对比.内部类从表面上看,就是在类中定 ...

  5. Java编程之委托代理回调、内部类以及匿名内部类回调(闭包回调)

    最近一直在看Java的相关东西,因为我们在iOS开发是,无论是Objective-C还是Swift中,经常会用到委托代理回调,以及Block回调或者说是闭包回调.接下来我们就来看看Java语言中是如何 ...

  6. “全栈2019”Java第一百一十章:局部内部类与匿名内部类区别详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. java 内部类、匿名内部类

    一:内部类 1:什么是内部类? 大部分时候,类被定义成一个独立的程序单元.在某些情况下,也会把一个类放在另一个类的内部定义,这个定义在其他类内部的类就被称为内部类(有些地方也叫做嵌套类),包含内部类的 ...

  8. Java之有名内部类和匿名内部类

    Java内部类 定义在外部类中的类就是内部类:内部类的定义是为了更清楚.详细地描述事物. 有名内部类和匿名内部类 Java语言根据内部类是否有类名将内部类分为有名内部类和匿名内部类(没有类名). 有名 ...

  9. java面对对象(六)--内部类、匿名内部类

    内部类 可以在一个类的内部定义另一个类这种类成为内部类或嵌套类,比如: class Outer{ … class Inner{ …. } } class Outer1{} // 这个Inner1不是O ...

随机推荐

  1. oracle 的变量的定义和赋值

    第一种 :先定义后赋值 代码 : declare     V_AgeingType        varchar2(500); begin V_AgeingType :='111'; end 第二种 ...

  2. node.js常用的几个模块总结

    /** 一 util *      是 node 里面一个工具模块 ,node 里面几乎所有的模块 都会用到 在这个模块 *  功能: *      1 实现继承 这是主要功能 *      2 实现 ...

  3. (转)iFrame高度自适应

    第一种方法:代码简单,兼容性还可以,大家可以先测试下: function SetWinHeight(obj) { var win=obj; if (document.getElementById) { ...

  4. JavaScript--格式化当前时间

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. 数据库备份工具mysqldump重要参数详解

    1. --single-transaction InnoDB 表在备份时,通常启用选项 --single-transaction 来保证备份的一致性,实际上它的工作原理是设定本次会话的隔离级别为:RE ...

  6. windows Server 2008 IIS7 503错误解决方案

    windows 2008 R2 在访问的时候经常会出现503错误,于之前使用的是默认配置,服务器最多只能处理5000个同时请求,今天下午由于某种情况造成同时请求超过5000,下面是具体的解决方案: w ...

  7. Rabbitmq init terminating in do boot 问题

    其实出现这个问题的原因很简单,就是rabbitmq的安装目录中是不能带空格的,但是官方安装包会默认的将我们的程序安装到Program Files下,哭晕啊有没有.所以,我们将rabbitmq从D:\P ...

  8. bzoj1188: [HNOI2007]分裂游戏

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...

  9. 省队集训day6 C

    Description 给定平面上的 N 个点, 其中有一些是红的, 其他是蓝的.现在让你找两条平行的直线, 使得在保证    不存在一个蓝色的点 被夹在两条平行线之间,不经过任何一个点, 不管是蓝色 ...

  10. The working copy xxxx needs to be upgraded to Subversion 1.7.

    原因是我在svn是低版本时候checkout的项目 而对方用的版本比我高 然后 我运行这个项目  就要求我  更新 如果我选择   对项目进行upgrade. 当 upgrade后 我的项目就在 现有 ...