Java抽象类字段覆盖

Ale*_*lex 11 java overriding field class abstract

我有一个应该实现公共字段的抽象类,这个字段是一个接口或另一个抽象的classe.

这样的事情:

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;
}
Run Code Online (Sandbox Code Playgroud)

现在我有另一个专门的类容器:

public abstract class SpecialContainer extends GenericContainer {
    public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
Run Code Online (Sandbox Code Playgroud)

Java的让我编译这个,和我想象的领域childSpecialContainer被自动重载领域childGenericContainer......这些问题是:我是对这个?孩子的自动"超载"会发生吗?

而且,更重要的问题,如果我有另一个这样的类:

public class ExternalClass {
    public GenericContainer container=new SpecialContainer();
    public int test() {
         return container.child.prop1
    }
}
Run Code Online (Sandbox Code Playgroud)

test()会返回1还是2?我的意思是GenericContainer容器领域prop1将调用什么,通用或特殊?如果特殊的prop1被声明为String(是的,java允许我在这种情况下编译)怎么办?

谢谢!

Abi*_*san 14

在Java中,数据成员/属性不是多态的.重载意味着字段将具有不同的值,具体取决于它访问的类.子类中的字段将隐藏超类中的字段,但两者都存在.根据引用类型调用字段,而方法用于实际对象.你可以自己试试.

它被称为变量隐藏/阴影,有关详细信息,请参见此处


Mau*_*res 11

它不会覆盖任何内容,您只是将原始字段隐藏在当前类范围内.如果您使用带有子类型的变量,您仍然可以访问原始属性.例:

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 );
    }

}
Run Code Online (Sandbox Code Playgroud)

这打印1然后打印2.

SpecialChild你也可以使用super以下方式上升到一个级别:

class SpecialChild extends GenericChild {
    public int prop1=2;

    public int getOriginalProp1() {
        return super.prop1;
    }

}
Run Code Online (Sandbox Code Playgroud)