为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕娘9325324 2023-03-23 14:23:32
我需要一个将在子类中使用的类中的方法,尽管此方法使用在子类中更改的属性。有没有一种方法可以访问子类的属性而不必重写方法?我试过为该属性使用吸气剂,但得到了相同的结果。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();    }}控制台显示:超级方法:超级超级方法:超级预期结果是:超级方法:超级超级方法:孩子
查看完整描述

3 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

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


你确定吗?以下应该正是您所追求的:


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 不能是私有的(否则无法从类外部访问它们),并且它们不能是静态的(否则它们是类的一部分,而不是该类的任何实例。)


查看完整回答
反对 回复 2023-03-23
?
ITMISS

TA贡献1871条经验 获得超8个赞

目前尚不清楚你在做什么,但你的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

    }

}



查看完整回答
反对 回复 2023-03-23
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

简短回答: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;

    }

}


查看完整回答
反对 回复 2023-03-23
  • 3 回答
  • 0 关注
  • 154 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号