-1

I am using the following UML and some directions to write a program.enter image description here

I am currently working on the Butterfly class. Below is what I have so far.

package nuisance;

import java.util.List;

/**
 * @author brand
 *
 */
public class Butterfly extends Insect {

    private List<String> colors;

    /**
     * @param species
     */
    public Butterfly(String species, List<String> colors) {
        super(species);
        this.colors = colors;
    }

    public Butterfly(Butterfly butterfly) {
        this.butterfly = butterfly;
    }

The issue I am having is in the second constructor which is supposed to initialize the fields based on an existing Butterfly object. I feel like I have written it correctly, but I am getting the following error:

Implicit super constructor Insect() is undefined. Must explicitly invoke another constructor.

I have done some research on this and I can't seem to figure out how to fix the issue. Any help would be greatly appreciated!!

Thank you in advance.

  • 3
    If you don’t call super explicitly you get a call to super inserted for you. Which doesn’t work if the super class doesn’t have a no-arg constructor. Also this.butterfly is not an instance member. – Nathan Hughes Feb 21 '20 at 04:17

2 Answers2

2

The issue is your copy constructor,

public Butterfly(Butterfly butterfly) {
    this.butterfly = butterfly;
}

has an implicit call to super() as the first line. Like,

public Butterfly(Butterfly butterfly) {
    super();
    this.butterfly = butterfly;
}

And there is no empty Insect constructor. Use Butterfly.getSpecies() and Butterfly.getColors() to perform the copy with a this constructor call. Like,

public Butterfly(Butterfly butterfly) {
    this(butterfly.getSpecies(), butterfly.getColors());
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    That would be a shallow copy, since the list of colors will be shared, and `List` is very likely mutable. Still, shallow copy might be ok, so +1 from me. – Andreas Feb 21 '20 at 04:18
  • 1
    @Andreas You're not wrong, but OP has `this.colors = colors;` in their first constructor. Which is where I would put the copy (do it once there - but that's just my opinion); `this.colors = new ArrayList<>(colors);` – Elliott Frisch Feb 21 '20 at 04:19
  • Not exactly sure which one is correct (shallow vs deep) but you guys definitely cleared up the original issue I was having, and I understand why as well. Cannot thank you enough! – Brandon Bischoff Feb 21 '20 at 04:21
  • 1
    @BrandonBischoff Ask yourself this, should changing the colors of one butterfly change the colors of the copies of that butterfly? If yes, you want a ***shallow*** copy. If no, you want ***deep*** copy. – Elliott Frisch Feb 21 '20 at 04:23
1

this.butterfly will fail to compile, because you don't have a field named butterfly (and you shouldn't).

Your copy-constructor should be:

public Butterfly(Butterfly butterfly) {
    super(butterfly.getSpecies());
    this.colors = new ArrayList<>(butterfly.colors); // deep copy
}
Andreas
  • 154,647
  • 11
  • 152
  • 247