处理静态变量时棘手的继承问题
Tricky inheritance issue when dealing with static variables
我的理解是,在 Java 继承带有静态变量的父 class 意味着静态变量将简单地在父子 classes 之间共享,并试图“覆盖”静态变量只会导致隐藏它们。
我已经在我的项目中定义了 class A,其中的函数使用了 class A 中定义的静态变量。我想创建一个非常相似的 class-- class B--这样它将具有相同的功能(无需通过将功能复制粘贴到 class B 文件中来复制功能的代码),但功能使用定义的静态变量在 class B.
如果我在扩展 class A 后简单地尝试“覆盖”静态变量,函数(即使通过 class B 的实例调用)仍将简单地使用 class A(而不是 class B)由于“隐藏”。有没有办法不重复函数的代码并共享逻辑(引用静态变量)但仍以某种方式满足以下要求?
- 继续使用静态变量
- 不要 add/force 对静态变量使用 getter 方法,因为强制使用 getter 方法意味着将来对代码的更改需要记住使用 getter 方法而不是直接使用变量。例如,如果我们以这种方式实现它,然后有人添加了一个直接使用静态变量(而不是使用 getter 方法)的新函数(比如
newFunction()
),那么 class B 会现在使用 class A 的静态变量(因为未使用 getter 方法)当 class B 调用 newFunction()
时。
public class A {
public static String CONSTANT_1 = "Some information";
public static String CONSTANT_2 = "More information";
public static String CONSTANT_3 = "Something Something";
public static String CONSTANT_4 = "More stuff, more stuff";
public void doSomething() {
// do something with CONSTANT_1
}
public void doSomething2() {
// do something with CONSTANT_2
}
public void doSomething3() {
// do something with CONSTANT_3
}
// ...
}
public class B extends A {
public static String CONSTANT_1 = "abc";
public static String CONSTANT_2 = "def";
public static String CONSTANT_3 = "ghi";
public static String CONSTANT_4 = "jkl";
// don't want to repeat all the logic in the functions in class A,
// want to somehow inherit or share code for functions between classes A and B,
// but have different static variables being used in the functions
}
到目前为止我考虑过但还不完全满意的地方:
转换为 Kotlin(不确定继承效果如何,静态被伴随对象替换)
使用 getter 方法,如 post
中所述
使用非静态而不是静态(尝试看看我们是否可以保持变量静态)
我会将成员变量和方法定义为抽象 class 的 non-static 成员。然后在A中暴露一个抽象class的单例实例,你可以这样使用:
A.getInstance().doSomething();
然后在 B 中,您可以公开抽象 class 的子 class 的单例实例。
在 Kotlin 中,这看起来会更简洁一些。您可以使 A 和 B 都成为扩展相同抽象 class 的 object
。或者,如果 A 或 B 也是常规 class,则给它们扩展抽象 class.
的伴生对象
如果你想让变量保持静态,你可以让 classA 中的方法接受变量作为参数。
要在不创建 class 的对象的情况下使用这些方法,也将这些方法设为静态。
public static void doSomething(String one) {
// do something with CONSTANT_1
System.out.println(one);
}
同样的方法也可以,
A.doSomething(A.CONSTANT_1);
A.doSomething(B.CONSTANT_1);
我的理解是,在 Java 继承带有静态变量的父 class 意味着静态变量将简单地在父子 classes 之间共享,并试图“覆盖”静态变量只会导致隐藏它们。
我已经在我的项目中定义了 class A,其中的函数使用了 class A 中定义的静态变量。我想创建一个非常相似的 class-- class B--这样它将具有相同的功能(无需通过将功能复制粘贴到 class B 文件中来复制功能的代码),但功能使用定义的静态变量在 class B.
如果我在扩展 class A 后简单地尝试“覆盖”静态变量,函数(即使通过 class B 的实例调用)仍将简单地使用 class A(而不是 class B)由于“隐藏”。有没有办法不重复函数的代码并共享逻辑(引用静态变量)但仍以某种方式满足以下要求?
- 继续使用静态变量
- 不要 add/force 对静态变量使用 getter 方法,因为强制使用 getter 方法意味着将来对代码的更改需要记住使用 getter 方法而不是直接使用变量。例如,如果我们以这种方式实现它,然后有人添加了一个直接使用静态变量(而不是使用 getter 方法)的新函数(比如
newFunction()
),那么 class B 会现在使用 class A 的静态变量(因为未使用 getter 方法)当 class B 调用newFunction()
时。
public class A {
public static String CONSTANT_1 = "Some information";
public static String CONSTANT_2 = "More information";
public static String CONSTANT_3 = "Something Something";
public static String CONSTANT_4 = "More stuff, more stuff";
public void doSomething() {
// do something with CONSTANT_1
}
public void doSomething2() {
// do something with CONSTANT_2
}
public void doSomething3() {
// do something with CONSTANT_3
}
// ...
}
public class B extends A {
public static String CONSTANT_1 = "abc";
public static String CONSTANT_2 = "def";
public static String CONSTANT_3 = "ghi";
public static String CONSTANT_4 = "jkl";
// don't want to repeat all the logic in the functions in class A,
// want to somehow inherit or share code for functions between classes A and B,
// but have different static variables being used in the functions
}
到目前为止我考虑过但还不完全满意的地方:
转换为 Kotlin(不确定继承效果如何,静态被伴随对象替换)
使用 getter 方法,如 post
中所述使用非静态而不是静态(尝试看看我们是否可以保持变量静态)
我会将成员变量和方法定义为抽象 class 的 non-static 成员。然后在A中暴露一个抽象class的单例实例,你可以这样使用:
A.getInstance().doSomething();
然后在 B 中,您可以公开抽象 class 的子 class 的单例实例。
在 Kotlin 中,这看起来会更简洁一些。您可以使 A 和 B 都成为扩展相同抽象 class 的 object
。或者,如果 A 或 B 也是常规 class,则给它们扩展抽象 class.
如果你想让变量保持静态,你可以让 classA 中的方法接受变量作为参数。
要在不创建 class 的对象的情况下使用这些方法,也将这些方法设为静态。
public static void doSomething(String one) {
// do something with CONSTANT_1
System.out.println(one);
}
同样的方法也可以,
A.doSomething(A.CONSTANT_1);
A.doSomething(B.CONSTANT_1);