有没有办法从超类访问子类元素?

我需要一个将在子类中使用的类中的方法,尽管此方法使用在子类中更改的属性。有没有一种方法可以访问子类的属性而不必重写方法?


我试过为该属性使用吸气剂,但得到了相同的结果。


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();

    }

}

控制台显示:


超级方法:超级


超级方法:超级


预期结果是:


超级方法:超级


超级方法:孩子


慕娘9325324
浏览 155回答 3
3回答

Helenr

我试过为该属性使用吸气剂,但得到了相同的结果。你确定吗?以下应该正是您所追求的: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 不能是私有的(否则无法从类外部访问它们),并且它们不能是静态的(否则它们是类的一部分,而不是该类的任何实例。)

ITMISS

目前尚不清楚你在做什么,但你的String a成员是private static班级的成员,而不是个别对象的成员。如果您创建了String a对象的成员,而不是类的成员,则可以在创建子类期间覆盖该值:U:\>jshell|  Welcome to JShell -- Version 12|  For an introduction type: /help introjshell> 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 SuperClassjshell> class ChildClass extends SuperClass {   ...>    public ChildClass() {   ...>      super("Child");   ...>    }   ...> }|  created class ChildClassjshell> var s = new SuperClass();s ==> SuperClass@4566e5bdjshell> var c = new ChildClass();c ==> ChildClass@ff5b51fjshell> s.superMethod();SuperMethod: Superjshell> 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 {&nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; SuperClass s = new SuperClass();&nbsp; &nbsp; &nbsp; ChildClass c = new ChildClass();&nbsp; &nbsp; &nbsp; s.superMethod();&nbsp; &nbsp; &nbsp; c.superMethod();&nbsp; }}class SuperClass {&nbsp; &nbsp; private static final String a = "Super";&nbsp; &nbsp; public void superMethod(){&nbsp; &nbsp; &nbsp; try{&nbsp; &nbsp; &nbsp; &nbsp; final Class<?> clazz = this.getClass();&nbsp; &nbsp; &nbsp; &nbsp; final Field fieldA = clazz.getDeclaredField("a");&nbsp; &nbsp; &nbsp; &nbsp; fieldA.setAccessible(true);&nbsp; &nbsp; &nbsp; &nbsp; final String value = (String)fieldA.get(null);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("SuperMethod: " + value);&nbsp; &nbsp; &nbsp; } catch (final NoSuchFieldException | IllegalAccessException ex){&nbsp; &nbsp; &nbsp; &nbsp; // Because reflection&nbsp; &nbsp; &nbsp; &nbsp; ex.printStackTrace();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}class ChildClass extends SuperClass {&nbsp; &nbsp; private static final String a = "Child";}输出是:SuperMethod: SuperSuperMethod: Child但是,老实说,我仍然喜欢使用经典覆盖:public class Main {&nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; SuperClass s = new SuperClass();&nbsp; &nbsp; &nbsp; ChildClass c = new ChildClass();&nbsp; &nbsp; &nbsp; s.superMethod();&nbsp; &nbsp; &nbsp; c.superMethod();&nbsp; }}class SuperClass {&nbsp; &nbsp; private static final String a = "Super";&nbsp; &nbsp; public void superMethod(){&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("SuperMethod: " + getA());&nbsp; &nbsp; }&nbsp; &nbsp; public String getA() {&nbsp; &nbsp; &nbsp; return a;&nbsp; &nbsp; }}class ChildClass extends SuperClass {&nbsp; &nbsp; private static final String a = "Child";&nbsp; &nbsp; @Override&nbsp; &nbsp; public String getA() {&nbsp; &nbsp; &nbsp; return a;&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java