【问题标题】:Is a constructor a mutator?构造函数是突变体吗?
【发布时间】:2018-11-19 03:04:03
【问题描述】:

我有一个任务,我需要添加 2 个构造函数,并且除此之外还列出了变异函数。但是我认为大多数构造函数都是突变体:正如post 中所见。所以我很困惑我需要为 mutator 方法做什么?我目前有以下构造函数:

//Constructors
public Species() {
    speciesName = "Balaenoptera musculus";
    population = 15000;
    growthRATE = -0.12;
    if (endangered(growthRATE) == true) {
        status = "endangered";
    } else {
        status = "not endangered";
    }
}

public Species(String name, int populationSize, double GR) {
    speciesName = name;
    population = populationSize;
    growthRATE = GR;
    if (endangered(GR) == true) {
        status = "endangered";
    } else {
        status = "not endangered";
    }
}

public Species(Species species) {
    speciesName = species.getSpeciesName();
    population = species.getPopulation();
    growthRATE = species.getGrowthRate();
    if (endangered(growthRATE) == true) {
        status = "endangered";
    } else {
        status = "not endangered";
    }
}

基于 cmets:

这是我尝试过的,但它导致了以下错误

类型 PrintStream 中的方法 print(boolean) 不适用于参数 (无效)

在 main 的这一行:

        Species O5 = O1;
    System.out.print(O5.changeSpeciesName("Gorilla beringei"));

方法如下:

    public void changeSpeciesName(String newSpeciesName) {
    speciesName = newSpeciesName;
}

【问题讨论】:

标签: java


【解决方案1】:

构造函数的全部意义在于初始化实例,这需要设置字段 - 所以你会认为构造函数是一个mutator,对吧?这有点技术性,但 mutator 专门更改现有实例上的字段的值,而构造函数 创建该实例。很多时候,构造函数确实“改变”了它正在创建的实例——但它是一个构造函数,而不是一个mutator。

另一方面,Mutators 是专门改变实例属性的方法。例如:

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

我不知道你在这里的任务究竟是什么,但我有一种感觉,你被告知要编写 mutator 方法,然后在构造函数中调用它们。例如,而不是

speciesName = "Balaenoptera musculus";
speciesName = name;
speciesName = species.getSpeciesName();

你应该这样做

setName("Balaenoptera musculus");
setName(name);
setName(species.getSpeciesName());

基本上,与其让构造函数自己更改变量,不如调用类的 mutator 来更改变量。

人们会告诉您这样做的一般原因是出于对“如果我们更改名称的设置方式会怎样?”之类的问题的担忧。这样,如果有什么改变,我们只需要在一个地方改变它:mutator 函数setName()。否则,我们必须更改每个构造函数,这是两个额外的更改 - 我们可能会忘记其中一个,这会产生错误。


但是,在构造函数中使用方法调用时,请确保您调用的方法不能被派生类覆盖。这可能会导致不良行为,因为代码可能使用部分初始化的对象。产生的错误很难找到,因为代码看起来没问题,但并没有达到您的预期。

您可以通过在方法声明中使用 final 来避免此类问题

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

或者通过避免在构造函数中调用方法。

【讨论】:

  • 我在问题中添加了信息
  • 你得到的新错误是因为你试图打印一个void。请记住,您将changeSpeciesName() 定义为void,这意味着它不会返回任何内容。然后,你打电话给print(changeSpeciesName(...)); print 函数正在寻找要打印的东西——从chanceSpeciesName() 返回的任何东西——但什么都没有返回,所以没有什么要打印的。因此错误。
  • @ModusTollens 说得好。我认为我对这个主题的了解不够详细,无法很好地表达这一点——您介意建议对我的答案进行修改吗?
  • @GreenCloakGuy 很高兴 :)。我添加了一些文字,但请仔细阅读,因为英语不是我的第一语言,我对此不太自信!
猜你喜欢
  • 2019-04-22
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
相关资源
最近更新 更多