Tom*_*mmy 48 java static abstract
我刚开始用一个例子来解释它:
public abstract class A{
static String str;
}
public class B extends A{
public B(){
str = "123";
}
}
public class C extends A{
public C(){
str = "abc";
}
}
public class Main{
public static void main(String[] args){
A b = new B();
A c = new C();
System.out.println("b.str = " + b.str);
System.out.println("c.str = " + c.str);
}
}
Run Code Online (Sandbox Code Playgroud)
这将打印出来:
b.str = abc
c.str = abc
但我想要一个解决方案,其中实例化超类的每个子类都有自己的类变量,同时我希望能够通过标识符引用该类变量,或者在抽象超类中定义的方法调用.
所以我希望输出为:
b.str = 123
c.str = abc
那可行吗?
Jon*_*eet 53
如果希望类B和C具有单独的静态变量,则需要在这些类中声明变量.基本上,静态成员和多态性不会在一起.
请注意,通过引用访问静态成员在可读性方面是一个非常糟糕的主意 - 它使它看起来像取决于引用的值,当它不是真的时.因此,当您str
向下移动到B和C 时,您当前的代码甚至都不会编译.相反,您需要
System.out.println("b.str = " + B.str);
System.out.println("c.str = " + C.str);
Run Code Online (Sandbox Code Playgroud)
如果你真的需要以多态方式访问该值(即通过A的实例),那么一个选项就是创建一个多态getter:
public class A {
public abstract String getStr();
}
public class B extends A {
private static String str = "b";
@Override public String getStr() {
return str;
}
}
Run Code Online (Sandbox Code Playgroud)
(和C相同).
这样,您就可以获得所需的行为,而不是每个实例都有一个单独的变量,但您仍然可以多态地使用它.实例成员返回这样的静态值有点奇怪,但你使用的是类型的多态,基本上......
public abstract class A {
private String str;
public String getStr() { return str;}
protected void setStr(String str) { this.str = str; }
}
Run Code Online (Sandbox Code Playgroud)
然后你就能拥有
B b = new B();
b.getStr();
Run Code Online (Sandbox Code Playgroud)
setter和getter是我的补充,你可以简单地使变量非静态.
更新如果您想拥有static-per-subclass,那么您可以拥有:
protected static Map<Class, String> values;
public abstract String getValue();
Run Code Online (Sandbox Code Playgroud)
然后:
public String getValue() {
values.get(getClass());
}
public void setValue(String value) {
values.set(getClass(), value);
}
Run Code Online (Sandbox Code Playgroud)
但这通常是一个坏主意.
将静态变量放入每个子类中,并向抽象超类添加一个(非静态)抽象方法:
abstract String getStr();
Run Code Online (Sandbox Code Playgroud)
然后在每个子类中实现 getStr() 方法,返回这个特殊子类的静态字段。
public class B extends A {
private static String str;
@Override
public String getStr() {
return B.str;
}
}
Run Code Online (Sandbox Code Playgroud)