Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
超类的私有成员是否由子类继承。。。JAVA_Java_Inheritance_Private_Access Control_Access Specifier - Fatal编程技术网

超类的私有成员是否由子类继承。。。JAVA

超类的私有成员是否由子类继承。。。JAVA,java,inheritance,private,access-control,access-specifier,Java,Inheritance,Private,Access Control,Access Specifier,我经历过: 但我还是很困惑 我说的是只继承,不访问。我知道他们在课堂外是看不见的 但是子类的对象是否有它自己的超类中那些私有成员的副本 例如 class Base { private int i; } class Derived extends Base { int j; } 现在, int的大小是4 现在, b的尺寸是4,d的尺寸是8吗 或 d的大小也将仅为4 当然,我说的是堆上的对象,我说的是b和d,而不是引用 更新:我刚刚在SCJP上读到凯西·塞拉和伯特的书。。。它说

我经历过:

但我还是很困惑

我说的是只继承,不访问。我知道他们在课堂外是看不见的

但是子类的对象是否有它自己的超类中那些私有成员的副本

例如

class Base {
    private int i;
}

class Derived extends Base {
    int j;
}
现在,

int的大小是4

现在,

b的尺寸是4,d的尺寸是8吗

d的大小也将仅为4

当然,我说的是堆上的对象,我说的是b和d,而不是引用


更新:我刚刚在SCJP上读到凯西·塞拉和伯特的书。。。它说他们不是继承的。。。。我发布了这个更新,因为仍然有很多人说是…

是的,子类的实例将有父类的私有字段的副本


但是,它们对于子类是不可见的,所以访问它们的唯一方法是通过父类的方法。

是的,派生类将具有基类的私有字段。若派生类定义了公共getter和setter,那个么您就可以从使用它的派生类中使用该字段

意志 b的大小是4 d的大小是8 或 d的大小也将仅为4


它是Java,而不是C。您无法轻松估计堆中对象的大小。它将大于4或8个字节。

两者都不-对象的大小包括一些开销。但是,派生将占用比基更多的空间

运行一个快速测试,看起来基本的大小大约是20字节,派生的大小大约是28字节。请注意,这些结果可能在不同的JVM上有所不同

public static void main(String[] args) throws InterruptedException {
    int size = 500000;
    double mem;

    mem = Runtime.getRuntime().freeMemory();
    Base[] base = new Base[size];
    for (int i = 0; i < size; i++) {
        base[i] = new Base();
    }
    System.out.println((mem - Runtime.getRuntime().freeMemory()) / size);

    System.gc();
    Thread.sleep(100);
    System.gc();

    mem = Runtime.getRuntime().freeMemory();
    Derived[] derived = new Derived[size];
    for (int i = 0; i < size; i++) {
        derived[i] = new Derived();
    }
    System.out.println((mem - Runtime.getRuntime().freeMemory()) / size);
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
int size=500000;
双膜;
mem=Runtime.getRuntime().freemory();
基准[]基准=新基准[尺寸];
对于(int i=0;i
由于JVM规范,
文件的构建方式如下:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}
super\u class
字段包括:

`对于类,super_类项的值必须为零,或者必须是常量_池表中的有效索引。如果super_类项的值为非零,则该索引处的常量_池项必须是常量_class_info(§4.4.1)结构,表示该类文件定义的类的直接超类。直接超类或其任何超类都不能在其类文件结构的access_flags项中设置ACC_FINAL标志

如果super_类项的值为零,则该类文件必须表示类对象,即唯一没有直接超类的类或接口

对于接口,super_类项的值必须始终是常量_池表中的有效索引。该索引处的常量池项必须是表示类对象的常量类信息结构`

更有趣的是
字段[]
部分:

字段表中的每个值必须是一个字段信息(§4.5)结构,给出此类或接口中字段的完整描述。fields表仅包括由此类或接口声明的字段。它不包括表示从超类或超接口继承的字段的项。

因此编译的类不包含继承的字段。另一方面,当创建对象时,
private
超级字段在内存中。为什么?让我们想象一下这个例子:

 classs A {
      int a;

      A(int a) {
          this.a = a;
      }

      void methodA() {
          System.out.println("A is: " + a);
      }
 }

 classs B extends A {
      int b;

      B(int b) {
          super(10);
          this.b = b;
      }

      void methodB() {
          super.methodA();
          System.out.println("B is: " + b);
      }
 }

输出应该是:
A is:10\n B is…

否,私有字段设计为可在其声明的类上访问。在类(包括派生类)之外访问它们的唯一方法是通过公共方法

如果要使基类中的成员由派生类继承,请使用“protected”而不是private。代码应为:

class Base {
  protected int i;
}

class Derived extends Base {
  int j;
}

“受保护”访问修饰符允许继承成员并为其分配自己的访问修饰符。

private
成员不是继承的,而是存在于父级(超级)中的实例化对象中。你的问题实际上是关于阴影的(我认为?你似乎在谈论对象的大小,这在Java中不适用)。请参阅:您能否提供确切的文本说明它们不是继承的?我认为在这一点上,术语上存在混乱。根据Java规范,子类不会“继承”其超类的私有成员,但它使用了非常严格的继承概念,这对Java规范很有用。该子类的实例肯定会有自己的thoes memebrs实例。因此,从这个意义上讲,您的问题中使用的意义是继承的。@Nimrand确切的文本是:
当一个成员被声明为私有时,子类不能继承它。
在第1章“声明和访问控制”的私有成员一节中,您完全正确。。。但是我们讨论的是继承它们,而不是访问它们。在这种情况下,如果要将基类成员继承到派生类,请将基类中的成员声明为“受保护”老实说,这个详细的解释有点过于复杂,无法回答最初的问题,但它提供了有关Java内部工作原理的大量信息+说明中的类标题结构为1。
class Base {
  protected int i;
}

class Derived extends Base {
  int j;
}