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]

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
Neviem jak sa to da urobit v jave ptz compilery mozu mat speciality tykajuce sa konstant apod. ja ni… nový
MM.. 10.08.2012 21:23
MM..
Ten prvý návrh som asi nepochopil (hovorím že som začiatočník, v podstate prvý krát sedím pred IDE),… nový
wewo 10.08.2012 21:35
wewo
Ve třídách máš ty proměnné statické, v supertřídě statické nejsou. Obecně se dá říct, že míchat dědi… nový
Wikan 10.08.2012 21:50
Wikan
S tými statickými a nestatickými premennými mám trochu bordel, pravda :-) Oni boli do Spaceship trie… nový
wewo 11.08.2012 14:03
wewo
normalny member neni konstanta a neni staticky. Proste to zadeklaruj ako normalny integer, v sekcii… nový
MM.. 11.08.2012 00:47
MM..
Aha, takže Java: public abstract class Spaceship { private int hull; private int maxHull; public Sp… nový
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… nový
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
Konštanty MAX_HULL a STANDART_HULL by nemali byť konštantami, ale atribútmi základnej triedy Spacesh… nový
los 10.08.2012 21:47
los

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!

Neviem jak sa to da urobit v jave ptz compilery mozu mat speciality tykajuce sa konstant apod. ja nie som na javu. Vseobecne ale vlastne chces vytvorit pre kazdu podtriedu odlisny kod fcie setHull, ptz konstanta je sucast kodu, a nie member triedy, a to je v rozpore s tym ze ta spolocna funkcia ma byt stejna.
Ked ma byt spolocna fcia stejna, tak by som jej dal MAX_HULL ako druhy parameter. Alebo urobit MAX_HULL ako normalneho membera supertriedy, a ked vytvaras podtriedu tak ho nastavis v konstruktore normalne na nejaku hodnotu.

P.S. ale ja nie som moc na sialenstva v OO, OO pouzivam len vtedy ked to ma vyznam co neni moc casto, pockaj si na OO specialistov mozno ti tu niekto napise aj ine moznosti.

Ten prvý návrh som asi nepochopil (hovorím že som začiatočník, v podstate prvý krát sedím pred IDE), ten druhý... Ako mám urobiť MAX_HULL normálneho membera supertriedy? :-) Teraz je nenormálny? :-) Je tam deklarovaný (a je mu implicitne priradená hodnota 0), v každej podtriede je tiež deklarovaný (a teda override-nutý, ak sa nemýlim), ale metóda supertriedy berie aj tak MAX_HULL od seba, nie od podtriedy, aj keď tú metódu volám na podtriedu :-(

P.S.: Rozumiem, aj keď mne sa OO veľmi pozdáva. V tomto prípade uprednostňujem formu pred obsahom, celé toto s vesmírnymi loďami som si iba vymyslel aby som sa mohol pohrať s OO, a aby som presne tieto veci ktoré teraz riešim dobre ovládol :) Je to jednoduchá vec, a chcem vedieť ako by to urobil niekto naozaj OO skúsený :)

Ďakujem pekne aj tak.

S tými statickými a nestatickými premennými mám trochu bordel, pravda :-) Oni boli do Spaceship triedy iba narýchlo dopísané, aj tak som ich chel v podstriedach overridnuť :-) U6 ale viam ako na to...

A odvodené triedy sa určite budú lísiť aj v správaní, nie len v hodnotách vlastností, žiaden strach :) Som v tom programe len na začiatku :)

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!

Konštanty MAX_HULL a STANDART_HULL by nemali byť konštantami, ale atribútmi základnej triedy Spaceship (prípadne protected read-only vlastnosťami, ak s nimi potrebuješ pracovať v zdedených triedach). Nastavovať by sa mali len pomocou konštruktora a mali by byť zohľadnené v setteri vlastnosti hull v základnej triede. Potom už nemusíš písať ďalšie settery pre vlastnosť hull v zdedených triedach.

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