博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java中的内部类
阅读量:4980 次
发布时间:2019-06-12

本文共 3613 字,大约阅读时间需要 12 分钟。

内部类

可以将一个类的定义定义在另一个类的定义中,这个类就叫做内部类。

让我们看下关于定义一个内部类的简单示例。

public class TestOne {    /*     * 定义一个内部类     * */    public class InnerClass{}}

上述代码我们在TestOne类中定义了一个InnerClass内部类。

关于使用内部类的好处,我将在下面的代码中一一介绍。

 

1、静态内部类:

静态内部类的定义和定义一个静态方法一样很简单,只需要在定义它的时候给它一个static修饰符。

public class TestOne {    /*     * 定义一个非静态内部类     * */    public class InnerClass{}    /*    * 定义一个静态内部类    * */    public static class StaticInnerClass{}    public static void main(String[] args) {        /*        * 实例化一个非静态内部类        * */        TestOne testOne = new TestOne();        TestOne.InnerClass innerClass = testOne.new InnerClass();                /*        * 实例化一个静态内部类        * */        TestOne.StaticInnerClass staticInnerClass = new TestOne.StaticInnerClass();    }}

像上述代码,定义了一个静态内部类和非静态内部类,他们有几个不同点。

  1. 静态内部类由static修饰。
  2. 静态类和静态方法一样是相对于类的,所以在实例化时不需要实例化外部类。而是直接通过外部类类名寻找内部类实例化。

 

2.局部内部类:

局部内部类就是定义在一个方法的内部,使用的范围也局限于这个方法的作用域。

public class TestOne {    /*    * 为TestOne类定义一个成员方法    * */    public void function(){        /*        * 在成员方法中定义一个内部类        * 相对于外部类来讲,这个类叫做局部内部类        * 因为它的作用域仅在这个方法有效        * */       class InnerClass{}       /*       * 只能在方法内部实例化和使用这个类       * */       InnerClass innerClass = new InnerClass();    }}

 

3.成员内部类:

定义在成员变量和成员方法同等区域的非静态内部类就叫做成员内部类,开头的那个例子就是一个公共的成员内部类。

public class TestOne {    /*     * 定义一个内部类     * */    public class InnerClass{}}

 

4.匿名内部类:

/** 定义匿名内部类的父接口* */interface InnerInterface{    void saying();}/* * 定义匿名内部类的父类 * */abstract class InnerAbstractClass{   abstract void saying();}public class TestOne {    private int a = 10;        public InnerInterface getInnerInterface(){    /*    * 定义匿名内部类。    * */        return new InnerInterface() {            public void saying(){                System.out.println("InnerInterface");            }        };    }        public InnerAbstractClass getInnerAbstractClass(){    /*    * 定义匿名内部类。    * */        return new InnerAbstractClass() {            void saying() {                System.out.println("InnerAbstractClass");            }        };    }  }

对于匿名内部类,我们在定义它时需要先定义它的外部父接口或父类(一组规范),其实内部类本身是一个子类,他在定义时重写父接口或父类中的方法。但是它不能有构造函数,因为它是匿名的所以没有构造器能提供给它使用。

但是匿名内部类我们只能使用一次,那是因为我们是在使用的时候才定义它的,如果需要重复使用,那我们应该定义局部内部类而不是匿名内部类。

在匿名内部类中给父类有参构造器传参:

/**父类*/abstract class InnerAbstractClass{    private int a;    public InnerAbstractClass(int a){        this.a = a;    }   abstract void saying();}public InnerAbstractClass getInnerAbstractClass(final int a){    /*    * 定义匿名内部类。    * */        return new InnerAbstractClass(a) {            void saying() {                System.out.println("InnerAbstractClass "+a);            }        };    }    public static void main(String[] args) {        TestOne testOne = new TestOne();       InnerAbstractClass a =  testOne.getInnerAbstractClass(15);       a.saying();    }}/**output:*15*/

当我们需要对匿名内部类传递外部参数时,需要将形参修饰成final的,这个道很容易理解,因为绝大多数时候你也不想自己传进去的变量重新调用时值发生改变或者引用指向另一个对象。

而虽然匿名内部类没有构造器,但是可以通过如图过程在父类中定义构造函数然后通过匿名内部类对父类构造器进行传参。

内部类的特性:

1.始终包含一个指向外部类的引用:

因为内部类是定义在外部类里面的,所以无论外部类和外部类的成员变量、成员方法被怎样修饰,内部类都可以通过外部类的引用调用他们。

public class TestOne {   private int a =10;  public class Inner{      public void fun(){          /*          *外部类对象引用:TestOne.this          * */          System.out.println(TestOne.this.a);      }  }    public static void main(String[] args) {    TestOne testOne = new TestOne();     TestOne.Inner inner = testOne.new Inner();     inner.fun();    }}/** output:* 10* */

2.继承类和实现接口:

因为在Java的继承结构中是单根继承的,所以一个类只能继承一个接口,虽然可以继承任意数量的接口,但是在一个类中实现太多的接口本身就不符合Java的编程规范,内部类很好的解决了这一点。

我们可以定义许多我们需要的内部类,通过合理的分配让它们去继承和实现我们想要的类和接口,这样写出来的代码会具有良好的可阅读性。

转载于:https://www.cnblogs.com/old-driver-lgq/p/10806282.html

你可能感兴趣的文章
yui问题
查看>>
c++ STL stack容器成员函数
查看>>
idea maven install 卡住,无报错排查。
查看>>
AFNetworking 3.0迁移指南
查看>>
mysql 内置功能 存储过程 创建有参存储过程
查看>>
bash变量常用技巧
查看>>
Git reflog
查看>>
BZOJ5340: [Ctsc2018]假面【概率+期望】【思维】
查看>>
leetcode341 - Flatten Nested List Iterator - medium
查看>>
php-session的使用(学习笔记,仅供参考)
查看>>
深入理解JavaScript系列(19):求值策略(Evaluation strategy)
查看>>
mp4文件格式解析(转)
查看>>
友坚恒天.开发板(Cotex-A9 Exynos4412 开发板)
查看>>
高精度运算
查看>>
番外篇-AppService服务
查看>>
解决远程连接mysql错误1130(转载)
查看>>
JavaWeb--------数据库连接池c3p0
查看>>
内联函数
查看>>
命令模式
查看>>
有关浏览器兼容样式问题
查看>>