I'm having difficulty figuring out how to overwrite parts of the "toString" methods in superclasses (polymorphism)

I have a superclass "Vessel" and a subclass "Bottle". The subclass "Bottle" further has two subclasses "GlasBottle" and "PlasticBottle".

I want the following output:

This vessel has a volume of 1

This bottle has a volume of 1 and contains juice

This green glas bottle has a volume of 2 and contains juice

This white glas bottle has a volume of 1 and contains beer

This OTHER bottle has a volume of 2 and contains cola

This PET bottle has a volume of 1 and contains milk

However, I'm having problems overriding the different toString methods in each class.

This is what I get as my output:

This vessel has a volume of 1

This bottle This vessel has a volume of 1 and contains juice

This green glas bottle This bottle This vessel has a volume of 2 and contains juice

This white glas bottle This bottle This vessel has a volume of 1 and contains beer

This OTHER bottle This bottle This vessel has a volume of 2 and contains cola

This PET bottle This bottle This vessel has a volume of 1 and contains milk

As you can see from the second output, it inserts "This vessel" since that string is part of the "toString" method that I'm calling, so it makes sense that it's there. However, I want java to omit that part of the superclass when I call the super.toString() and only include the other necessary parts. Here are my superclass and subclasses:

public class Vessel {

    private int volume=0;

    public Vessel(int volume) {
        this.volume = volume;
    }

    public String toString() {
    return "This vessel has a volume of "+volume;
    }

}

public class Bottle extends Vessel {

    private String content="";

    public Bottle(int volume, String content) {
        super(volume);
        this.setContent(content);
    }

    public String getContent(String content) {
        return this.content = content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String toString() {
        return "This bottle "+super.toString()+" and contains "+content;
    }

}

public class GlasBottle extends Bottle {

    private String color="";

    public GlasBottle(int volume, String content, String color) {
        super(volume, content);
        this.setColor(color);
    }

    public String getColor(String color) {
        return this.color = color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String toString() {
        return "This "+color+" glas bottle "+super.toString();
    }

}

public class PlasticBottle extends Bottle {

    private String material="";

    public PlasticBottle(int volume, String content, String material) {
        super(volume, content);
        if(material != "PET") {
            this.material = "OTHER";
        }else {
            this.setMaterial(material);
        }
    }

    public String getMaterial(String material) {
        return this.material = material;
    }

    public void setMaterial(String material) {
        this.material = material;
    }

