Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Pascal: Periytyminen useasta luokasta Delphissä

Janezki [07.09.2008 09:49:25]

#

En ole ihan varma tästä, mutta muistelen että Oliosuuntautuneen Ohjelmistokehityksen kurssilla mainittiin että olio voi saada ominaisuudet useasta luokasta. En ymmärtänyt sitä silloin enkä ole varma ymmärränkö vieläkään. Esitämpä ensin ongelmani.

TKE:ssä on monenlaisia ammuksia (Ammuksilla tarkoitan niitä instansseja jotka lentävät kentällä, en niitä jotka pelaajalla on taskussa). Osa ammuksista on fyysisiä entiteettejä (niillä on hitbox sekä normaalit fysiikkalaskut pätevät niihin) ja osa on vain yksinkertaisia matemaattisia malleja (kuten vanhan tk:n ammukset jotka joko osuvat viholliseen tai välähtävät vain maassa ja seinillä). Ongelma on se että kaikilla ammuksilla on ammusten ominaisuuksia (kuten vaurio ja tuhoutuminen osuessa), mutta panoksilla on myös ominaisuuksia jotka liittyvät niiden lentoratoihin (kuten äsken mainitsin fysiikka-ammuksista ja matematiikka-ammuksista). Tässä nykyinen entiteettihierarkia panosten osalta, sisennykset ilmaisevat periytymisen:

TMapEntity
 TVisualMapEntity
  TProjInstaGib
  TPhysEntity
   TCreature
    TBasicPlayer
   TProjPhys

TProjInstaGib on matemaattinen ammus ja TProjPhys on fyysinen. Periaatteessahan tässä ei ole ongelmaa kun tekee vain tuplana sen kuvitellun yleisen ammusluokan ominaisuudet kumpaankin luokkaan, mutta en haluaisi tehdä spagettikoodia. Ongelmia tulee lisäksi siinä kun TCreature ja TPhysEntity ottavat vastaan osuman ammuksesta. Näille luokille on ihan sama onko ammus InstaGib vai Phys, mutta koska yleistä ammusluokkaa ei ole, on hieman hankala lähettää ammuksen tietoja näiden luokkien käsiteltäviksi.

Eli kysymyksiin: Voiko olioon kapseloida toiminnallisuutta kahdesta eri luokasta? Onko ongelmaan joku muu järkevämpi ratkaisu?

User137 [07.09.2008 16:20:04]

#

Tuleeko ongelmia lisää jos yleisen ammus-luokan tekisi?

Delphissä voi käyttää abstrakteja aliohjelmia tai sitten hieman epävirallisempana keinona viitettä aliohjelmaan. Tuon aliohjelman voi määritellä kussakin luokassa ammuksen tyypin mukaan.

1 esimerkki viitteestä Delphin omissa kirjastoissa vaikka TButton.onClick event jolle design tila antaa arvon pääohjelman koodista.

Janezki [07.09.2008 17:09:41]

#

User137 kirjoitti:

Tuleeko ongelmia lisää jos yleisen ammus-luokan tekisi?

Delphissä voi käyttää abstrakteja aliohjelmia tai sitten hieman epävirallisempana keinona viitettä aliohjelmaan. Tuon aliohjelman voi määritellä kussakin luokassa ammuksen tyypin mukaan.

1 esimerkki viitteestä Delphin omissa kirjastoissa vaikka TButton.onClick event jolle design tila antaa arvon pääohjelman koodista.

Jos tekee erillisen ammusluokan niin silloin TProjPhysille pitäisi kopioida fyysisen objektin ominaisuudet, ja sitä koodia riittääkin enemmän kuin tarpeeksi. En edes näkisi sitä mielelläni vaihtoehtona.
Mietin myös sellaista vaihtoehtoa että TProjPhysin voisi korvata vain normaalilla entiteetillä joka törmätessään viholliseen vapauttaa itsensä ja luo uuden TInstaGib-ammuksen, joka hoitaa sitten itse vauriontekemisen. Menee tosin aika järjettömän kuulloiseksi.

Tarkoititko siis että tehdään itsenäiset proceduurit panosten toiminnallisuuden käsittelyyn ja sitten panosluokista vain kutsutaan niitä?

Metabolix [07.09.2008 19:57:21]

#

Delphissä ei ole moniperintää. Helpoiten pääset vastaavaan efektiin luultavasti juuri noilla ulkoisilla funktioilla. Yksi mahdollisuus on laittaa nämä yleiset ominaisuudet kuitenkin omaan luokkaansa ja käyttää tätä luokkaa sitten kummastakin ammustyypistä:

TProjGeneral = class
  function ...;
end;

TProjInstaGib = class of TMapEntity
  General: TProjGeneral;
end;

TProjPhys = class of TPhysEntity
  General: TProjGeneral;
end;

Janezki [07.09.2008 20:23:27]

#

Metabolix kirjoitti:

Yksi mahdollisuus on laittaa nämä yleiset ominaisuudet kuitenkin omaan luokkaansa ja käyttää tätä luokkaa sitten kummastakin ammustyypistä:

TProjGeneral = class
  function ...;
end;

TProjInstaGib = class of TMapEntity
  General: TProjGeneral;
end;

TProjPhys = class of TPhysEntity
  General: TProjGeneral;
end;

No tuo alkaa näyttämään jo säädylliseltä ratkaisulta. Kiitti Metabolix, oot pro.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta