Java的内部类

  

首先我们来了解一下什么是内部类?

  内部类是指在一个外部类的内部再定义一个类.内部类可以是静态static的,也可用public,default,protected和private修饰。(而外部顶级类即类名和文件名相同的只能使用public和default)

 

为什么要使用内部类?

  比如我们在new一个接口的时候,我们是不是需要new一个实现接口的类,然后要实现接口中的方法,显得很麻烦,如果是使用内部类的话,可以直接在类中直接new一个接口的实现,显得是很方便的,又例如我们要使用某一个对象的中的方法,我们是不是new这个类出来,然后调用这个类的方法,这样做的话,类文件会大量的存在,为了避免这种情况,我们也可以借助内部类来实现.

一. java内部类的分类

    1. 成员内部类

    2. 方法内部类

    3. 匿名内部类

成员内部类

 public class Test {
class A{
public void show(){
System.out.println("这是一个成员内部类");
}
} /**
* 在下面方法,构建成员内部类的对象,并调用成员内部类中的方法
*/
public void test(){
A a = new A();
a.show();
} public static void main(String[] args) {
new Test().test();
}
}

成员内部类方式二

 public class Test1 {
class A {
public void test(){
System.out.println("A");
}
} public static void main(String[] args) {
      

      /**
       * 语法: 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称() ;
       */

         Test1.A ta = new Test1().new A();
ta.test();
}
}

方法内部类

 public class B {
public void show(){
System.out.println("这是一个方法的外部类");
}
}
 /**
* 测试方法内部类
*
*/
public class Test {
public void test(){
class A extends B { public void method(){
System.out.println("方法内部类的方法只在该方法中调用");
} } /**
* 定义在方法里的类,称为方法的内部类
* 且方法内部类中的方法要在该方法中调用
*/
new A().method(); System.out.println("该方法执行完毕");
} public static void main(String[] args) {
Test t = new Test();
t.test();
}
}

方法内部类要注意的局部变量问题

 public class Test1 {
private int a = 10 ; public void show(){
System.out.println("这是成员的内部类");
} /**
* 方法内部类可以直接调用外部类的成员
*/
public void test(){ class A {
public void showA(){
System.out.println("a= :"+a);
show() ;
}
} /**
* 方法内部类,只有在方法内部调用才有效
*/
new A().showA();
} public void test1(){
/**
* int c = 10 ;
* 局部变量是在栈内存的,方法中的变量是随着方法的调用而创建的,随着方法的调用完毕而销毁
*/ /**
* 为什么final什么的变量就可以呢?因为final是发生在编译期间的,这个时候它已经编译好了,
* 所以是可以引用的
*/
final int c = 10 ;
class B {
public void showB(){
System.out.println("c="+c);
}
} /**
* 而new出来的的对象是在堆内存的,但是等方法调用完毕会,有可能这个对象还没有销毁
* 但是这个方法已经销毁了,让一个存在的对象要调用一个不存在的变量,显然会报错
*/
B b = new B();
b.showB();
}
}

匿名内部类

  

 匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。

    什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:

      a·只用到类的一个实例。
      b·类在定义后马上用到。
      c·类非常小(SUN推荐是在4行代码以下)
      d·给类命名并不会导致你的代码更容易被理解。

    在使用匿名内部类时,要记住以下几个原则:

      a·匿名内部类不能有构造方法。
      b·匿名内部类不能定义任何静态成员、方法和类。
      c·匿名内部类不能是public,protected,private,static。
      d·只能创建匿名内部类的一个实例。
      e·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
      f·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。

 /**
* 定义个接口
*/
public interface TestInterface {
public void show();
}
 /**
*
* 一个类实现一个接口时,要么实现接口中的方法,要么继续抽象
*/
public abstract class Test implements TestInterface{
public void test(){
System.out.println("这是抽象类中的方法");
}
}
 public class AnonymousTest extends Test{

     public void show() {
System.out.println("实现了接口中的方法");
}
}

测试没有带名字的匿名内部类和带名字的匿名内部类

public class Demo {
public static void main(String[] args) {
AnonymousTest at = new AnonymousTest();
at.show();
at.test(); /**
* 创建了一个没有名字内部类,它实现了TestInterface接口
* 同时还创建了一个没有名字的内部类对象
*/
new TestInterface(){ public void show() {
System.out.println("实现了接口中的方法");
} }.show(); /**
* 创建了一个没有名字内部类,它是一个抽象类
* 同时还创建了一个没有名字的内部类对象
*/
new Test(){ public void show() {
System.out.println("实现了接口中的方法");
}
}; /**
* 这是一个带名字的内部类,它是一个接口
* 同时创建了一个内部类对象
*/
TestInterface tf = new TestInterface(){ public void show() {
System.out.println("这是接口中的方法");
} }; /**
* 这是一个带名字的匿名内部类,它是抽象的类
* 同时还创建了一个带名字的内部类对象
*/
Test t = new Test(){ public void show() {
System.out.println("带名字的匿名内部类");
}
}; /**
* 调用方法
*
* t.show()是匿名内部类中的方法
* t.test()是Test抽象类中的方法
*/
t.show();
t.test();
}
}

匿名内部类做参数传递

 /**
* 匿名内部类做参数
*
*/
public class Demo1 {
public static void main(String[] args) {
new Demo1().show(new TestInterface(){ public void show() {
System.out.println("匿名内部类做参数");
} });
} public void show(TestInterface tf){
tf.show();
}
}

匿名内部类做返回值

 public class Demo2 {
public static void main(String[] args) {
TestInterface tf = new Demo2().test();
System.out.println(tf); Test t = new Demo2().test1();
System.out.println(t);
} /**
* TestInterface是一个接口
* @return TestInterface
*/
public TestInterface test(){
return new TestInterface(){ public void show() {
System.out.println("匿名内部类做返回值");
} };
} /**
* Test是一个抽象类
* @return Test
*/
public Test test1(){
return new Test(){ public void show() {
System.out.println("匿名内部类做返回值");
} };
}
}

Java的内部类的更多相关文章

  1. Java学习--内部类(一)

    Java学习--内部类(一) 一. 内部类的定义和特点 class Outer{ privite int num = 5; class Inner{ public void Display(){ Sy ...

  2. java使用内部类的好处及其初始化

    java使用内部类的原因 每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响          java内部类初始化 ForeCatal ...

  3. JAVA基础——内部类详解

    JAVA内部类详解 在我的另一篇java三大特性的封装中讲到java内部类的简单概要,这里将详细深入了解java内部类的使用和应用. 我们知道内部类可分为以下几种: 成员内部类 静态内部类 方法内部类 ...

  4. JAVA面向对象-----内部类的概述

    JAVA面向对象-–内部类的概述s 将类定义在另一个类的内部则成为内部类.其实就是类定义的位置发生了变化. 在一个类中,定义在类中的叫成员变量,定义在函数中的叫成员函数,那么根据类定义的位置也可以分为 ...

  5. Java的内部类真的那么难以理解?

    01 前言 昨天晚上,我把车停好以后就回家了.回家后才发现手机落在车里面了,但外面太冷,冷到骨头都能感受到寒意——实在是不想返回一趟去取了(小区的安保还不错,不用担心被砸车玻璃),于是打定主意过几个小 ...

  6. 第30节:Java基础-内部类

    内部类 // 外部类 class Demo{ private int num = 3; // 定义内部类 class Int{ void show(){ System.out.println(&quo ...

  7. 【Java】 内部类

    [Java]内部类 可以将一个类的定义放在另一个类的定义内部,这就是内部类. 使用内部类的的原因主要有三点: 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据. 内部类可以对同一个包中的 ...

  8. java中内部类的积累

    放在一个类的内部的类我们就叫内部类. 二. 作用 1.内部类可以很好的实现隐藏 一般的非内部类,是不允许有 private 与protected权限的,但内部类可以 2.内部类拥有外围类的所有元素的访 ...

  9. Java 基础 内部类

    Java 基础 内部类 内部类(嵌套类) nested class 目的为外围类enclosing class提供服务. 四种: 静态成员类 static member class 非静态成员类 no ...

随机推荐

  1. spring事物配置,声明式事务管理和基于@Transactional注解的使用

    http://blog.csdn.net/bao19901210/article/details/41724355 http://www.cnblogs.com/leiOOlei/p/3725911. ...

  2. GAT2.0使用文档(组合接口测试)

    3.2接口用例场景组件 在此之前,大家应该都已经开发完成了一个最简单的接口测试用例,但是之前的接口用例的期望结果是固定值,不能动态的去做对比,有很大局限性.下面开始介绍怎样通过场景组件来动态对测试结果 ...

  3. Android-Universal-Image-Loader的缓存处理机制

    讲到缓存,平时流水线上的码农一定觉得这是一个高大上的东西.看过网上各种讲缓存原理的文章,总感觉那些文章讲的就是玩具,能用吗?这次我将带你一起看过UIL这个国内外大牛都追捧的图片缓存类库的缓存处理机制. ...

  4. [问题2014S13] 解答

    [问题2014S13]  解答 (1) 先证必要性:若 \(A=LU\) 是 非异阵 \(A\) 的 \(LU\) 分解,则 \(L\) 是主对角元全部等于 1 的下三角阵,\(U\) 是主对角元全部 ...

  5. 通过Mac远程调试iPhone/iPad上的网页(转)

    我们知道在 Mac/PC 上的浏览器都有 Web 检查器这类的工具(如最著名的 Firebug)对前端开发进行调试,而在 iPhone/iPad 由于限于屏幕的大小和触摸屏的使用习惯,直接对网页调试非 ...

  6. js的一些复习

    JavaScript Js是一种直译式的脚本语言,是一种弱类型,基于对象的语言.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言 ...

  7. Android 连接webservice(利用谷歌提供的jar包)

    Android开发,需要连接webservice,之前就想用谷歌提供的jar包,下载地址:http://pan.baidu.com/s/1hqMTUHe 把它下载下来粘贴到libs文件夹下即可: 网上 ...

  8. 【转】gdb 调试段错误

    [转]gdb 调试段错误 转自:blog.csdn.net/yangzhu1982/article/details/6318600 开发嵌入式Linux的时候经常会遇到segmentation fau ...

  9. [java基础]循环结构2

    [java基础]循环结构2 写了几个循环结构练习~记录一下~~ 1:99乘法表 /** 文件路径:G:\JavaByHands\循环语句\ 文件名称:GameForFor.java 编写时间:2016 ...

  10. 打完补丁后测试db_link对SCN的影响

    环境:11.2.0.4.0 升 11.2.0.4.8 后测试 背景:oracle 的db_link会导致实例间SCN同步,SCN增长速度过快则会产生错误: 方案:oracle官方推荐升级版本,但升级之 ...