0

The Dog class has a size 3 array with four string values. However, in the subclass GreatDane, I have to add one more element to this same array. I must do this without using an arraylist (my Java course has not covered those yet).

Here is the class:

abstract class Dog {

String mSize [] = {"tiny", "small", "average", "large"};

int mFeedCounter;

int dogSize = 0;

String getSize() {
        return mSize[dogSize];
    }

    /*
     * setSize
     * Sets the size of the Dog
     * @param size the new size of the Dog, a String
     * @return nothing
     */
    void setSize(String size) {
        mSize[dogSize] = size;
    }

And here is the sub class:

Define the GreatDane class below
 *
 *  Great Danes have an extra size category, "huge".
 *  After growing to a "large" size, they may grow
 *  to an additional, "huge" size after 3 meals.
/************************************************/
class GreatDane extends Dog{
      String mSize[] = {"tiny","small","average","large","huge"};

    @Override
    void feed(){
        if(++mFeedCounter == 3){
        dogSize ++;
        getSize();
        mFeedCounter = 0;}
      }
    }

I tried reassigning the array reference with mSize = new String []{"tiny","small","average","large","huge"}; but this just gave me an identifier expected error.

Anyways, I don't know why GreatDane is not moving to mSize[4].

For reference, here is another class with a similar method that worked:

class Chihuahua extends Dog{
    @Override
    void feed(){
        if(++mFeedCounter ==5){
        dogSize++;
        getSize();
        mFeedCounter = 0;}
    }
}
TonyKazanjian
  • 269
  • 2
  • 13

2 Answers2

0

In your GreateDane constructor, you could change the reference of Super's mSize like below:

GreatDane() {
    String mSize[] = new String[5];//define string array of size 5
    System.arraycopy(super.mSize, 0, mSize, 0, super.mSize.length);//copy existing elements from parent class
    mSize[4] = "huge";//add new elements at the end
    super.mSize = mSize;//change reference of super now as you dont want two copies of the same array in parent and child.
}
SMA
  • 36,381
  • 8
  • 49
  • 73
0

Firstly, and putting aside how this is an inappropriate design for this use case, if you want your subclasses to be able to modify what array mSize refers to, you should declare it protected access, rather than package-private (default) access:

protected String[] mSize = {"tiny", "small", "average", "large"}; //Brackets are idiomatically placed after type, not name, in Java.

You can read more about access modifiers here. Then, all subclasses (not just ones in the same package, as yours was), can modify it. Your attempt did not work because it creates a new variable mSize, coincidentally with the same name as Dog's mSize, but entirely different. Since you defined getSize() in class Dog, it refers to Dog's mSize, and not GreatDane's mSize. Instead, reassignment with mSize = new String [] {"tiny","small","average","large","huge"}; is correct, but you received an error because you cannot simply put code statements wherever. You need to put the statement either in a constructor:

//these classes and methods should be public (also in Dog)
public class GreatDane extends Dog {
    public GreatDane() {
        mSize = new String[]{"tiny","small","average","large","huge"};
    }

    @Override
    public void feed(){
        mFeedCounter++;//incrementing inside other statements is concise but discouraged
        if (mFeedCounter == 3) { //consider >= 3 just in case
            dogSize++;
            getSize();
            mFeedCounter = 0;
        }
    }
}

or in an initializer block:

public class GreatDane extends Dog {
    {
        mSize = new String[]{"tiny","small","average","large","huge"};
    }

    @Override
    public void feed() {
        ...

It's difficult to say which version is more correct because this design does not make sense in the first place. mSize should in theory be replaced with a getSizeDescription method that references a static array, and which is overridden in classes that describe additional sizes, or that supports all possible sizes but where dogs of the wrong type are prohibited from growing too large.

Community
  • 1
  • 1
Vitruvie
  • 2,327
  • 18
  • 25
  • Thanks, that looks like something closer to what I'm supposed to do, but when I reassign `mSize` in the initializer block or constructor, I get a "not a statement" error or a "; expected" error when I compile, even though I know my syntax is not wrong at all. – TonyKazanjian Feb 15 '15 at 09:35
  • @silentkit Oops- copypaste error. Fixed the syntax. – Vitruvie Feb 15 '15 at 09:41
  • No prob. I still don't understand why I'm getting "identifier expected" compile errors, though. Using the same syntax you posted, or using `mSize []` in the definition. – TonyKazanjian Feb 15 '15 at 09:48
  • I don't understand what's wrong with this syntax in the declaration: `mSize = new String[]{"tiny","small","average","large","huge"};` yet the compiler points out an expected error right after `mSize` – TonyKazanjian Feb 15 '15 at 10:00
  • @silentkit The problem is that it is not a declaration of a variable, method, or code block, being an assignment to an existing variable, and therefore cannot be placed outside of a method or code block. It's a valid statement, but placed outside of a legal context in which it's expected. – Vitruvie Feb 15 '15 at 10:18
  • @silentkit If this answer solved your problem, make sure to accept it by clicking the checkmark outline below its vote count on the left. – Vitruvie Feb 15 '15 at 10:19