Olio-ohjelmointi

Javaw

Olen lukenut 10-osaisen Java-oppaan Helsingin yliopiston sivuilta, jonka jälkeen lainasin kirjastosta Arto Wiklan kirjan Ohjelmoinnin perusteet Java-kielella. Lukeminen eteni hyvin, ja ymmärsin lukemani, kunnes pääsin sivulle 53; olio-ohjelmointo. Luin sitä pari sivua, ja olin "Mitä vittua????", en ymmärtänyt mitään. Kysymys siis kuuluu, onko olio-ohjelmointi välttämätöntä esim. 2D peliä tehdessä, voinko hypätä olio-ohjelmoinnnäim yli kirjassa?)

9

635

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • työssä näin skeidaa

      Java perustuu luokkiin joten olioasiat on syytä osata, ainakin jollakin tasolla.

      Älä välitä jos ohjelmasi ei ole täysin kaikkien olioperiaatteiden mukainen. Sama pätee moniin työelämän ohjelmiin. Myös olio-ohjelmoinnilla pystyy tuottamaan täyttä sotkua työelämässäkin ja spaghettikoodia joka jättää rivinumero-BASIC:in GOTO-salaatin varjoonsa.

    • Javaw

      Onko olio-ohjelmoinnista jotakin hyötyä siis? Olisiko jossakin (netissä) jotakin selvempää opasta kuin tuo mainitsemani kirja?

      En ymmärtänyt MITÄÄN.

      • hyötyäkin voi olla

        "Onko olio-ohjelmoinnista jotakin hyötyä siis?"

        Konkreettisin hyöty olio-ohjelmoinnista on ehkä siinä että ohjelmoija ja asiakas voivat puhua samoja termejä käyttäen. Asiakkaan ei tarvitse ymmärtää ohjelmointia ja sen problematiikkaa.

        Asiakas selittää probleemakentän alan termejä käyttäen ja ohjelmoija toteuttaa sen olio-ohjelmoinnilla niin että asiakkaan bisneslogiikan rakenne näkyy ohjelmassa hyvin selvästi.

        Kun ohjelmaan tarvitaan muutoksia (niinkuin aina ennenpitkää tarvitaan), niin asiakkaan ja ohjelmoijan on helpompi keskustella asiasta järkevästi kun ohjema selkeästi mallintaa asiakkaan ongelmakenttää. Tähän ainakin pyritään. Tietysti asiakkaan toivoma "pieni muutos" ei välttämättä ole teknisesti pieni...


      • pompom--

        "En ymmärtänyt MITÄÄN. "

        Tämä johtuu siitä, että olet idiootti. Ohjelmointi ei sovi ihan kenelle tahansa tollolle vaan se vaatii tietynlaista älyllistä ajattelukykyä, jota sinulta puuttuu.

        Mutta ei hätää, olisit luultavasti ihan pätevä rekkakuski.


      • aikuinen65
        pompom-- kirjoitti:

        "En ymmärtänyt MITÄÄN. "

        Tämä johtuu siitä, että olet idiootti. Ohjelmointi ei sovi ihan kenelle tahansa tollolle vaan se vaatii tietynlaista älyllistä ajattelukykyä, jota sinulta puuttuu.

        Mutta ei hätää, olisit luultavasti ihan pätevä rekkakuski.

        Sinulta tuntuu puuttuvan paljon enemmän. Joko olet noin 15-vuotias tai kys. ikäiseksi jäänyt peräkammarinpoika. Oikeata duunia et kykene tekemään, vain leikkimään ja pelaamaan.


    • ZeroOne

      Olio-ohjelmointi auttaa tekemään ohjelmastasi helpommin ymmärrettävän, uusiokäytettävän ja laajennettavan. Pienet ohjelmat voi toki kirjoittaa pötköön vaikkapa yhteen main-metodiin, mutta vähänkään isommissa kannattaa käyttää olioita. Oliot muun muassa auttavat piilottamaan turhia yksityiskohtia ohjelman muilta osilta, jotka suorittavat jotakin logiikkaa.

      Tässä on äkkiä googlaamani englanninkielinen johdatus olio-ohjelmointiin: http://sepwww.stanford.edu/sep/jon/family/jos/oop/oop1.htm Kirjoittaja on kuvauksensa perusteella lähtenyt samasta tilanteesta kuin sinä, joten jos jaksat tuon esityksen käydä ajatuksella läpi, se lienee valaiseva.

      Olio-ohjelmointi on oikeastaan aika luonnollinen tapa ajatella maailmaa. Kaikki substantiivit voidaan ajatella olioina. 2D-pelissä tulet varmasti tarvitsemaan olioita (ihan jo siksikin että jos Javalla olet jotakin koodannut, olet jo käyttänyt olioita). Ajatellaan vaikka autopeliä. "Auto" on selvästi ensimmäinen vastaan tullut substantiivi. Mitä ominaisuuksia on autolla? Voidaan vaikka vähän yleistää ja ajatella käsitettä "Ajoneuvo". Ajoneuvolla on usein pyörät: autoilla neljä, moottoripyörillä kaksi, rekoilla vaikkapa 16. Miten tämä sitten näkyisi Javassa? Vaikkapa näin (http://pastebin.com/6y1ad25W):

      public class Ajoneuvo {
      public int pyorienLukumaara;
      }

      Tuossa on erittäin yksinkertainen Java-luokka nimeltä Ajoneuvo. Luokalla on yksi kenttä, kokonaisluku nimeltä "pyorienLukumaara". Nyt aletaan vähitellen päästä asian pihviin. Edellä oleva koodipätkä on siis LUOKKA, ei vielä OLIO. Olio on luokan "instanssi" eli esiintymä. Luokka kuvaa käsitteen: ajoneuvo. Olio kuvaa jonkin tämän käsitteen "ruumiillistuman": sinun autosi, minun polkupyöräni, hänen rekkansa. Java-ohjelmointia opiskelleena tämä ei näyttäne sinulle vieraalta (http://pastebin.com/g06wRLq7):

      public class Ajoneuvotesti {
      public static void main(String... parametrit) {
      Ajoneuvo sinunAutosi = new Ajoneuvo();
      Ajoneuvo minunPolkupyorani = new Ajoneuvo();
      Ajoneuvo hanenRekkansa = new Ajoneuvo();
      }
      }

      Näin olemme luoneet Ajoneuvo-luokasta kolme oliota: sinunAutosi, minunPolkupyorani ja hanenRekkansa! Eihän ollut kovin vaikeaa? Tämä on nyt toistaiseksi vielä aika typerä esimerkki, sillä nuo oliot eivät eroa toisistaan mitenkään. Kokeillaanpas laittaa niille tuo ainut tieto minkä niille voi laittaa, eli pyörien lukumäärä. Koodi muuttuu seuraavanlaiseksi (http://pastebin.com/gRc3hGfV):

      public class Ajoneuvotesti {
      public static void main(String... parametrit) {
      Ajoneuvo sinunAutosi = new Ajoneuvo();
      sinunAutosi.pyorienLukumaara = 4;
      Ajoneuvo minunPolkupyorani = new Ajoneuvo();
      minunPolkupyorani.pyorienLukumaara = 2;
      Ajoneuvo hanenRekkansa = new Ajoneuvo();
      hanenRekkansa.pyorienLukumaara = 16;
      }
      }

      No, nyt niillä on pyörät, mutta aika pitkä koodihan tuosta tuli noin yksinkertaisen asian kertomiseksi, vai mitä? On totta, että Javalla joskus helpot asiat vievät tilaa enemmän kuin jollakin toisella ohjelmointikielellä, mutta kun Ajoneuvo-luokasta alkaa tulla monimutkaisempi, tuo main-metodi pysyy silti siistinä. Edellä olevaa koodia voisi hioa esimerkiksi tekemällä Ajoneuvolle niin kutsutun konstruktorin. Konstruktori on pätkä koodia, joka suoritetaan, kun luokasta luodaan uusi olio. Lue tuo pätkä vielä uudestaan, siinä tuli taas kaksi hengästyttävää termiä eli olio ja luokka. ;) Muista, "luokka" on asian yleinen kuvaus, "olio" on konkreettinen asia. Edellä luotiin kolme Ajoneuvo-oliota komennolla "new Ajoneuvo()". Tuossa "()" kuvaavat tyhjää konstruktoria: emme antaneet ajoneuvolle parametreja. Tehdäänpä sille konstruktori (http://pastebin.com/Jz8feTpB):

      public class Ajoneuvo {
      public int pyorienLukumaara;

      public Ajoneuvo(int pyorat) {
      this.pyorienLukumaara = pyorat;
      }
      }

      Okei? Ei vieläkään liian monimutkaista? :) Nyt voimme kertoa ajoneuvolle sen pyörien määrän heti kun luomme ajoneuvon (http://pastebin.com/X0ZyDbMP):

      public class Ajoneuvotesti {
      public static void main(String... parametrit) {
      Ajoneuvo sinunAutosi = new Ajoneuvo(4);
      Ajoneuvo minunPolkupyorani = new Ajoneuvo(2);
      Ajoneuvo hanenRekkansa = new Ajoneuvo(16);
      System.out.println("Fillarissa on " minunPolkupyorani.pyorienLukumaara " pyörää.");
      }
      }

      Tadaa! Olemme luoneet olioita, joille on konstruktorissa annettu arvoja. Lisäsin vielä System.out.println -tulostuskomennon (tarkkaan ottaen System-luokan out-kenttään tallennetun olion println-metodi!), joka tulostaa yhdestä oliosta sen pyörien lukumäärän.

      Tässä vasta hipaistiin olio-ohjelmoinnin pintaa. Edellä kuvatulla Ajoneuvo-luokalla oli vain yksi kenttä, pyorienLukumaara. Kenttiin tallennetaan olion "tila", tieto siitä, minkälainen olio on. Olion tilaa muutetaan yleensä sen _metodien_ kautta. Esimerkiksi autossa voisi olla korjaustilanteita varten metodi "irrotaRengas", joka vähentäisi siitä yhden pyörän (http://pastebin.com/DFgBc1Ax).

      (Nyt tuli merkkimäärä täyteen!)

      • ZeroOne

        Sitten tarvitaan myös metodi renkaan kiinnittämiseksi (http://pastebin.com/yi13XXuD). Nyt komento "minunAutoni.irrotaRengas();" vähentää minunAutoni -olion renkaiden lukumäärää yhdellä ja "minunAutoni.kiinnitaRengas();" lisää autoon yhden renkaan.

        No, fiksu ihminen kysyy tässä vaiheessa, että mihin noita metodeita tarvittiin, miksi ihmeessä en vain sanoisi suoraan että "minunAutoni.pyorienLukumaara--;" ja "minunAutoni.pyorienLukumaara ;" siellä missä haluan pyörien lukumäärää vaihtaa? Vastaan, että onneksi olkoon, tuo on loistava kysymys!

        Tässä päästään siihen, mistä sanoin jo aluksi: käyttämällä olioita saat piilotettua toteutuksesta yksityiskohtia, joista muun koodin ei tarvitse olla kiinnostunut. Esimerkki: renkaitakin on erilaisia: leveitä, kapeita, sileitä, nastarenkaita, jne jne. Tässä vaiheessa voidaan taas muistella, mitä sanoin aluksi: "Kaikki substantiivit voidaan ajatella olioina." Mitäs jos siis tehtäisiin luokka Rengas: http://pastebin.com/E1g8MDJH.

        Pitkä ja hankalan näköinen? Ei oikeastaan. Emme käyttäneet tässä melkein mitään tekniikoita, mitä emme olisi jo käyttäneet Ajoneuvon kanssa: mukana on vain tällä kertaa kolme kenttää (kuvio, leveysMillimetria ja nastat), konstruktori, joka ottaa kolme parametria sekä lopuksi kolme metodia, jotka palauttavat luokan kenttien arvot. Metodien käyttö olion tilan kyselyyn on yleensä hyvä käytäntö sen sijaan että käyttäisimme suoraan olion kenttiä, syystä jota olen tässä juuri selittämässä, eli että ne piilottavat alla olevan toteutuksen. Rengas-luokassa kenttiin ei edes pääse luokan ulkopuolelta suoraan käsiksi, koska ne on esitelty avainsanalla "private" Ajoneuvossa käytetyn avainsanan "public" sijaan.

        Palataan hetkeksi ajoneuvoon, lisätään siihen vastaava ajoneuvon renkaiden lukumäärän kertova metodi: http://pastebin.com/auku58PL. Samassa yhteydessä muutin public-kentän privateksi, joten joudumme testiohjelmassamme vaihtamaan rivin 'System.out.println("Fillarissa on " minunPolkupyorani.pyorienLukumaara " pyörää.");' riviksi 'System.out.println("Fillarissa on " minunPolkupyorani.kerroPyorienLukumaara() " pyörää.");' että se toimisi.

        No, miksi taas tehtiin niin vaikeasti? Koska jos nyt muutat Ajoneuvon sisäistä toteutusta, sinun ei enää tarvitsekaan muuttaa testiohjelmaasi! Tehdäänpä uusi versio ajoneuvosta, sellainen, johon voidaan asettaa erilaisia pyöriä: http://pastebin.ca/2379557

        Ajoneuvo-luokka oli niin yksinkertainen, että se muuttui väkisinkin ehkä aika paljon, mutta pointtina minulla oli metodi kerroPyorienLukumaara(): se kertoo edelleen ajoneuvon pyörien lukumäärän, vaikka ajoneuvossa ei enää ole pyorienLukumaara-kenttää, vaan lista Rengas-olioita! Listaan on tallennetu ajoneuvon yksittäiset renkaat. Kokonainen käyttöesimerkki voisi olla vaikka tällainen: http://pastebin.ca/2379559

        Tuossa luodaan Ajoneuvo-luokasta uusi olio nimeltä minunPolkupyorani ja kiinnitetään siihen kaksi 50 mm leveää karkeaa rengasta, joista toinen on kulunut ja joista kummassakaan ei ole nastoja. :) Aika helppoa loppujen lopuksi, eikö?


      • ZeroOne
        ZeroOne kirjoitti:

        Sitten tarvitaan myös metodi renkaan kiinnittämiseksi (http://pastebin.com/yi13XXuD). Nyt komento "minunAutoni.irrotaRengas();" vähentää minunAutoni -olion renkaiden lukumäärää yhdellä ja "minunAutoni.kiinnitaRengas();" lisää autoon yhden renkaan.

        No, fiksu ihminen kysyy tässä vaiheessa, että mihin noita metodeita tarvittiin, miksi ihmeessä en vain sanoisi suoraan että "minunAutoni.pyorienLukumaara--;" ja "minunAutoni.pyorienLukumaara ;" siellä missä haluan pyörien lukumäärää vaihtaa? Vastaan, että onneksi olkoon, tuo on loistava kysymys!

        Tässä päästään siihen, mistä sanoin jo aluksi: käyttämällä olioita saat piilotettua toteutuksesta yksityiskohtia, joista muun koodin ei tarvitse olla kiinnostunut. Esimerkki: renkaitakin on erilaisia: leveitä, kapeita, sileitä, nastarenkaita, jne jne. Tässä vaiheessa voidaan taas muistella, mitä sanoin aluksi: "Kaikki substantiivit voidaan ajatella olioina." Mitäs jos siis tehtäisiin luokka Rengas: http://pastebin.com/E1g8MDJH.

        Pitkä ja hankalan näköinen? Ei oikeastaan. Emme käyttäneet tässä melkein mitään tekniikoita, mitä emme olisi jo käyttäneet Ajoneuvon kanssa: mukana on vain tällä kertaa kolme kenttää (kuvio, leveysMillimetria ja nastat), konstruktori, joka ottaa kolme parametria sekä lopuksi kolme metodia, jotka palauttavat luokan kenttien arvot. Metodien käyttö olion tilan kyselyyn on yleensä hyvä käytäntö sen sijaan että käyttäisimme suoraan olion kenttiä, syystä jota olen tässä juuri selittämässä, eli että ne piilottavat alla olevan toteutuksen. Rengas-luokassa kenttiin ei edes pääse luokan ulkopuolelta suoraan käsiksi, koska ne on esitelty avainsanalla "private" Ajoneuvossa käytetyn avainsanan "public" sijaan.

        Palataan hetkeksi ajoneuvoon, lisätään siihen vastaava ajoneuvon renkaiden lukumäärän kertova metodi: http://pastebin.com/auku58PL. Samassa yhteydessä muutin public-kentän privateksi, joten joudumme testiohjelmassamme vaihtamaan rivin 'System.out.println("Fillarissa on " minunPolkupyorani.pyorienLukumaara " pyörää.");' riviksi 'System.out.println("Fillarissa on " minunPolkupyorani.kerroPyorienLukumaara() " pyörää.");' että se toimisi.

        No, miksi taas tehtiin niin vaikeasti? Koska jos nyt muutat Ajoneuvon sisäistä toteutusta, sinun ei enää tarvitsekaan muuttaa testiohjelmaasi! Tehdäänpä uusi versio ajoneuvosta, sellainen, johon voidaan asettaa erilaisia pyöriä: http://pastebin.ca/2379557

        Ajoneuvo-luokka oli niin yksinkertainen, että se muuttui väkisinkin ehkä aika paljon, mutta pointtina minulla oli metodi kerroPyorienLukumaara(): se kertoo edelleen ajoneuvon pyörien lukumäärän, vaikka ajoneuvossa ei enää ole pyorienLukumaara-kenttää, vaan lista Rengas-olioita! Listaan on tallennetu ajoneuvon yksittäiset renkaat. Kokonainen käyttöesimerkki voisi olla vaikka tällainen: http://pastebin.ca/2379559

        Tuossa luodaan Ajoneuvo-luokasta uusi olio nimeltä minunPolkupyorani ja kiinnitetään siihen kaksi 50 mm leveää karkeaa rengasta, joista toinen on kulunut ja joista kummassakaan ei ole nastoja. :) Aika helppoa loppujen lopuksi, eikö?

        Lopuksi vielä muutama sana perinnästä, joka on pelottava termi, jonka olet jossain kirjassa tai muussa materiaalissa jo nähnyt. Vedä henkeä, ei tämäkään ole vaikeaa. :) Ajoneuvo on yläkäsite monille asioille: esimerkiksi fillareille, autoille ja rekoille. Perintää voidaan hyödyntää tilanteissa, joissa meillä on olioita, joilla on jotakin samaa, mutta myös joitakin eroja. Kaikilla ajoneuvoilla on esimerkiksi pyörät. Muokataan Ajoneuvo-luokka seuraavanlaiseksi: http://pastebin.ca/2379563

        Oho, mitäs nyt tapahtui? Luokan ensimmäiselle riville ilmaantui sana "abstract" ja metodi "public abstract int kerroPyorienLukumaara();" ei näytä palauttavan mitään. No, muutin Ajoneuvon ns. abstraktiksi luokaksi. Se tarkoittaa, ettei Ajoneuvosta voida enää suoraan muodostaa olioita: "new Ajoneuvo();" ei enää toimi, vaan tarvitaan jotakin tarkempaa... vaikkapa "new Henkiloauto();" tai "new Polkupyora();": http://pastebin.ca/2379566 (Huom: laita nuo molemmat luokat omiin tiedostoihinsa: Henkiloauto.java ja Polkupyora.java.)

        Tässä Henkiloauton ja Polkupyoran sanotaan LAAJENTAVAN Ajoneuvo-luokkaa. Ajoneuvo-luokassa oleva "abstract int kerroPyorienLukumaara()" tarkoittaa abstraktia metodia, eli luokkien, jotka laajentavat Ajoneuvoa, tulee TOTEUTTAA tuo "kerroPyorienLukumaara()" metodi. Esimerkkitoteutukseni palauttavat vain vakioluvut, mutta kuten aiemmin nähtiin, luokan sisällä voi olla mitä tahansa logiikkaa, kunhan sen lopputuloksena vain saadaan vastaukseksi pyörien lukumäärää kuvaava kokonaisluku. :) Käyttöesimerkkinä voisi olla sitten vaikka tällainen: http://pastebin.ca/2379567 Huomaatko, kuinka teemme esimerkiksi olion "Ajoneuvo sinunAutosi", mutta annamme sille arvon "new Henkiloauto()"? Olisimme voineet myös sanoa "Henkiloauto sinunAutosi = new Henkiloauto();", mutta tällöin Java ei tunnistaisi "autoa" ja "polkupyörää" samaan hierarkiaan eli ajoneuvoihin kuuluviksi. Niiden metodeita voisi edelleen käyttää, mutta ne eivät olisi enää vertailukelpoisia. Pyörien lukumäärä alkaa olla aika venytetty esimerkki, mutta venytetään nyt sitten kun alkuun ollaan päästy, ja lisätään metodi, jolle voi antaa kaksi ajoneuvoa, ja joista se laskee pyörien yhteismäärän: http://pastebin.ca/2379568

        Uudelle "kerroPyorienYhteismaara(Ajoneuvo a, Ajoneuvo b)" -metodille voi nyt antaa parametreiksi mitä tahansa, mikä laajentaa Ajoneuvo-luokkaa. Paljon ankeampaa olisi ollut tehdä esimerkiksi erilliset metodit "kerroPyorienYhteismaara(Henkiloauto a, Henkiloauto b)", "kerroPyorienYhteismaara(Henkiloauto a, Polkupyora b)" ja "kerroPyorienYhteismaara(Polkupyora a, Polkupyora b)", eikö totta?

        Vielä toiseksi viimeinen huomio: abstrakteissakin luokissa voi olla toteutuksia metodeille. Tämä on erityisen kätevää, kun hyödynnetään metodeita, joiden toteutukset sijaitsevat luokan aliluokissa. Esimerkiksi auton tulisi tietää kulutuksensa satasella ja tankissa olevan bensan määrä. "Auto" voi olla turhan yleinen käsite esimerkiksi autopeliin jossa on useita erilaisia autoja, joten se olisi hyvä ehdokas abstraktiksi luokaksi. Esimerkiksi siis näin: http://pastebin.ca/2379574

        Nyt kun teet vaikkapa luokat "public class Ferrari extends Auto" ja "public class Audi extends Auto" ja määrittelet toteutukset metodeille "kerroKulutusSatasellaLitroina()" ja "kerroTankissaOlevanBensanMaaraLitroina()", voit hyödyntää niiden yhteisessä yläluokassa määriteltyä metodia "kerroJaljellaOlevaSuurinMahdollinenAjomatkaKilometreina()". :)

        Ja vielä viimeinen huomio: luokan ei ole pakko olla abstrakti, että sitä voisi laajentaa. Ei mennä tähän sen enempää, riittää että tiedät asian etkä hämmästy kun se tulee vastaan. :)


    • Annan nyt oman panokseni tähän keskusteluun. Olio - perusteisen lähestymistavan omaksuminen on oleellista Javassa, jotta voi ymmärtää kielen.

      String mjono = "Tarjoan koulutusta Javasta kiinnostuneille!";

      Tuossa oikeastaan luodaan mjono -niminen olio, joka on tietotyypiltään String. Seuraavaksi voidaan luodun olion kautta kutsua String -tietotyypissä määriteltyjä palveluja ja metodeja, esim.

      boolean koulutustatarjollako = mjono.contains("koulutus");

      Olio -pohjainen ohejlmointi säästää aikaa ja vaivaa myös, ja samaa koodia ei tarvitse toistaa useaan kertaan.

      Tässä nyt jotain mietteitäni. Jos joku kiinnostui tarjoamastani koulutuksesta, voi lukea Tori -palstalta tarjoukseni!

    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Et olisi piilossa enää

      Vaan tulisit esiin.
      Ikävä
      73
      3305
    2. Minä en ala kenenkään perässä juoksemaan

      Voin jopa rakastaa sinua ja kääntää silti tunteeni pois. Tunteetkin hälvenevät aikanaan, poissa silmistä poissa mielestä
      Ikävä
      68
      1889
    3. Loukkaantunut lapsi on yhä kriittisessä tilassa

      Seinäjoella Pohjan valtatiellä perjantaina sattuneessa liikenneonnettomuudessa loukkaantunut lapsi on yhä kriittisessä t
      Kauhava
      31
      1881
    4. Tiedän, että emme yritä mitään

      Jos kohtaamme joskus ja tilaisuus on sopiva, voimme jutella jne. Mutta kumpikaan ei aio tehdä muuta konkreettista asian
      Ikävä
      16
      1431
    5. Miten hetki

      Kahden olisi paras
      Ikävä
      28
      1381
    6. Mitä, kuka, hä .....

      Mikähän sota keskustassa on kun poliiseja on liikkeellä kuin vilkkilässä kissoja
      Kemi
      25
      1296
    7. Näin pitkästä aikaa unta sinusta

      Oltiin yllättäen jossain julkisessa saunassa ja istuttiin vierekkäin, siellä oli muitakin. Pahoittelin jotain itsessäni
      Ikävä
      6
      1286
    8. Noh joko sä nainen oot lopettanut sen

      miehen kaipailun jota sulla EI ole lupa kaivata. Ja teistä ei koskaan tule mitään. ÄLÄ KOSKAAN SYÖ KUORMASTA JNE! Tutu
      Ikävä
      63
      1197
    9. Taisit sä sit kuiteski

      Vihjata hieman ettei se kaikki ollutkaan totta ❤️ mutta silti sanoit kyllä vielä uudelleen sen myöhemmin 😔 ei tässä oik
      Ikävä
      10
      1197
    10. Kerro nainen

      Milloin huomasit, että kyse ei ole ihastumisesta vaan jostain selvästi vakavammasta.
      Ikävä
      53
      945
    Aihe