超类的私有成员是否由子类继承。。。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;
}