专栏首页Java爬坑系列【Java入门提高篇】Day6 Java内部类——成员内部类

【Java入门提高篇】Day6 Java内部类——成员内部类

  内部类是什么,简单来说,就是定义在类内部的类(一本正经的说着废话)。

  一个正经的内部类是长这样的:

public class Outer {
    class Inner{
    }
}

  这是为了演示而写的类,没有什么luan用,可以看到Inner类置于Outer类的内部。

  那为什么要大费周章的在类内部定义一个类呢?不能在类外部定义类吗?内部类跟外部类有什么关系?

  确实,很多时候,在外部单独定义一个类确实更加方便,也更加通用,但内部类的存在自然有其存在的道理,内部类作为寄生在外部类的类,可以自由访问内部类的所有的属性和方法,有没有联想其我们之前说的继承,子类可以继承父类的属性和方法,但是内部类有着更高的访问权限,不仅是public属性,protected属性,就连private属性也可以轻松访问,这样就不会让修饰符限制你的想象了(手动滑稽)。

  内部类也分很多种:成员内部类、静态内部类、局部内部类、匿名内部类。今天先来说说第一种:成员内部类。

  成员内部类是最简单粗暴的内部类,上面那个栗子中的Inner类就是成员内部类,相比普通的类,成员内部类是不能有static修饰的成员或者方法的,因为成员内部类是寄生在外部类中的,所以必须先有外部类实例才能有成员内部类。在外部创建内部类对象时,姿势也不太一样,看起来像是这个样子的:

public class Test {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
    }
}

  在内部类中可以访问外部类的方法和属性,外部类也可以访问内部类的方法和属性,举个栗子:

public class Outer {
    private int num;
    private Inner inner;

    Outer(){
        num = 1;
        inner = new Inner();
    }

    public void print(){
        System.out.println("Outer.print()");
        System.out.println(inner.num);
        System.out.println(num);
    }

    class Inner{
        private int num;

        Inner(){
            num = 2;
        }

        public void print(){
            System.out.println("Inner.print()");
            System.out.println(this.num);
            System.out.println(Outer.this.num);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        outer.print();
        inner.print();
    }
}

  输出如下:

Outer.print()
3
1
Inner.print()
3
1

  外部类访问内部类的姿势是先生成内部类实例,然后就能访问所有方法和属性,内部类访问外部类方法和属性则直接使用Outer.属性/方法名 即可。

  在这个栗子中,我们可以看到内部了Inner可以对外围类Outer的属性进行无限制的访问,尽管它是private修饰的。因为当我们在创建某个外围类的内部类对象时,会往内部类传入一个外部类的引用,只要我们在访问外部类的成员时,就会用这个引用来选择外围类的成员。引用内部类的时候,需要使用Outer.Inner这样的形式来声明,而不能直接使用Inner来声明(除了在Outer类中),当需要使用到内部类的时候,还是推荐使用getInnerInstance的方式来获取,特别是当内部类只有无参构造器的时候:

public class Outer {
    private int num;
    private Inner inner;

    Outer(){
        num = 1;
        inner = new Inner();
    }

    public Inner getInnerInstance() {
        return new Inner();
    }

    public void print(){
        System.out.println("Outer.print()");
        System.out.println(inner.num);
        System.out.println(num);
    }

    public class Inner{
        private int num;

        Inner(){
            num = 2;
        }

        public void print(){
            System.out.println("Inner.print()");
            System.out.println(this.num);
            System.out.println(Outer.this.num);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.getInnerInstance();
        outer.print();
        inner.print();
    }
}

  这样的话,就能更好的封装了。

  当然,内部类跟外部类还有一个很重要区别:内部类可以用private修饰,而外部类是不能使用private修饰的。如果内部类仅仅在类内部使用时,使用private修饰后,就可以更好的隐藏内部信息。

  至此,内部类的第一部分讲解完毕,欢迎大家继续关注。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【Java入门提高篇】Day3 抽象类与接口的比较

      抽象类跟接口都讲完了,现在来做一个比较。   其实说实话,没有多大的可比较性,它们是完全不同的两个东西,它们的抽象不在同一个层级上。但是为了让大家更好的理解...

    弗兰克的猫
  • 【Java入门提高篇】Day10 Java代理——静态代理

      今天要介绍的是一个Java中一个很重要的概念——代理。   什么是代理?联系生活想想看,代理似乎并不陌生,最形象的代表便是经纪人,明星一般都有经纪人,经纪人...

    弗兰克的猫
  • 【Java入门提高篇】Day8 Java内部类——匿名内部类

      今天来看看另一个更加神奇的类——匿名内部类。   就像它的名字表示的那样,这个类是匿名的,用完之后,深藏功与名,就像扫地僧那样默默潜藏于深山之中。匿名内部类...

    弗兰克的猫
  • J2SE 内部类 [Inner]

    /**  * 内部类:  *  内部类与其所在的外层来之间存在着逻辑上的依赖关系--内部类的对象布恩给你单独存在,他必须依赖一个其外层类的对象  *  *  ...

    Hongten
  • java内部类

    用户3030674
  • 第九章:舞台(Stage)简介舞台类以及使用

    1.API定义:拥有多个层次结构的二维场景,场景中有许多演员,处理纹理图片和接收的输入事件,以及负责操作游戏视角、 2.特点:盛装演员,监听并接收触屏事件,处...

    Xiaolei123
  • 苹果的Swift语言开源了!

    ? 苹果公司在今年6月份举行的全球开发者大会中曾承诺今年年底开源新编程语言 Swift,而它终于实现了诺言。据悉,Swift的编程语言将在Apache 2.0...

    非著名程序员
  • 浅谈JAVA设计模式之——桥接模式(Bridge)

    1.你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。

    冰河
  • 迪米特法则

    1. Each unit should have only limited knowledge about other units: only units "c...

    LieBrother
  • OpenCV 3.1.0中特征检测与描述算法接口改动

    OpenCV从 2.4.x升级到3.x中有很多代码重构和性能提高,还有API接口的整合,以Feature2D及其扩展模块的特征检测与描述为例,在OpenCV2....

    OpenCV学堂

扫码关注云+社区

领取腾讯云代金券