我需要一个将在子类中使用的类中的方法,尽管该方法使用的属性在子类中已更改。有没有一种方法可以访问子类的属性而不必重写该方法?
我已经尝试过使用该属性的getter方法,但是得到了相同的结果。
public class SuperClass {
private static final String a = "Super";
public void superMethod(){
System.out.println("SuperMethod: " + a);
}
}
public class ChildClass extends SuperClass {
private static final String a = "Child";
}
public class Main {
public static void main(String[] args) {
SuperClass s = new SuperClass();
ChildClass c = new ChildClass();
s.superMethod();
c.superMethod();
}
}
控制台显示:
SuperMethod:超级
SuperMethod:超级
预期结果是:
SuperMethod:超级
SuperMethod:孩子
答案 0 :(得分:5)
我已经尝试过使用该属性的getter方法,但是得到了相同的结果。
确定吗?以下应该正是您所追求的:
class SuperClass {
private String a = "Super";
public void superMethod() {
System.out.println("SuperMethod: " + getA());
}
public String getA() {
return this.a;
}
}
class ChildClass extends SuperClass {
private String a = "Child";
@Override
public String getA() {
return this.a;
}
}
public class Main {
public static void main(String[] args) {
SuperClass s = new SuperClass();
ChildClass c = new ChildClass();
s.superMethod();
c.superMethod();
}
}
请注意,getter不能是私有的(否则它们不能从类外部访问),并且不能是静态的(否则它们是类的一部分,而不是该类的任何实例)。 )
答案 1 :(得分:1)
不清楚您在做什么,但是您的String a
成员是该类的private static
成员,而不是单个对象的成员。
如果使String a
成为对象的成员而不是类的成员,则可以在创建子类的过程中覆盖该值:
U:\>jshell
| Welcome to JShell -- Version 12
| For an introduction type: /help intro
jshell> class SuperClass {
...> protected final String a;
...>
...> protected SuperClass(String _a) {
...> a = _a;
...> }
...>
...> public SuperClass() {
...> this("Super");
...> }
...>
...> public void superMethod() {
...> System.out.println("SuperMethod: "+a);
...> }
...> }
| created class SuperClass
jshell> class ChildClass extends SuperClass {
...> public ChildClass() {
...> super("Child");
...> }
...> }
| created class ChildClass
jshell> var s = new SuperClass();
s ==> SuperClass@4566e5bd
jshell> var c = new ChildClass();
c ==> ChildClass@ff5b51f
jshell> s.superMethod();
SuperMethod: Super
jshell> c.superMethod();
SuperMethod: Child
更新
现在我们知道了您的实际用例(从下面的评论中),您想要实现的内容非常简单:
class SuperClass {
private final static Logger LOG = Logger.getLogger(SuperClass.class);
protected Logger getLogger() { return LOG; }
public void superMethod(){
getLogger().info("superMethod() called.");
}
}
class ChildClass extends SuperClass {
private final static Logger LOG = Logger.getLogger(ChildClass.class);
@Override
protected Logger getLogger() { return LOG; }
}
public class Main {
public static void main(String[] args) {
SuperClass s = new SuperClass();
ChildClass c = new ChildClass();
s.superMethod(); // Message logged to SuperClass.LOG
c.superMethod(); // Message logged to ChildClass.LOG
}
}
答案 2 :(得分:0)
简短的答案:Java无法按照您想要的方式进行操作,因为编译器会将String常量与最终值合并,因此"SuperMethod: " + a
将在生成的字节码中转换为"SuperMethod: Super"
。
唯一的解决方案是使用反射(如果需要):
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) {
SuperClass s = new SuperClass();
ChildClass c = new ChildClass();
s.superMethod();
c.superMethod();
}
}
class SuperClass {
private static final String a = "Super";
public void superMethod(){
try{
final Class<?> clazz = this.getClass();
final Field fieldA = clazz.getDeclaredField("a");
fieldA.setAccessible(true);
final String value = (String)fieldA.get(null);
System.out.println("SuperMethod: " + value);
} catch (final NoSuchFieldException | IllegalAccessException ex){
// Because reflection
ex.printStackTrace();
}
}
}
class ChildClass extends SuperClass {
private static final String a = "Child";
}
输出为:
SuperMethod: Super
SuperMethod: Child
但是,老实说,我还是会喜欢使用经典替代:
public class Main {
public static void main(String[] args) {
SuperClass s = new SuperClass();
ChildClass c = new ChildClass();
s.superMethod();
c.superMethod();
}
}
class SuperClass {
private static final String a = "Super";
public void superMethod(){
System.out.println("SuperMethod: " + getA());
}
public String getA() {
return a;
}
}
class ChildClass extends SuperClass {
private static final String a = "Child";
@Override
public String getA() {
return a;
}
}