• Java中内部类揭秘(一):外部类与非静态内部类的”相互可见性“


               声明:本博客为原创博客。未经同意,不得转载。原文链接为 http://blog.csdn.net/bettarwang/article/details/27012421

          我们都知道。非静态内部类能够訪问外部类的私有成员(包含私有变量和方法),这也正是使用非静态内部类与普通类的一个重要差别:非静态内部类是依赖于外部类对象而存在的,这样的依赖就包含它要能自由地訪问外部类对象的全部成员(由于private成员都能够訪问了,其它权限的成员更不在话下。只是一般来说一个内部类仅仅会訪问外部类的部分成员而不是全部)。比方心脏作为单独的一个类存在可能没有太大的意义,它必须依附于详细的Person对象存在才有意义。并且心脏它要能够自由地訪问Person对象的一些成员,如血液、营养等。

           显然,外部类对于非静态内部类而言是全然透明的。可是实际上,外部类与非静态内部类的还有一个特征尽管不经常使用。却也值得注意,那就是非静态内部类事实上跟外部类的其它成员相似。仅仅是它的一个成员而已,因而即使非静态内部类的修饰符为private、即使非静态内部类的构造器修饰符为private,外部类也能够新建非静态内部类的对象。例如以下例所看到的:

    import java.util.*;
    
    class Car
    {
      private float gasAmount;
      private String gasType;
      public Car(float gasAmount,String gasType)
      {
        this.gasAmount=gasAmount;
        this.gasType=gasType;
        new Engine();
      }
    
      private void print(String msg)
      {
         System.out.println(msg);
       }
      private class Engine
      {
        private int rotateSpeed;
        private Engine()
        {
          if(gasType=="93#"&&gasAmount>0)
          {
              rotateSpeed=1500;
              print("Gas amount is "+String.valueOf(gasAmount)+" gallon now.Engine starts successfully");
          }
          else if(gasType=="93#"&&gasAmount<=0)
          {
              rotateSpeed=0;
              print("Engine starts failed! Please add fuel first!");
           }
          else
          {
              rotateSpeed=0;
              print("Gas type is not correct!");
           }
          
        }
      }
    }
    
    
    public class OuterSample
    {
      public static void main(String[]args)
      {
         new Car(2.0f,"93#");
         new Car(0.0f,"93#");
      }
    }

    输出结果例如以下图所看到的:


    显然,由输出结果可看出:第一。尽管非静态内部类的修饰符和构造器均为private,可是外部类仍然能够创建内部类对象。第二,非静态内部类能够使用外部类的private成员(如此处的private成员变量gasType及gasAmount); 

           还有一个经常被人忽略的地方是:在外部类的方法中,也能够通过创建非静态内部类的对象来訪问内部类包含private成员在内的全部成员,只是注意必须是外部类的实例成员才行,而不能在外部类的静态成员(包含静态方法和静态初始化块)中使用非静态内部类。原因非常easy:非静态内部类可看作是外部类的一个实例成员。而静态成员不能訪问实例成员。

    例如以下例所看到的:

    import java.util.*;
    
    class Car
    {
      private float gasAmount;
      private String gasType;
      private Engine engine;
      public Car(float gasAmount,String gasType)
      {
        this.gasAmount=gasAmount;
        this.gasType=gasType;
        engine=new Engine();
      }
    
      public void printRotateSpeed()
      {
        //事实上写成print("Rotate speed is "+String.valueOf(new Engine().rotateSpeed));也行。可是不太符合实际。由于一车相应一引擎
         print("Rotate speed is "+String.valueOf(engine.rotateSpeed));
       }
      private void print(String msg)
      {
         System.out.println(msg);
       }
      private class Engine
      {
        private int rotateSpeed;
        private Engine()
        {
          if(gasType=="93#"&&gasAmount>0)
          {
              rotateSpeed=1500;
              print("Gas amount is "+String.valueOf(gasAmount)+" gallon now.Engine starts successfully");
          }
          else if(gasType=="93#"&&gasAmount<=0)
          {
              rotateSpeed=0;
              print("Engine starts failed! Please add fuel first!");
           }
          else
          {
              rotateSpeed=0;
              print("Gas type is not correct!");
           }
          
        }
      }
    }
    
    
    public class OuterSample
    {
      public static void main(String[]args)
      {
         Car car01=new Car(2.0f,"93#");
         car01.printRotateSpeed();
         Car car02=new Car(0.0f,"93#");
         car02.printRotateSpeed();
      }
    }
    输出结果例如以下图:


           从输出结果能够看出,在外部类的方法printRotateSpeed()中。通过非静态内部类的对象来a訪问了其private成员rotateSpeed,这事实上跟实际中的情况非常像,即发动机从汽车处获得燃料信息,汽车再从发动机处获得转速并显示在仪表盘上。

          综上,非静态内部类可自由訪问外部类包含privated成员在内的全部成员,外部类也可通过创建内部类的对象来訪问其包含private成员在内的全部成员。所以它们尽管在类层面不是相互可见的,可是从广义上来说具有相互可见性,这也是我在题目上打上双引號的原因。

  • 相关阅读:
    iOS开发多线程篇 03 —线程安全
    【Objective-C】01-Objective-C概述
    insert小细节,大问题
    高速修复汉澳sinox命令解释程序bash shell漏洞
    load-on-startup 解释
    研究下JavaScript中的Rest參数和參数默认值
    UVALive 6530 Football (水
    Android多线程分析之五:使用AsyncTask异步下载图像
    POJ2407_Relatives【欧拉phi函数】【基本】
    cocos2d-x 下使用加密 sqlite3
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10715041.html
  • Copyright © 2020-2023  润新知