0

I'm currently having difficulty getting my new subclass to compile:

public class CompilationAlbum extends Album {

    private String seriesOfAlbums;

    public CompilationAlbum(String seriesOfAlbums) {
        this.seriesOfAlbums = seriesOfAlbums;
        albumType = "Compilation";
    }
}

Can anyone point out what I'm doing wrong? The fault seems to lie with the constructor, but I can't see why that should cause an error. The error message also reads "actual and formal argument lists differ in length."

EDIT: The Album class, minus methods, looks like this:

import java.util.ArrayList;

public class Album {

    private String name;
    private ArrayList<Track> trackList;
    private int length; 
    private int fileSize;
    private double averageRating;
    private String albumType;

    public Album(String name){
        this.name = name;
        trackList = new ArrayList<Track>();
    }
Zetland
  • 569
  • 2
  • 11
  • 25
  • Following up on the conversation about how to set the name, I wouldn't consider the private fields to be a "problem." Assuming there are public or protected get/set methods, it would generally be preferable to use those (i.e. this.setName(name)) rather than directly modifying the fields. See some discussion about that here: http://stackoverflow.com/questions/2279662/java-protected-fields-vs-public-getters – Shaun Nov 05 '14 at 19:01

2 Answers2

2

If you don't explicitly call a constructor of the superclass in the first line of the subclass constructor, a call to super() is inserted by the compiler. Since Album doesn't have a no-argument constructor, compilation fails because the inserted call to super() isn't valid.

There are two ways to resolve this - either call the existing superclass constructor with some String argument (you'd have to decide what makes sense for your particular use case), or add a no-argument constructor to the superclass (again, the behavior of this constructor will depend on what you're actually trying to do).

Here's an approach that might make sense:

public class CompilationAlbum extends Album {

    private String seriesOfAlbums;

    public CompilationAlbum(String name, String seriesOfAlbums) {
        super(name);
        this.seriesOfAlbums = seriesOfAlbums;
        albumType = "Compilation";
    }
}
Shaun
  • 2,446
  • 19
  • 33
  • I've just edited my post to add the Album class (minus methods). – Zetland Nov 05 '14 at 16:58
  • Right - so that's what we thought. You'll fix the compilation error if you change the CompilationAlbum constructor to start with super(seriesOfAlbums); Alternatively, since that probably doesn't make sense in terms of your actual use case, you could add a no-argument constructor to Album. – Shaun Nov 05 '14 at 17:00
  • Okay, I've added `super(seriesOfAlbums);` and it works better now, although I'm still getting an error message for trying to construct `albumType` when `albumType` is a private variable. Do you know a way around this, allowing a subclass to modify its superclass? – Zetland Nov 05 '14 at 17:08
1

Without seeing the source code for Album, I'm guessing that it does not have a default constructor.

You wrote this:

public class CompilationAlbum extends Album {

    private String seriesOfAlbums;

    public CompilationAlbum(String seriesOfAlbums) {
        this.seriesOfAlbums = seriesOfAlbums;
        albumType = "Compilation";
    }
}

You want this:

public class CompilationAlbum extends Album {

    private String seriesOfAlbums;

    public CompilationAlbum(String seriesOfAlbums) {
        super(seriesOfAlbums);
        this.seriesOfAlbums = seriesOfAlbums;
        albumType = "Compilation";
    }
}

Now that I see the Album class, your problem is private members. Make those protected so child classes can get at them, too.

duffymo
  • 305,152
  • 44
  • 369
  • 561