Java抽象类字段重写
我有一个抽象类,它应该实现一个公共字段,这个字段是一个接口或另一个抽象类 大概是这样的:Java抽象类字段重写,java,class,overriding,field,abstract,Java,Class,Overriding,Field,Abstract,我有一个抽象类,它应该实现一个公共字段,这个字段是一个接口或另一个抽象类 大概是这样的: public abstract class GenericContainer { public GenericChild child; } public abstract class GenericChild { public int prop1=1; } public abstract class SpecialChild extends GenericChild { publ
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extends GenericChild {
public int prop1=2;
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
现在我有了另一个专门的类容器:
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
Java允许我编译这个,我想象SpecialContainer
中的字段child
会自动重载GenericContainer的字段child
。。。
问题是:
我说的对吗?孩子会自动“超载”吗
还有一个更重要的问题,如果我有另外一节课,像这样:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extends GenericChild {
public int prop1=2;
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
test()
将返回1或2?我指的是GenericContainer
container字段prop1
将调用什么,通用还是特殊?
如果特殊的prop1被声明为String(是的,java允许我在这种情况下也编译),会怎么样
谢谢 关于
…我想象SpecialContainer中的字段“child”会自动重载GenericContainer的字段“child”
不会。字段不会被重写,只有方法会被重写
这就是为什么优先使用(可重写的)getter和setter方法而不是直接访问字段的原因之一。您的字段几乎都应该是私有的
至于您的设计,您的SpecialContainer类不需要有SpecialChild字段,而是应该将SpecialChild对象放置在GenericChild字段中
Java允许我编译这个,我认为
SpecialContainer正在自动重载
通用容器
首先,继承性不适用于变量。字段(Insatnce变量)不会在子类中被重写。只有在子类中用public、protected或default
标记时,字段才可见。在Java中,数据成员/属性不是多态的。重载意味着字段将具有不同的值,具体取决于访问它的类。子类中的字段将隐藏超类中的字段,但两者都存在根据引用类型调用字段,而方法用于实际对象。你可以自己试试
它被称为变量隐藏/阴影,有关更多详细信息,请查看它没有覆盖任何内容,您只是在当前类范围中隐藏原始字段。如果将变量与子类型一起使用,则仍可访问原始属性。例如:
abstract class GenericContainer {
public GenericChild child;
}
abstract class GenericChild {
public int prop1=1 ;
}
class SpecialChild extends GenericChild {
public int prop1=2;
}
class SpecialContainer extends GenericContainer {
public SpecialChild child;
}
public class Main {
public static void main( String ... args ) {
GenericContainer container = new SpecialContainer();
container.child = new SpecialChild();
System.out.println( container.child.prop1 );
SpecialChild child = (SpecialChild) container.child;
System.out.println( child.prop1 );
}
}
这将打印1,然后打印2
从SpecialChild
您还可以使用super
升级一级:
class SpecialChild extends GenericChild {
public int prop1=2;
public int getOriginalProp1() {
return super.prop1;
}
}
为了回答您的问题,它维护两个实例。根据引用容器的方式(通过抽象或impl)确定引用的变量
public class Test {
public abstract class Container{
public Generic gen = new Generic();
}
public class ContainerImpl extends Container{
public GenericImpl gen = new GenericImpl();
}
public class Generic{
public int prop = 0;
}
public class GenericImpl extends Generic{
public int prop = 1;
}
public Test(){
Container c = new ContainerImpl();
System.out.println(c.gen.prop); // Outputs "0"
System.out.println(((ContainerImpl)c).gen.prop); // Output "1"
}
public static void main(String[] args) {
new Test();
}
}
眼前更大的问题是,你为什么要设计这样的东西?我想你是从理论的角度问的
我的2美分,这不是很好的OO设计。最好将公共变量设为私有变量,并通过构造函数或属性设置器分配它们的值。实际上,它会在代码中导致意外的结果。为什么没有人注意到该程序将抛出NullPointerException
具有相同名称的子类的字段
将隐藏超类的字段
。没有使用字段覆盖。只有使用方法才能重写
作者的原始代码:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extend GenericChild {
public int prop1=2;
}
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
不。字段不会被重写,只有方法会被重写。因此,如果在“SpecialChild”中我有一个使用prop1的方法,它在第一次调用时会得到什么?1还是2?我尝试过,从SpecialChild中删除prop1将允许我在SpecialChild中编写一个也使用prop1的方法,如果它仅在GenericChild中定义。。。所以我认为会发生一种过载……您可以尝试运行它。上面的程序抛出“NullPointerException”。对于您提出的问题,其答案是字段不能被覆盖。如果在子类中定义了相同的字段名,则子类字段将隐藏超类的字段。@AmitG yes,因为在GenericContainer中我没有初始化泛型子类。在我的整个项目中,它起了作用。