Java 扩展类中的访问属性/常量

Java 扩展类中的访问属性/常量,java,inheritance,Java,Inheritance,我正在努力实现以下目标: 我有一个父类,带有一些逻辑。在子类中,我“重新定义”常量/属性。有没有办法让父类中定义的方法可以访问子属性?或者更具体地说,在下面的示例中,有没有办法强制“out”方法编写extended而不是base public class BaseTest { public static final String x = "base"; public void out() { System.out.println(x); } } pub

我正在努力实现以下目标:

我有一个父类,带有一些逻辑。在子类中,我“重新定义”常量/属性。有没有办法让父类中定义的方法可以访问子属性?或者更具体地说,在下面的示例中,有没有办法强制“out”方法编写extended而不是base

public class BaseTest {
    public static final String x = "base";

    public void out() {
        System.out.println(x);
    }
}

public class ExtendedTest extends BaseTest{
    public static final String x = "extended";
}

public class Main {
    public static void main(String[] args) {
        BaseTest base = new BaseTest();
        ExtendedTest extended = new ExtendedTest();
        base.out(); // base (as expected)
        extended.out(); // base (extended expected)
        System.out.println(extended.x); // extended (as expected)
    }
}
我主要来自PHP世界,在那里这种方法工作得很好。不知道我是否遗漏了什么,或者Java的设计本身不允许这样做

多谢各位


注意:无论属性是否为静态,这都不重要。我只是希望能够重写子类中的任何类型的属性(就像我可以重写方法一样),根据我迄今为止收到的答案,这在Java中似乎是不可能的。在PHP中,这是绝对可能的,这就是我问这个问题的原因。

静态
字段不受继承的约束。out()方法体中的
x
指的是
BaseTest.x
。由于您没有重写
out()
,因此
out()
方法的主体仍然打印
BaseTest.x
静态
字段不受继承。
out()方法主体中的
x
引用
BaseTest.x
。由于您没有重写
out()
,因此
out()
方法的主体仍然打印
BaseTest.x
静态成员的值在编译时解析,并且添加
ExtendedTest.x
不会影响同样存在的
BaseTest.x
,这就是
BaseTest\out()的内容
方法已链接到

要实现您想要的,您需要一个重写的方法:

public class BaseTest {
    public String x() {
        return "base";
    }

    public final void out() {
        System.out.println(x());
    }
}

public class ExtendedTest extends BaseTest {
    @Override
    public String x() {
        return "extended";
    }
}

此模式通常与基类或接口中的抽象方法一起使用,以要求子类定义名称或键等属性。

静态成员在编译时解析,并且添加
ExtendedTest.x
不会影响现有的
BaseTest.x
,这就是
BaseTest\out()的功能
方法已链接到

要实现您想要的,您需要一个重写的方法:

public class BaseTest {
    public String x() {
        return "base";
    }

    public final void out() {
        System.out.println(x());
    }
}

public class ExtendedTest extends BaseTest {
    @Override
    public String x() {
        return "extended";
    }
}

此模式通常与基类或接口中的抽象方法一起使用,以要求子类定义名称或键等属性。

为什么该字段仍然是静态字段?最简单的修复方法是使用一个局部字段(不是静态的)和一个返回该字段值的抽象方法。顺便说一句,可能的重复应该遵守Java命名约定:常量(
static final
variables)应该在大写字母SNAKE\u CASE.Malis中,术语在这里非常重要:在Java中,属性由getter和/或setter方法定义,而不是由字段(成员变量)定义;某些属性甚至没有支持字段,但会在需要时进行计算。字段访问(无论是静态还是实例)在编译时解析,因此直接字段引用不会受到重新声明另一个同名字段的影响。方法在Java中用于此目的,句号。为什么它是一个静态字段?最简单的修复方法是使用一个局部字段(不是静态的)和一个返回该字段值的抽象方法。顺便说一句,可能的重复应该遵守Java命名约定:常量(
static final
variables)应该在大写字母SNAKE\u CASE.Malis中,术语在这里非常重要:在Java中,属性由getter和/或setter方法定义,而不是由字段(成员变量)定义;某些属性甚至没有支持字段,但会在需要时进行计算。字段访问(无论是静态还是实例)在编译时解析,因此直接字段引用不会受到重新声明另一个同名字段的影响。方法在Java period中用于此目的。如上文所述,它不是关于是否是静态的,而是关于在父级/子级中定义的。换句话说,是否有可能在父类中创建基本逻辑,并反映在子类中实现的逻辑更改?如上所述,它不是静态的,也不是静态的,而是在父/子类中定义的。换句话说,是否可以在父类中创建基本逻辑并反映在子类中实现的更改?这正是我想要避免的。但是,只要我的“PHP方法”看起来不可能使用,我就只能在没有它的情况下生活:)无论如何,谢谢你的澄清。@Malis如果你能更详细地解释你实际上要做的任务,我们也许能够帮助展示更地道的Java。一般来说,属性是从超类(
BaseTest#getX()
)透明继承的,如果属性的值需要更改,可以使用setter进行更改。注释有点短,但我会尝试。假设我有一辆基本级的车和一辆扩展级的车。车辆有一个“feature”wheels(这可能是一个普通属性,但在PHP中通常是一个常量;在Java中不存在常量,因此是静态的final…)在PHP中,基类可以通过
static::wheels
访问“shared”常量,子类只包含
类Car extensed Vehicle{const wheels=4;}
它不需要特殊的构造函数,不需要重写方法,只需要一行,整个逻辑都在基类中。我在Java中寻找类似的行为。@Malis您可以重写方法或定义属性
wheels
,并在
Car
构造函数中设置其值。这正是我想要避免的。但是,只要我的“PHP方法”看起来不可能使用,我就只能在没有它的情况下生活:)无论如何,谢谢你的澄清。@Malis,如果你能更详细地解释你要完成的任务的话