Problem z konstruktorem

0

Witam wszystkich.
Mój problem jest następujący: Mam następujacą hierarchię Płazy<-Zaba<-SkaczącaZaba<-OgraniczonaSkaczącaZaba. W tej ostatniej klasie nadpisuję (override) metodę setColor() z klasy Płazy tak że ta metoda nie robi nic (puste ciało metody). W klasie Płazy metoda ta ustawia kolor obiektu a jak już wspomniałem wcześniej w klasie OgraniczonaSkaczącaZaba metoda ta jest nadpisana i nie robi nic. W tej ostatniej klasie mam też drugi konstruktor z dwoma argumentami, który według zapewnień mojego tutora ma rozwiązać ten problem, gdyz jak twierdzi mój tutor rzeczywiście jeśli będziemy tworzyć obiekt za pomocą konstruktora domyślnego to nasza OgraniczonaSkaczącaZaba będzie bez koloru natomiast jeśli użyjemy naszego drugiego konstruktora to problem będzie rozwiązany. No i tu mam problem. Jakiego konstruktora bym nie użył to OgraniczonaSkaczącaZaba jest bez koloru. Mam nadzieję iż ktoś będzie w stanie pomóc mi z tym nieszczęsnym kolorem i konstruktorem. Zamieszczam kody z tych czterech klas:
Płazy:
import ou.*;
/**

  • The abstract class Amphibian forms the basis of all amphibians.
  • @Author M255 Course Team
  • @version 1.0
    */
    public abstract class Amphibian extends OUAnimatedObject
    {

/* instance variables */

private OUColour colour;
private int position;

/**
* Constructor for objects of the abstract class Amphibian
*/
public Amphibian()
{
super();
OUDialog.alert("From amphibian constructor " + colour);
}

/* instance methods /
/
*
* Test method
*/
public abstract void shout();

/**
* Moves the receiver to the left
*/
public abstract void left();

/**
* Moves the receiver to the right
*/
public abstract void right();

/**

  • Resets the receiver to its "home" position
    */
    public abstract void home();

/**
* Returns the position of the receiver.
*/
public int getPosition()
{
return position;
}

/**
* Sets the position of the receiver to the value of the argument aPosition
*/
public void setPosition (int aPosition)
{
position = aPosition;
this.update("position");
}

/**
* Sets the colour of the receiver to the argument's colour.
*/
public void sameColourAs(Amphibian anAmphibian)
{
this.setColour(anAmphibian.getColour());
}

/**
* Returns the colour of the receiver.
*/
public OUColour getColour()
{
return colour;
}

/**
* Sets the colour of the receiver to the value of the argument aColour.
*/
public void setColour(OUColour aColour)
{
OUDialog.alert("From amphibian setColour " + aColour);
colour = aColour;
this.update("colour");
}

/**
* Sets the colour of the receiver to brown.
*/
public void brown()
{
this.setColour(OUColour.BROWN);
}

/**
* Sets the colour of the receiver to green.
*/
public void green()
{
this.setColour(OUColour.GREEN);
}

/**
* Causes user interface to emit a sound.
*/
public void croak()
{
this.performAction("croak");
}

/**
* Returns a string representation of the receiver.
/
public String toString()
{
return "An instance of class "+ this.getClass().getName()
+ ": position " + this.getPosition()
+ ", colour " + this.getColour();
}
}
Zaba:
import ou.
;
/**

  • The class Frog defines an amphibian with the characteristics of a frog.
  • @Author M255 Course Team
  • @version 2.0
    */

public class Frog extends Amphibian
{
/**
* Constructor for objects of class Frog which initialises colour to green
* and position to 1.
*/

public Frog()
{
super();
this.setColour(OUColour.GREEN);
this.setPosition(1);
OUDialog.alert("From Frog constructor " + getColour());
}

/* instance methods /
/
*
* test method
/
public void shout()
{
OUDialog.alert("FROM FROG CLASS");
}
/
*
* Resets the receiver to its "home" position of 1.
*/
public void home()
{
this.setPosition(1);
}

/**
* Decrements the position of the receiver by 1.
*/
public void left()
{
this.setPosition(this.getPosition()-1);
}

/**
* Increments the position of the receiver by 1.
*/
public void right()
{
this.setPosition(this.getPosition()+1);
}

/**
* Causes a change in an appropriate observing user interface.
* Icon representing the receiver performs a jump animation
/
public void jump()
{
this.performAction("jump");
}
}
SkaczącaZaba:
import ou.
;
/**

  • The class HoverFrog is a subclass of Frog with the addition of the

  • instance variable height and the accessors setHeight() and getHeight().

  • @Author M255 Course Team

  • @version 1.0
    /
    public class HoverFrog extends Frog
    {
    /
    Instance variable */

    /** The current hovering height of the HoverFrog (in the range 0-6) */
    private int height;

    /**

    • Constructor for objects of class HoverFrog which initialises height to 0.
      */
      public HoverFrog()
      {
      super();
      this.height = 0;
      OUDialog.alert("From HoverFrog constructor " + getColour());
      }

/* Instance methods */

/**
* Returns the height of the receiver.
*/
public int getHeight()
{
return this.height;
}

/**
* Sets the height of the receiver to the value of the argument aHeight.
* aHeight must lie in the range 0-6 otherwise height remains unchanged.
*/
public void setHeight(int aHeight)
{
if ((aHeight >= 0) && (aHeight <= 6))
{
this.height = aHeight;
this.update("height");
}
}

/**
* Increases the height of the receiver by the value of the argument stepChange.
* The new height of the receiver must lie in the range 0-6 otherwise height
* remains unchanged.
*/
public void upBy(int stepChange)
{
this.setHeight(this.getHeight() + stepChange);
}

/**
* Decreases the height of the receiver by the value of the argument stepChange.
* The new height of the receiver must lie in the range 0-6 otherwise height
* remains unchanged.
*/
public void downBy(int stepChange)
{
this.setHeight(this.getHeight() - stepChange);
}

/**
* If the height of the receiver is greater than 0 decrements the height of the receiver
* by 1, otherwise height remains unchanged.
*/
public void down()
{
this.downBy(1);
}

/**
* If the height of the receiver is less than 6 increments the height of the receiver
* by 1, otherwise height remains unchanged.
*/
public void up()
{
this.upBy(1);
}

/**
* Resets the receiver to its home position and to a height of 0.
*/
public void home()
{
super.home();
this.setHeight(0);
}

/**
* Returns a string representation of the receiver.
/
public String toString()
{
return super.toString() + ", height " + this.getHeight();
}
}
OgraniczonaSkaczącaZaba:
import ou.
;
/**

  • Class RestrictedHoverFrog - write a description of the class here.

  • @Author (your name)

  • @version (a version number or a date)
    /
    public class RestrictedHoverFrog extends HoverFrog
    {
    /
    *

    • Default constructor for objects of class RestrictedHoverFrog
      */
      public RestrictedHoverFrog()
      {
      super();
      OUDialog.alert("From RestrictedHoverFrog() constructor " + getColour());

    }

    public RestrictedHoverFrog(int aPosition, int aHeight)
    {
    //super();
    OUDialog.alert("From RestrictedHoverFrog(int aPosition, int aHeight) constructor " + getColour());
    if ((aPosition > 0)&&(aPosition < 12))
    {
    this.setPosition(aPosition);
    }
    if ((aHeight >=0)&&(aHeight <7))
    {
    this.setHeight(aHeight);
    }
    }
    /*Instance methods */
    public void setHeight(int aHeight)
    {
    super.setHeight(aHeight);
    if (this.getHeight() > 0)
    {
    this.setColour(OUColour.RED);
    }
    else
    {
    this.setColour(OUColour.GREEN);
    }
    }

    public void setColour(ou.OUColour aColour)
    {
    OUDialog.alert("From RestrictedHoverFrog() setColour(ou.OUColour aColour) " + getColour());
    }

    public void setPosition(int aPosition)
    {
    if ((aPosition >= 1)||(aPosition <= 11))
    {
    super.setPosition(aPosition);
    }

    }
    }
    Z góry dzięki za odpowiedź.

0

Chryste, co za zaciemniony kod...
Wywal te komentarze bo one nic nie wnoszą do sprawy.
Kod otaczaj znacznikami <code> (bez kolorowania kodu) lub <code class="cpp">.

Co do sprawy - jeżeli przedefiniowujesz metodę wirtualną, to ZAWSZE musisz sprawdzić kod źródłowy klas przodków, żeby upewnić się jak ta metoda jest wywoływana i do czego. Jeżeli nie masz kodu źródłowego, to musisz przeryć dokumentację na wszelkie sposoby i zrobić kupę testów i mieć trochę szczęścia.

Jeżeli dobrze zrozumiałem, to przedefiniowujesz setcolour. Oznacza to automatycznie, że klasy przodków raczej wywołają Twoją wersję i w ten sposób nie zrobią tego co pierwotna metoda robiła (co naprawdę robiła, to powinieneś sprawdzić w jej kodzie źródłowym, a nie brać to na wiarę). Użycie Twojego konstruktora z parametrami musiałoby wymusić na Twojej metodzie setColor wywołanie super.setcolor(). Najprościej to spowodować przez ustawienie w swoim obiekcie dodatkowej zmiennej boolean, która ustawiona w konstruktorze pozwalałaby z setcolor wywołać pierwotną wersję tej metody. Coś w tym stylu:

//...
private bezKoloru;
//...
public RestrictedHoverFrog()
{
  super();
  bezKoloru = true;
  //...
}
public RestrictedHoverFrog(int aPosition, int aHeight)
{
  //...
  bezKoloru = false;
}

public void setColour(ou.OUColour aColour)
{
  if(!bezKoloru)
    super.setColour(aColour);
}

Musisz jednak wiedzieć, że jeżeli metody setColour() używa jeden z konstruktorów odpalanych przez super(), to nic to nie da ponieważ wywołania konstruktorów muszą poprzedzać każdy inny kod. A w momencie odpalenia super() zmienna bezKoloru będzie miała wyzerowaną wartość (czyli false), co oznacza, że taki kod nie zadziała. Czyli można jedynie albo zawsze ustawiać kolor, albo nigdy go nie ustawić zależnie od warunku instrukcji if w setColour().

Taki problem rozwiązuje się przez umieszczanie w konstruktorze przodka metody chronionej (protected) wywoływanej tuż po konstruktorze. I tam umieszcza się wszelki kod ustawiający stan obiektu, któr nie jest niezbędny do jego konstrukcji. Często metoda taka ma nadawaną nazwę init() lub initialize().
O tym musi jednak pomyśleć ktoś, kto klasy projektuje, a nie ktoś kto jej tylko używa. Sprawdź czy konstruktory OUAnimatedObject wywołują jakieś metody chronione. Jeżeli tak, przedefiniuj je tak aby zależnie od potrzeby koloru nie ustawiały. Jeżeli nic takiego nie ma, a metoda setColour wywoływana jest na sztywno w konstruktorze, to niewiele można z tym zrobić poza przerobieniem kodu klasy OUAnimatedObject (o ile masz źródła), jej przodków lub klasy, które używa (o ile masz do nich jakiś dostęp chroniony lub publiczny).


0

Dzięki za Twoją odpowiedź.

1 użytkowników online, w tym zalogowanych: 0, gości: 1