Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Pomoc s OO kódom

Zdravím! :) Potreboval by som trochu helfnúť s jedným kódom. Nerobím žiadnu hru (aj keď by sa to tak mohlo zdať), iba sa tak hrám s triedami a skúšam veci s dedičnosťou a polymorfizmom a tak. V OO som neskúsený, prečítal som nejaké knižky ale keď som to skúsil v praxi, našiel som pár zádrhelov Bol by som rád ak by ste mi pomohli nech sa môžem pohnúť ďalej :)

Dal som si aj tú malú námahu cvaknúť UML diagram aby bol môj problém zrozumiteľnejší :) Inak celý popis problému je rovno v tom obrázku :)

(áno, používam názvy lodí zo seriálu Battlestar Galactica, lebo sa mi nechcelo žiadne vymýšlať :-) )

[problem.jpg]

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
jak presne a kde presne si definoval tie konstanty a kde presne ich "nevidiet" (jak k nim pristupuje…
MM.. 10.08.2012 20:45
MM..
ahoj, ako som vyššie napísal, definície konštánt mám v každej jednej konkrétnej (neabstraktnej) tri…
wewo 10.08.2012 21:12
wewo
Aha, takže Java: public abstract class Spaceship { private int hull; private int maxHull; public Sp…
los 10.08.2012 22:05
los
Ej, no tento návrh sa mi aj celkom pozdáva :) Ak teda rozumiem, tak z podtriedy volám konštruktor su…
wewo 11.08.2012 14:07
wewo
A podle čeho se to učíš? Ve většině učebnic je to někde na začátku. http://cs.wikipedia.org/wiki/Ter… nový
Wikan 11.08.2012 15:10
Wikan
Z rôznych zdrojov, ale hlavne odtiaľto: hfjava poslední
wewo 11.08.2012 15:43
wewo

ahoj,

ako som vyššie napísal, definície konštánt mám v každej jednej konkrétnej (neabstraktnej) triede.

Teda napr. trieda Viper (to je jeden z typov stíhačiek) vyzerá takto:

public class Viper extends Fighter
{
        
    static final int STANDART_HULL = 12; // toto sú konštanty s ktorými má pracovať
    static final int MAX_HULL      = 15; // setter a konštruktor (pokiaľ nemá hull zadaný ako
                                         // argument)
       
    String name;    
    
    public Viper()
    {
       this.setName("Viper");
       this.setHull(STANDART_HULL);
    }
    
    public Viper(String name)
    {
       this.setName(name);
       this.setHull(STANDART_HULL);
    }
    
    public Viper(String name, int hull)
    {
       this.setName(name);
       setHull(hull);     
    }

}

Takto zatiaľ vlastne vyzerá každá konkrétna trieda, menia sa iba konštanty (malá stíhačka má menšie pancierovanie ako veľký krížnik).

Tieto konštanty používam v Setteri, využívam enkapsuláciu aby som pri zmenení premennej hull mohol overiť či nepresahuje MAX_HULL, lebo malá stíhačka rady Viper nemôže mať väčší hull ako 15.

Setter mám ale definovaný v superclasse Spaceship, keďže ho majú mať všetky lode rovnaký.

Starship:

public abstract class Spaceship
{    
    protected int hull;
    protected int MAX_HULL;      // tieto tri premenné musia byť delkarované, inak setter v tejto
    protected int STANDART_HULL; // triede veľmi protestoval :-) Sú teda nastavené na hodnotu 0.

   
    public Spaceship()                                                         
    {                                                                           
    }                                                                        
    
    public int getHull() {
        return hull;
    }

    public void setHull(int hull) { // Toto je tá metóda, setter, ktorá nefunguje správne. Podtriedy
        if (hull <= MAX_HULL)       // ju dedia a na ich inštancie ju viem vyvolať, ale argument
        this.hull = hull;           // porovnáva a nastavuje s premennou MAX_HULL z tejto triedy, teda  
       else                         // s hodnotou 0, a to aj keď sú v podtriedach na ktoré ju volám 
        this.hull = MAX_HULL;       // override-nuté.Táto metóda teda vždy v premennej podtriedy hull 
    }                            // nastaví hodnotu 0, nezávisle od toho, aký argument do nej vkladám.
    
    ........ // tu sú potom ešte všelijaké iné metódy, ktoré teraz netreba riešiť......               
}

Tomu, že supertrieda nevidí premenné a konštanty svojich podtried rozumiem. Potreboval by som preto skôr nejaký návrh, ako tento problém vyriešiť s tým, aby bol kód čo najviac objektovo-orientovaný.

(napísať getter a setter zvlášť pre každú podtriedu by bolo riešenie, ale neverím že neexistuje nič lepšie a elegantnejšie :-) )

Ďakujem pekne za rady!

Aha, takže Java:

public abstract class Spaceship {

    private int hull;
    private int maxHull;

    public Spaceship(int hull, int maxHull) {
        if (hull > maxHull) {
            throw new IllegalArgumentException();
        }
        this.hull = hull;
        this.maxHull = maxHull;
    }

    public int getHull() {
        return hull;
    }
    
    public int setHull(int hull) {
        this.hull = hull < maxHull ? hull : maxHull;
    }

    ...
}

Metóda setHull a konštruktor sú trochu nekonzistentné, pretože v jednej sa vyhadzuje výnimka a v druhej sa potichu nastaví maximálna hodnota. Mal by si si vybrať jednu možnosť a tú dodržiavať.

public class Viper extends Fighter {
       
    private String name;    
    
    public Viper() {
        this("Viper");
    }
    
    public Viper(String name) {
        this(name, 12);
    }
    
    public Viper(String name, int hull) {
        super(hull, 15)
        setName(name);
    }

    ...
}

Konštantu STANDART_HULL som úplne vyhodil, lebo sa mi nezdá, že by si si ju potreboval niekde pamätať. Ale môžeš si ju tam samozrejme pridať.

Ej, no tento návrh sa mi aj celkom pozdáva :) Ak teda rozumiem, tak z podtriedy volám konštruktor supertriedy a posielam do neho hodnoty takto pekne, hmm, ešte som sa týmto netretol veru :)

Popravde sa mi nepáči to, že mi to hádže Exception (ale to si viem vyriešiť), a ten druhý spôsob, čo je v setteri, takú syntax som ešte nevidel :-? "hull < maxHull ? hull : maxHull;" tie dvojbodky a otázniky ma tam dobre mätú, nestretol som sa ešte s niečim takým :-):-) aj tak ďakujem pekne!

Zpět do poradny Odpovědět na původní otázku Nahoru