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成员在内的所有成员,不过注意必须是外部类的实例成员才行,而不能在外部类的静态成员(包括静态方法和静态初始化块)中使用非静态内部类,原因很简单:非静态内部类可看作是外部类的一个实例成员,而静态成员不能访问实例成员。如下例所示:

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成员在内的所有成员,所以它们虽然在类层面不是相互可见的,但是从广义上来说具有相互可见性,这也是我在题目上打上双引号的原因。

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

时间: 2024-12-14 05:00:21

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

139、Java中使用this访问外部类属性

01.代码如下: package TIANPAN; class Outer { // 外部类 private String msg = "Hello World !"; class Inner { // 定义一个内部类 public void print() { System.out.println(Outer.this.msg); // 外部类.this = 外部类当前对象 } } public void fun() { Inner in = new Inner(); // 内部类对

深入理解Java中为什么内部类可以访问外部类的成员

内部类简介 虽然Java是一门相对比较简单的编程语言,但是对于初学者, 还是有很多东西感觉云里雾里, 理解的不是很清晰.内部类就是一个经常让初学者感到迷惑的特性. 即使现在我自认为Java学的不错了, 但是依然不是很清楚.其中一个疑惑就是为什么内部类对象可以访问外部类对象中的成员(包括成员变量和成员方法)? 早就想对内部类这个特性一探究竟了,今天终于抽出时间把它研究了一下. 内部类就是定义在一个类内部的类.定义在类内部的类有两种情况:一种是被static关键字修饰的, 叫做静态内部类, 另一种是

java 内部类如何访问外部类的对象

用this就可以做到 实例如下: package innerclass; /** * 内部类如何得到外部类的对象 *  * */ public class DotThis { public class Inner { //返回外部内的对象 public DotThis outer(){ return DotThis.this; } } public void print(){ System.out.println("Out class"); } /** * 得到内部内的对象 */ pu

java中内部类的创建四种情况,三种方式,及内部数据访问权限

内部类和外部类的关系,及内部静态类的数据访问权限,声明方式. 第一种,在外部类内部声明使用内部类,内部类的类型为static和非 static类型,内部类数据类型为private,protected,public 类型的访问权限.外部类为非静态声明和权限如下: package com; public class Test1 { //@author 张春蕾 private class Name{ private int i =1; public int s = 2; protected int m

Java中内部类

内部类的规则: 1.内部类可以直接访问外部类中的成员,包括私有. 之所以可以直接访问外部类中的成员,是因为内部类中持有一个外部类的引用,格式:外部类名.this 2.外部类要访问内部类,必须建立内部类对象 访问格式: 1.当内部类定义在外部类的成员位置了,而且非私有,可以在外部其他类中. 可以直接建立内部类对象. 格式: 外部类类名.内部类名  变量名= new 外部类对象.new 内部类对象. Outer.inner out = new Outer().new inner(); 2.当内部类在

java 第44节 引用外部类的对象

2016-06-30 package com.java1995; /** * 1.引用外部类的对象 * Inner: this.count * Outer:Outer.this.count * @author Administrator * */ //外部类 public class Outer { private int count =1 ; //内部类 class Inner{ private int count = 2; //内部类的方法 public void print(int cou

java中内部类的积累

放在一个类的内部的类我们就叫内部类. 二. 作用 1.内部类可以很好的实现隐藏 一般的非内部类,是不允许有 private 与protected权限的,但内部类可以 2.内部类拥有外围类的所有元素的访问权限 3.可是实现多重继承 4.可以避免修改接口而实现同一个类中两种同名方法的调用. 提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就是在类中又定

关于Java中内部类的一些概念整理

把一个类放到另一个类的内部定义,这个定义在其他类内部的类就被称为内部类. 内部类的作用: (1).内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类. (2).内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问.但外部类不能访问内部类的实现细节. (3).匿名内部类适用于创建那些仅需要一次使用的类. (4).内部类比外部类可以多使用三个修饰符:private.protected.static--外部类不可以使用

JavaSE8基础 内部类可以访问外部类的私有成员

os :windows7 x64    jdk:jdk-8u131-windows-x64    ide:Eclipse Oxygen Release (4.7.0)        代码: //内部类 就是在一个类的内部在定义一个类 //外部类 class TestOuter { private int num = 10; //内部类 private class TestInner { public void showInner() { //内部类可以访问外部类的私有成员 System.out.