    public String toString() {
        return "This "+material+" bottle "+super.toString();
    }

}

What you want is 'overriding' not overwriting.

First of all add a getVolume() method to your top level Vessel class, since your volume is private.

You can simply put the parts that change as separate methods. So in Bottle you put a method like this:

protected String getBottleType() {
  return "bottle";
}

and change your toString() like this:

public String toString() {
    return "This " + getBottleType() + " has a volume of " + getVolume() + " and contains " + content;
}

Then in each subclass of Bottle you just override getBottleType(). For example in GlassBottle you just do:

@Override
protected String getBottleType() {
 return color + " glass bottle";
}

You can then actually leave out the toString() of the sub classes unless you wish to change the sentence.

Kendrick Lamar - i (Audio), I definition, the ninth letter of the English alphabet, a vowel. See more. I definition is - the 9th letter of the English alphabet. How to use i in a sentence. me or I?

I suppose that you would avoid duplication by using the volume information of the toString() parent class :

public String toString() { return "This vessel has a volume of "+volume; }

But it will not give the expected result in this way :

public String toString() {
    return "This bottle "+super.toString()+" and contains "+content;
}

It will just mix the current class and the parent class information in the built String.

What you want in the subclass is :

public String toString() {
    return "This bottle has a volume of " + getVolume() + " and contains "+content;
}

In this case you should introduce a getter to access to volume from the subclasses.

Note that to avoid duplication and keep the volume field private you could also write something like in the subclass :

public String toString() {
    return "This bottle" + toStringVolume() " and contains " + content;
}

And define in the parent class :

public final String toStringVolume(){
   return "has a volume of " + volume;     
}

But is it really valuable ? It creates some indirection in the reading for not a great value.

I (Kendrick Lamar song), Create an account or log in to Instagram - A simple, fun & creative way to capture, edit & share photos, videos & messages with friends & family. I or i is the ninth letter and the third vowel letter of the modern English alphabet and the ISO basic Latin alphabet. Its name in English is i (pronounced / ˈ aɪ /), plural ies. 1 History 2 Use in writing systems

I want java to omit that part of the superclass when I call the super.toString() and only include the other necessary parts.

You understand that super.toString() returns the whole string as you defined. "the other necessary parts" is the thing only you are aware of. You could parse super.toString() to extract the parts you need, but it's tedious and folly.

A reasonable way is to access parent's properties by public getters and construct a unique String for each subclass ignoring how the parent represented itself.

I, The ninth letter of the basic modern Latin alphabet. I (lower case ı). The letter i without a dot above, in both the upper case and the lower case versions. Usage in various languages Faroese. Í is the 11th letter of the Faroese alphabet and represents /ʊi/.. Hungarian, Icelandic, Irish, Czech and Slovak. Í is the 16th letter of the Hungarian alphabet, the 12th letter of the Icelandic alphabet, the 16th letter of the Czech alphabet and the 18th letter of the Slovak alphabet.

I think the simplest thing to do is as follows: Remove the toString methods from GlasBottle and PlasticBottle, introduce the notion of a 'vesselQualifier' (e.g. color, material), and rewrite the toString methods in Vessel and Bottle as shown below, which obtain the paired down classname from the corresponding sub-class at runtime. I've removed all of the other unrelated code for the sake of brevity.

public class Vessel {
    protected String vesselQualifier() {
        return null;
    }
    public String toString() {
        String[] classNameParts = this.getClass().getCanonicalName().split("\\.");
        return "This "
                +(vesselQualifier()==null?"":(vesselQualifier()+" "))
                +classNameParts[classNameParts.length-1]+" has a volume of " + volume;
    }
}

public static class Bottle extends Vessel {
    public String toString() {
        return super.toString() + " and contains " + content;
    }
}

public static class GlasBottle extends Bottle {
    @Override
    protected String vesselQualifier() {
        return color;
    }
}

public static class PlasticBottle extends Bottle {
    @Override
    protected String vesselQualifier() {
        return material;
    }
}

Instagram, I definition is - the 9th letter of the English alphabet. How to use i in a sentence. me or I? Song i; Artist Kendrick Lamar; Licensed to YouTube by UMG (on behalf of Aftermath); CMRRA, EMI Music Publishing, SOLAR Music Rights Management, UMPG Publishing, LatinAutor - SonyATV, ASCAP

I, I suppose we could start—why not?—by actually reading it. And within just a phrase or two, you realize why people were afraid of it: Allen is a  Ï, lowercase ï, is a symbol used in various languages written with the Latin alphabet; it can be read as the letter I with diaeresis or I-umlaut.. In Afrikaans, Catalan, Dutch, French, Galician, Welsh, Southern Sami, and occasionally English, ï is used when i follows another vowel and indicates hiatus (diaeresis) in the pronunciation of such a word.

I, I-94 is a place for U.S. visitors to find travel records. Î is a letter which appears in several French words, like naître (to be born), abîme (abyss), maître (master), (crème) fraîche and more. Unlike Â, Ê, and Ô, the circumflex does not alter the pronunciation of î or û.

I Actually Read Woody Allen's Memoir, Log in to i-Ready®, online assessment and instruction that helps teachers provide all students a path to proficiency and growth in reading and mathematics. Log in to i-Ready®, online assessment and instruction that helps teachers provide all students a path to proficiency and growth in reading and mathematics.

Comments
  • What you want to do is have fields that contain the name of the object, like String thisName = "bottle". Then in your toString you just need to do return "This" + thisName + "whatever";
  • @WoeIs add a public getter for volume