【问题标题】:How these two inner class objects differ? [duplicate]这两个内部类对象有何不同? [复制]
【发布时间】:2018-01-29 17:35:10
【问题描述】:

我正在尝试培养对内部类的直觉和熟悉度。
我正在研究这个 java 的主题,经过一些研究,我开始练习。
我想出了这段代码,它的行为方式我无法理解。
我创建了一个带有公共内部类 Inner 的类 Example
Example 类中,我创建了 Innerobj 的对象,在 MainClass 类中,在main 函数我创建了另一个 Inner 类实例(在创建封闭类的实例之后)。
示例类代码:

    public class Example {

    Inner obj = new Inner(9);

    class Inner {
        public int x;

        public Inner(int a) {
            x=a;
        }   
    }

}

主类:

public class MainClass{
     public static void   main ( String args[] ) {

            Example example = new Example();
            System.out.println(example.obj.x); // output 9
            Example.Inner obj = example.new Inner(10);
            System.out.println(obj.x); //output 10
            System.out.println(example.obj.x); // output 9
            }
     }

鉴于语句Inner obj= new Inner() 和语句Example.Inner obj = example.new Inner(10) 都声明了同名的Inner 类的对象,我不明白这怎么没有问题。 我认为这与它们在内存中的存储方式有关,但它们似乎是两个完全不同的东西,但我不明白如何。

更新: 到目前为止,答案都很好,我编辑了更改代码并将构造函数数量减少到一个的问题。这应该可以澄清我的疑虑。

【问题讨论】:

  • obj in mainobj in Example 没有关系。如果我的名字是Gabriele,我们不是同一个人吗?或者只是有一个相同的名字而没有进一步的关系?
  • 两个变量的作用域完全不同。一个是main方法的局部变量。另一个是示例字段。想象一下,如果每个循环 for (int i = 0; i < N; i++) 没有编译,因为其他一些不相关的代码也使用了一个名为 i 的变量。那将是无法管理的,不是吗?
  • 请对解释投反对票,至少我可以尝试编辑!投票对我很重要,我对这个问题进行了研究,我可能会因为有人投反对票而被禁止 6 个月!
  • 这怎么可能是我连作文都没学过的问题的重复!?
  • 为了培养直觉和熟悉内部类,不要在其封闭类之外创建它们。 Example.Inner obj = example.new Inner(10); 不是典型用法。仅当您需要访问封闭类的私有字段和方法(未在您的示例中给出)时才使用内部类。内部类应该是其封闭类内部的实现助手,而不是您打算在外部使用的东西。

标签: java oop inner-classes


【解决方案1】:

您有两个Inner 类的实例,虽然两个实例的名称相同obj,但它们是相互独立的。在main 方法之外定义的Inner 类实例是使用default constructor 创建的。所以example.obj.x 输出6

Inner 类实例 objmain 方法中定义是使用 parameterized constructor 创建的,所以 obj.x 输出 10。

这里重要的是当你做example.obj.x时,你指的是Inner类的实例在main方法之外创建,当你做obj.x时,你指的是Inner 类实例在主方法中创建Inner 的这两个实例是完全独立的。

编辑

到目前为止,答案都很好,我编辑了问题,更改了 代码并将构造函数的数量减少到一个。这应该 澄清我的疑虑。

拥有一两个构造函数不会改变任何事情。在main 方法外部定义的Inner 类实例和在main 方法内部定义的一个实例是Inner 类的两个独立实例。

x,在main 外部定义的Inner 实例的数据成员具有9 的值,并且只能使用Example 类的实例example 访问。因此example.obj.x 输出9

main 中定义的Inner 实例可以使用在main 中定义的obj 直接访问,其x 的值为10。因此obj.x 输出10

【讨论】:

  • 那么main方法中创建的实例不是外部类中的字段吗?也不是 sublcas ,它只是一个实例,就像一个非内部类(在另一个文件中定义),它可以访问外部的所有成员和方法,并且只有在创建外部实例时才能创建。那正确吗? :)
  • @GabrieleScarlatti 检查编辑后的答案,希望它能帮助您更好地理解您的代码。
  • 那么main方法中创建的实例不是外部类中的字段吗?也不是 sublcas ,但它只是一个实例。对吗?是的,没错。
  • 感谢您的帮助!最后一件事:这个先前的想法是否也正确“就像一个非内部类(在另一个文件中定义)可以访问外部的所有成员和方法,并且只有在创建外部实例时才能创建。是对吗?”我需要明白我是否真的明白!
  • 类的每个实例都可以访问其 public 数据成员和 public 方法,并且可以使用该实例在另一个类中访问它们班级。 private 方法或数据成员只能在该类中直接访问。
【解决方案2】:

您创建了两个对象:exampleExample 的一个实例,和objExample.Inner 的一个实例。这两个对象没有任何关系,也不共享任何信息,所以每个对象中的x字段可以持有不同的int

【讨论】:

  • 我也在 E​​xample 中创建了一个 Inner 的实例,不是吗?
  • 是的,您使用Example 中的隐式构造函数创建了Inner 的实例,但是example 中的obj 与您手动创建的obj 无关。它们是不同的对象;您可以根据需要创建任意数量的Inners,并在每个int x 中放置不同的int x
  • 如果您在Example.Inner obj = example.new Inner(10); 行中为您创建的对象使用不同的名称,事情可能会更清楚。如果你改用Example.Inner myObj = example.new Inner(10); 怎么办?那么你不会期望myObjexample 中的obj 拥有相同的int,对吧?仅仅因为这两个事物具有相同的名称并不能使它们成为同一个对象。
【解决方案3】:

不管你有一个内部类,你有两个完全不同的Inner实例。

由于Inner 的构造函数将6 分配给xexample.obj.x 被赋值为 6。

obj 正在实例化一个新实例(因此使用了关键字 new),然后它为其构造函数传入值 10。

这就是为什么你会得到两个不同的值;因为这两个实例是完全分开的,并且彼此之间没有共享值(即静态字段),所以值会不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-19
    • 2011-08-29
    • 2019-09-09
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多