【问题标题】:Confused about error while learning Polymorphism在学习多态性时对错误感到困惑
【发布时间】:2016-05-20 00:31:16
【问题描述】:

我正在学习多态性,我在我的超类和子类中得到这条红线,它在我的代码中被注释:

    public class Animals {
  private String name;

  public Animals(String name) {
      this.name = name;
        }

  public void changeName(String name){
      this.name= name;
  }

  public String getName(){
      return this.name;  // 
  }

}

这是我的子类:

public class Dog extends Animals {
    private String colour;

    public Dog(String name, String colour){
        super(name);  
        this.colour = colour;
    }

    public void changeColour(String colour) {
        this.colour = colour;
    }
    public String getColour(){
        return this.colour;
    }

}    

这是另一个带有 main 方法的脚本:

public class AnimalPolyTesting {
    public static void main(String[] args) {
        Animals puppy = new Dog("homie", "black"); // constructor Dog cannot be applied to given types;
        puppy.getName();
        (Dog) puppy.getColour(); // not a statement

    }
}

我不确定为什么会出现这些红线 编辑:代码运行但没有任何结果。 Edit2:修复了类。

【问题讨论】:

  • 一个void 方法不能return 一个值。
  • 您的方法getName() 声明void(即“无返回类型”)为其返回类型,但您尝试返回String,即变量name 的内容。那是不相容的。您必须声明像public String getName() 这样的方法。
  • public void Animals(String name) 是一种方法。要将其变成构造函数,请删除void,因此您的基类只有默认构造函数public Animals(),因此构造函数错误
  • Java 中的多态性通常有一些特殊的类,例如abstract class。你的一门课可以考虑abstract吗?此外,也许再次查看类 docs.oracle.com/javase/tutorial/java/javaOO/constructors.html 的构造函数语法
  • 另外Animal(单数)是该类的更好名称

标签: java methods polymorphism subclass superclass


【解决方案1】:

[更新]

我已在您的代码中注释了有问题的行。

public class Animals {
  private String name;

  /*
   * This is a method, not a constructor, because it has a return type.
   * Since there is no constructor, Java will automatically generate an implicit
   * `Animal` constructor for you -- one with no parameters.
   *
   * To fix: remove the return type.
   */
  public void Animals(String name) {
      this.name = name;
  }

  public void changeName(String name){
      this.name= name;
  }

  /*
   * The return type should be String, not void.
   */
  public void getName(){
      return this.name;  // RED LINE: Unexpected return value
  }
}

public class Dog extends Animals {
    private String colour;

    /*
     * 1. A "super(...)" call only makes sense from within a constructor, but this is not
     * a constructor, due to the void return type.
     * 2. Java will automatically generate an implicit `Dog` constructor for you -- one with no parameters.
     * 3. Since the only Animals constructor is the implicit constructor, which has no parameters,
     * the "super(...)" call would fail even if this was a constructor.
     * 
     * To fix: Fix Animals, and remove the void return type.
     */
    public void Dog(String name, String colour){
        super(name);  // RED LINE: constructor Animals in Animals class cannot be applied to given types; 
        this.colour = colour;
    }

    public void changeColour(String colour) {
        this.colour = colour;
    }

    /*
     * The return type should be String, not void.
     * 
     * To fix: change "void" to "String".
     */
    public void getColour(){
        return this.colour; //RED LINE: unexpected return value
    }
}

public class AnimalPolyTesting {
    public static void main(String[] args) {

        /*
         * The only Dog constructor is the implicit constructor, which has no parameters.
         * 
         * This will be fixed once Dog and Animals are fixed.
         */
        Animals puppy = new Dog("homie", "black"); // constructor Dog cannot be applied to given types;

        puppy.getName();

        /*
         * Dog.getColour() returns nothing (since its return type is void).
         * It makes no sense to try to coerce nothing to be of type Dog.
         * 
         * To call getColor(), you need to coerce puppy to be a Dog this way:
         * ((Dog) puppy).getColour();
         */
        (Dog) puppy.getColour(); // not a statement

    }
}

【讨论】:

  • 我修复了我的课程,把它们不应该出现的地方去掉。现在我在主方法类上,但即使我写 System.out.println(puppy.getName()); 仍然没有得到任何输出。我想它至少会打印出小狗的名字。至于(狗)puppy.getColour();我试图让输出显示狗的颜色,但该方法在超类中不存在,因为小狗是动物类型,所以我用 (Dog) 投射它,以便它现在可以打印出颜色
  • 我尝试在纠正所有带注释的错误后运行代码,System.out.println(puppy.getName()) 确实为我打印出“homie”。确保您已进行所有建议的更改。我将在我的答案中添加有关如何解决强制问题的信息,以便您可以致电getColour()
【解决方案2】:

看起来getName() 的返回类型设置为void,而您正尝试返回String。在此方法中将void 更改为String,红线应该在那里消失。 getColour()你也有同样的问题。

除此之外,你的构造函数不能有返回类型,所以你应该删除那些上的void

您的行(Dog) puppy.getColour(); 正在尝试将从puppy.getColour() 返回的String 转换为Dog 对象。我相信您要做的是在puppy 上调用getColour(),但您注意到它首先需要是Dog。试试这个:((Dog)puppy).getColour();,这样你就可以将puppy 转换为Dog,然后你就可以调用你想要的方法了。

【讨论】:

    【解决方案3】:

    你的动物类应该是这样的

    public class Animals {
        private String name;
    
        public Animals(String name) {
            this.name = name;
        }
    
        public void changeName(String name){
            this.name= name;
        }
    
        public String getName(){
            return this.name;
        }
    
    }
    

    您遇到的问题是您的构造函数有一个void 返回类型。构造函数不应该有返回类型。其次,您的 getName() 方法的返回类型为 void。为了让它正常工作,您需要声明它返回的内容。鉴于此,我将由您来实现其余代码。

    【讨论】:

      【解决方案4】:

      构造函数不能有返回类型,因为它是隐式的(Dog 的构造函数显然返回 Dog):

      public Dog(...)
      

      不是

      public void Dog(...)
      

      当然,Animals 也是如此。

      而您的 get 方法声明了一个与意图相矛盾的 void 返回类型,因此更改为:

      public String getName()...
      public String getColour()...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-21
        • 1970-01-01
        • 1970-01-01
        • 2018-03-18
        • 2013-06-02
        • 1970-01-01
        • 2011-05-12
        • 1970-01-01
        相关资源
        最近更新 更多