Yritän tehdä sellaista systeemiä että on vektori, johon voi säilöä sellaisia olioita, jotka tietävät omistajansa (owner) eli mihin vektoriin kuuluvat.
No, ajattelin tehdä tämän ihan niin että jokainen tällainen säilöttävä olio toteuttaa rajapinnan
public interface Owned
{
public E getOwner();
public void setOwner(E newOwner);
}
Sitten se vektoriluokka johon näitä olioita säilötään
public class OwnerVector
No, ajattelin tehdä tämän ihan niin että jokainen tällainen säilöttävä olio toteuttaa rajapinnan
public interface Owned
{
public E getOwner();
public void setOwner(E newOwner);
}
Sitten se vektoriluokka johon näitä olioita säilötään
public class OwnerVector
Vastaukset 6
Vanhimmat
> public class OwnerVector
Ja tuli mieleen, että jos sulla ei ole jotain spesifistä tarvetta käyttää genericsejä, niin ehkä seuraava olis yksinkertaisempaa:
public interface Owned {
public OwnedVector getOwner();
public void setOwner(OwnedVector newOwner);
}
Owner on aina tyyppiä OwnerVector (tai sen aliluokka..), joten sitä ei tarvitse merkitä genericseillä.
public class OwnerVector extends Vector {
...
}
OwnerVectorin elementit ovat nyt Owned-rajapinnan toteuttavia luokkia, ja kaikki vectoria muokkaavat tai tietoja hakevat metodit ottavat vastaan ja palauttavat Owned-olioita.
class OwnedClass implements Owned {
...
}
class SomeGroup extends OwnerVector {
...
}
Ja nämä sitten ovatkin triviaaleja..
Ajattelin kyllä ihan käyttää tuota vektoriluokkaa (ja rajapintaa) ihan geneerinä, kun se jatkuva tyyppimuuntelu on rasittava ja sekin luo vähän turhaa overheadia.
No kuitenkin, olen kokeillut myös tuota muotoa
public class OwnerVector
> Ajattelin kyllä ihan käyttää tuota vektoriluokkaa
> (ja rajapintaa) ihan geneerinä, kun se jatkuva
> tyyppimuuntelu on rasittava ja sekin luo vähän
> turhaa overheadia.
Mitä tyyppimuuntelua tarvitsisit? Voit käyttää Owned-rajapintaa kaikkialla, vaikka toteuttava luokka olisikin jokin muu.
Esim. jos laajennat Vector-luokan add-metodia, sinne tulee näin:
public boolean add(Owned obj) {
...
}
ja metodia voi käyttää koodissa esim.
SomeGroup group = new SomeGroup();
OwnedClass o = new OwnedClass();
group.add(o);
ja kaikki toimii ihan oikein
Sun ongelmasi on oikeastaan aika perinteinen olio-ohjelmointitilanne, eikä sitä genericsejä käyttämällä ainakaan yksinkertaisemmaksi saa.
Totta kai käytän geneeristä luokkaa tässä tapauksessa, koska johdettu vektoriluokka on periaatteessa ihan sama kuin geneerinen Vector pl. tuo omistus-ominaisuus.
Siis esim. get-metodi palauttaa oikean tyyppisen olion eikä sitä tarvitse tyyppimuuntaa, toisin kuin ilman geneerisyyttä.
No okei, sitten sun pitää käyttää OwnerVectoria kuten geneeristä Vectoria, eli kokoelmana. Owned-rajapinnasta tulee siis tämmöinen:
public interface Owned {
public OwnerVector getOwner();
public void setOwner(OwnerVector owner);
}
ei kai Owned-instanssien tarvitse tietää, mikä sen ownerin oikea tyyppi on, riittää että se on OwnerVector. (niinkuin yleisestikin vector-luokkaa käytetään suoraan, sitä ei laajenneta..)
Ja OwnerVector määritellään siis näin:
class OwnerVector extends Vector
ja käyttö:
// Owned-toteutuksia
OwnedImpl1 own1 = new OwnedImpl1();
OwnedImpl2 own2 = new OwnedImpl2();
OwnerVector v1 = new OwnerVector();
OwnerVector v2 = new OwnerVector();
v1.add(own1);
v2.add(own2);
...
own1.getOwner() // paluutyyppi OwnerVector
own2.getOwner() // paluutyyppi OwnerVector
v1.get(0); // paluutyyppi on OwnedImpl1
v2.get(0); // paluutyyppi on OwnedImpl2
Mä luulen, että sun ongelma noiden genericsien kanssa oli se, ettei java oikein osaa hanskata rekursiivisia generics-määrityksiä, siis tyyliin:
class Owned ja
class OwnerVector
eli jommastakummasta päästä kannattaa genericsit pudottaa pois.