【问题标题】:Accessing variable of a method in superclass访问超类中方法的变量
【发布时间】:2014-10-12 20:29:20
【问题描述】:

我有一个包含 Animal 类以及 Dog 和 Cat 子类的基本代码。我有一个说话的方法。 speak 方法接收一个字符串,并返回一个猫狗“语言”的字符串。如果字符的 ascii 码是偶数,则返回“uff”,如果不是,则返回“vau”。当我重写该方法时,我想从 Dog 类中设置oddSound 和 evenSound,但我找不到合适的方法来执行此操作。
这段代码来自 Animal 类:

public String speak(String what){
    String speakableString = new String();
    String oddSound = new String();
    String evenSound = new String();

    for (int i = 0; i < what.length(); i++) {
        if((((int) what.charAt(i)) & 1) == 1){ 
            speakableString.concat(oddSound); 
        }else if ((((int) what.charAt(i)) & 1) == 0){
            speakableString.concat(evenSound);
        }
    }

    speakableString = speakableString.substring(0, speakableString.length()-1);
    return speakableString;
}

这段代码来自 Dog 类:

public String speak(String what){
    //set oddSound = "vau"
    //set evenSound = "uff"
    return super.speak(what);
}

【问题讨论】:

  • .concat() 不会改变任何东西。
  • 如果修复.concat()语句后问题依旧,请贴出相关代码进行继承。
  • 听起来像 oddSoundevenSound 不应该是方法的局部变量,而是 DogCat 类的属性。
  • 这不是一个错误解决问题。我将尝试通过编辑问题来更清楚地说明这一点。
  • @mattm 这实际上是个好主意。能详细解释一下吗?

标签: java class variables


【解决方案1】:

Animal 类中,有两个受保护的字段,

protected String oddSound;
protected String evenSound;

然后,在DogCat 类中,您可以设置这些字段:

oddSound = "woof";
evenSound = "woofwoof"

然后,在speak() 方法中,您可以简单地使用this.oddSoundthis.evenSound

【讨论】:

  • 我如何从Animal访问Cat的私有变量?
  • 其实,这完全回答了我的问题,但另一个答案有点“好”。
【解决方案2】:

您可以将它们保留为数据成员,并在各自的构造函数中设置它们:

public class Animal {
    private String oddSound;
    private String evenSound;

    protected Animal (String oddSound, String evenSound) {
        this.oddSound = oddSound;
        this.evenSound = evenSound;
    }

    public String speak(String what){
        String speakableString = new String();

        for (int i = 0; i < what.length(); i++) {
            if((((int) what.charAt(i)) & 1) == 1){ 
                speakableString = speakableString.concat(oddSound); 
            }else if ((((int) what.charAt(i)) & 1) == 0){
                speakableString = speakableString.concat(evenSound);
            }
        }
}

public class Dog extends Animal {
    public Dog() {
        super ("uff", "vau");
    }
}

【讨论】:

    【解决方案3】:

    Animal 类应该声明你的 speak 方法,因为这对 Dog 和 Cat 类都是通用的。

    public class Animal {
        String oddSound;
        String evenSound;
    
        public Animal(String oddSound, String evenSound) {
            this.oddSound = oddSound;
            this.evenSound = evenSound;
        }
    
        public String speak(String what){
            String speakableString = new String();
    
            for (int i = 0; i < what.length(); i++) {
                if((((int) what.charAt(i)) & 1) == 1){ 
                    speakableString = speakableString.concat(oddSound); 
                }else if ((((int) what.charAt(i)) & 1) == 0){
                    speakableString = speakableString.concat(evenSound);
                }
            }
    
        speakableString = speakableString.substring(0, speakableString.length()-1);
        return speakableString;
        }
    }
    

    请记住,string.concat 方法会创建一个 new 对象,它不会修改调用它的实例。见String API Documentation

    您的 Dog 和 Cat 类应仅在需要时定义或覆盖方法。看来您在他们的 speak 方法中所做的只是调用超级方法实现。你可以完全摆脱它。

    如果您想扩展 Animal 类以提供新的方法或实现,请这样做:

    public class Dog extends Animal {
        public Dog() {
            // This calls the super constructor, which sets the oddSound and evenSound fields
            super("vau", "uff");
        }
    
        // This section does nothing.
        // A method implementation which only calls its super implementation is ineffective.
        // If you were to provide a new implementation, this is where it would be.
        //public String speak(String what) {
        //  super.speak(what);  
        //}
    }
    

    【讨论】:

      【解决方案4】:

      您可以将您的 speak 实现分成两部分,以允许您传入要用于 oddSoundevenSound 的字符串。

      public String speak(String what){
          return getSpeakableString(what, new String(), new String());
      }
      protected String getSpeakableString(String what, String oddSound, String evenSound){
          //this is just copied from what you had in your question, it likely doesn't do what you actually want.
          String speakableString = new String();
          for (int i = 0; i < what.length(); i++) {
              if((((int) what.charAt(i)) & 1) == 1){ 
                  speakableString.concat(oddSound); 
              }else if ((((int) what.charAt(i)) & 1) == 0){
                  speakableString.concat(evenSound);
              }
          }
          speakableString = speakableString.substring(0, speakableString.length()-1);
          return speakableString;
      }
      
      //in subclass
      @Override
      public String speak(String what){
          return getSpeakableString(what, "vau", "uff");
      }
      

      【讨论】:

      • 是的,这是我第一次练习时所做的。但是我的老师说这不是最好的方法,我应该找到一种新的方法来做到这一点。
      • 考虑到这是一种方法,我们可以简单地设置一个字段或属性,将它们传入可能不是最好的主意。
      猜你喜欢
      • 2017-08-22
      • 1970-01-01
      • 1970-01-01
      • 2018-09-28
      • 2013-09-08
      • 2023-04-01
      • 2019-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多