我认为我的代码错误地使用了静态成员。
下面是一个例子。变量类型和名称可能没有意义。
public class subclass extends superclass {
private static Boolean varBool = new Boolean(true);
private static Double varDoub = new Double(4.3);
private static CustomType varCustom = new CustomType(varBool, varDoub);
public subclass() { super(varCustom); }
}
我认为这是对静态的错误使用。我看到作者想定义可以传递给超类的默认值,并使用 static 来实现。使用此类的方式,我相信不会引起问题,因为值没有改变,但现在我希望它们用于不同的实例。
我正在考虑使用静态方法来定义这些默认值。
public class subclass extends superclass {
public subclass() { super(getVarCustom()); }
private static getVarBool() { return new Boolean(true); }
private static getVarDoub() { return new Double(4.3); }
private static getVarCustom() { return new CustomType(getVarBool(), getVarDoub()); }
}
这将允许我通过将值传递给新的构造函数来更改默认值,而不影响其他实例。
例如:
public class subclass extends superclass {
public subclass() { super(getVarCustom()); }
public subclass(double dub) { super(getVarCustom(dub)); }
private static getVarBool() { return new Boolean(true); }
private static getVarDoub() { return new Double(4.3); }
private static getVarCustom() { return new CustomType(getVarBool(), getVarDoub()); }
private static getVarCustom(double dub) { return new CustomType(getVarBool(), dub); }
}
我想这并不完美,但我试图通过不改变其他类使用此类的方式来尽量减少对代码库的影响。
这样做可以吗,还是我误会了什么?
你想要的是行不通的。静态方法不“做”继承。您最好将静态方法视为完全存在于类之外。
在 java 中,类(好吧,类型)有两个角色。当然,它们定义类型,但是,它们还有另一个角色,即命名空间。它是具有完全限定名称空间的类型(它们存在于一个包中,因此,您可以有两个名为
Foo
的类,java 允许您通过包进行区分)。然后方法存在于inside 一个中,因此,您可以完全限定类这一事实意味着方法也具有名称空间。这就是 java 解决 cameragun 问题的方法(相机和枪都有 shoot(Person p)
方法,但是,你不会想混淆的!)。
因此,静态方法必须在类中。但它们不继承,不像实例方法——你不能“覆盖”静态方法:
class Parent {
Parent() {
System.out.println("This is the result of foo: " + foo());
}
static String foo() {
return "in parent";
}
}
class Child extends Parent {
static String foo() {
return "in child";
}
}
new Child();
将打印in parent,显示你如何cannot“覆盖”静态方法。
正因为如此,不可变字段的解决方案更简单、更清晰,所以,你应该坚持你已经拥有的。但是,请注意您的静态常量没有标记
final
这意味着您现在拥有全局可变状态。如果您喜欢可维护的代码,那么您不希望那样。标记他们final
。并且,使它们成为 ALL_CAPS
(“常量”的 java 约定 - 避免必须记录“这些应该是不可变的类型”,因为全大写暗示它)。
如果你想要扩展式的东西作为构建工作的一部分,这就是工厂的用途。工厂是一种机制,通过它你可以赋予类的
static
方面(构造函数 是静态的,从某种意义上说,你不需要有一个类的实例来调用一个类,它们也不会“继承”/不能被覆盖):
class ParentFactory {
public double defaultFooVal() {
return 2.0;
}
public Parent create() {
return new Parent(defaultFooVal());
}
class ChildFactory extends Parent {
@Override public double defaultFooVal() {
return 3.0;
}
}
ParentFactory f = new ChildFactory();
Parent p = f.create();
System.out.println(p.getFooVal());
会打印
3.0
如你所愿。