[英]Is there a way to access a subclass element from a super class?
我需要一个将在子类中使用的类中的方法,尽管该方法使用的是在子类中更改的属性。 有没有一种方法可以访问子类的属性而不必重写该方法?
我已经尝试过使用该属性的吸气剂,但得到相同的结果。
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();
}
}
控制台显示:
超级方法:超级
超级方法:超级
预期结果是:
超级方法:超级
超级方法:子级
我已经尝试过使用该属性的吸气剂,但得到相同的结果。
你确定吗? 以下就是您所追求的:
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不能是私有的(否则它们不能从类外部访问),并且不能是静态的(否则它们是该类的一部分,而不是该类的任何实例)。
目前尚不清楚您在做什么,但是您的String a
成员是该类的private static
成员,而不是单个对象的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
}
}
简短的答案: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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.