Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: [Java] metodin nimessä muuttuja?

Sivun loppuun

Tommittaja [12.06.2009 19:01:02]

#

Kuten otsikko sanoo: voiko metodin nimessä olla kutsuttaessa esim: int muuttujaa, jotta voisi "skrollata" metodeita...

public class luokka {
    public static void metodi1() {
         //toiminto
    }
    public static void metodi2() {
         //toiminto
    }
    public static void metodi3() {
         //toiminto
    }
    public static void main(String[] args) {
        int i;
        for (i = 1; i < 4; i++) {
        metodi+i();
    }
}

Tyyliin? voiko jotenkin noin tehdä? ihan mikä vaan tapa, jolla voi tehdä noin, käy...

Jackal von ÖRF [12.06.2009 19:42:24]

#

Ei onnistu tuo Javassa, ainakaan muuten kuin reflektiolla. Joissakin dynaamisesti tyypitetyissä kielissä tuo voi onnistua (esim. PHP:ssa onnistuu).

Miksi yrität tehdä noin?

Laurelin [12.06.2009 22:37:28]

#

Lopulta olisi järkevää opetella nimeämään jokainen metodi yksilöllisesti. Jos koodiaan katsoo yhtään myöhemmin uudestaan, on yllättävän hankalaa saada kiinni ajatuksenjuoksustaan jo yksinkertaisissa ohjelmissa.

Ehdottamasi ajatus on käynyt kai sitten muidenkin aloittelevien ohjelmoivien kuin minun mielessäni. :> Tuo reflektio vaikuttaa pikavilkaisulla turhankin edistyneeltä – jos välttämättä haluat käydä epäintuitiivisesti nimettyjä metodeja läpi silmukassa, sopisiko tilanteeseen kätevä pieni switch–case?

public class luokka {

    public static void metodi(int i) {
        switch (i) {
        case 1: metodi1(); break;
        case 2: metodi2(); break;
        case 3: metodi3(); break;
        }
    }

    public static void metodi1() {
         //toiminto
    }
    public static void metodi2() {
         //toiminto
    }
    public static void metodi3() {
         //toiminto
    }

    public static void main(String[] args) {
        for (int i = 1; i < 4; i++) {
            metodi(i);
        }
    }
}

Jackal von ÖRF [13.06.2009 11:43:31]

#

Nimet metodi1, metodi2 jne. eivät tosiaankaan kerro mitään metodin tarkoituksesta, joten missään todellisessa ohjelmassa ei pitäisi olla tarvetta tehdä noin. Tässä artikkeli siitä, miten muuttujat/metodit/luokat kannattaa nimetä: http://tottinge.blogsome.com/meaningfulnames/

Tommittaja [13.06.2009 13:42:34]

#

Tarvitsisin noita siihen ASCII-peliin, jota olen tekemässä, sillä kun tein siitä liikkumisesta sen metodin, en saa mentyä seuraavaan kenttään vain kirjoittamalla liikkumiseen taso1(); tai taso2(); yms... joten ajattelin, olisiko tuommoista tapaa olemassa. keksin juuri kylläkin toisen tavan, joka tosin vie enemmän rivejä, mutta toimii yhtä hyvin...
Metodit sitäpaitsi eivät tee muuta tuossa pelissä, kuin ovat kenttiä, joten nimi "taso1" ja "taso2" yms kertovat kaiken tarvittavan.. no, katson nyt miten tuon teen... :)

Ps: olen lukenut tuon "meaningfulnames" monta kertaa :D

Teuro [13.06.2009 13:47:26]

#

Mutta eihän liikkumismetodi voi olla riippuvainen kentän tasosta mitenkään? Ja muutoinkin eihän tuollaisella ohjelmoinnilla pääse puusta pitkään, koska joudut tekemään siis jokaiselle tasolle oman metodin, joka on oleellisilta osiltaan identtinen.

Tommittaja [13.06.2009 13:53:55]

#

en joudu, teen sen tällä rakenteella:

liikkumismetodi {

}
taso1() {
   taulukko yms {
   }
   liikkuminen()
}
taso2() {
   taulukko yms {
   }
   liikkuminen()
}

yms...
ja keksin jo tavan, minne sinne laitan ja miten sen tasonvaihdon :D

Edit: laitan siis sinne maalivertailun sisään, toisen vertailun, että onko esim taso1()=mennään tasoon2() ja niinpoispäin...

Edit: saako niitä hippatekoälyjä enää mistään ladattua, kun ajattelin katsoa mallia niistä, jos tekisin itseään seuraavan vihollisen? enkä itse osaa suoraan...

Teuro [13.06.2009 13:56:11]

#

Millä tavalla nuo kaksi metodia ovat erilaisia, kun minusta ne ovat aivan identtiset, jos nimeä ei lasketa.

Tommittaja [13.06.2009 13:58:54]

#

niissä on erilainen taulukko, sillä koko pelihän toimii talukossa, taulukko on vain erilainen/kokoinen, eri elementit ja kaikki.

Sisuaski [13.06.2009 14:11:07]

#

No miksi niille taulukoille sitten tarvitaan omat funktiot?
Mikset tee vain yhtä funktiota, ja syöttele sille noita taulukoita parametrina?

Teuro [13.06.2009 14:12:36]

#

Entä jos tekisi yhden oikein hyvän kenttäfunktion, joka osaa lukea tiedostosta kenttien speksit? Tällöin riittäisi tosiaan yksi kentän latausfunktio.

/* Kentän speksit */
vihu|12857|16859|30|61.7|8
vihu|9584|3257|68|81.9|3
kentta|25000|40000
maali|26354|37854

Yllä oleva on pätkä kenttätiedostoa, jonka pohjalta uusi kenttä voidaan ladata. Esimerkiksi vihu 12857 16859 30 61.7 8 voisi tarkoittaa, että luodaan vihu luokasta uusi olio, joka on kentällä pisteessa 12857 16859 hänellä on 30 % energiaa hänellä on 61.7 % todennäköisyys osua, sekä hänellä on 8 kutia lippaassa. Loput lienevät selviä?

Latausfunktio voisi toimia jotenkin seuraavasti

<?php
$taso = file("taso1.txt");
$riveja = count($taso);

for($i = 0; $i < $maara; $i++){
    $tiedot = explode("|", $taso[$i]);

    if($tiedot[0] == 'vihu'){
        Vihut[] = new Vihollinen($tiedot[1], $tiedot[2], $tiedot[3], $tiedot[4], $tiedot[5]);
    }else if($tiedot[0] == 'kentta'){
        $kentta->asetaKoko($tiedot[1], $tiedot[2]);
    }else if($tiedot[0] == 'maali'){
        $kentta->asetaMaali($tiedot[1], $tiedot[2])
    }
}
?>

Tommittaja [13.06.2009 14:17:51]

#

öhöm?? väärä kieli :D ja sen tason taulukon pitää olla _juuri_ tietynlainen...

Teuro [13.06.2009 14:23:17]

#

Javan standardikirjastosta löytynee vastaavat funktiot tuolle. Millä tavalla taulukon pitää olla tieynlainen?

Tommittaja [13.06.2009 14:27:40]

#

esim: taso1() = tällainen:

#########
# #   #
# # # # #
# # # # #
# # # # #
# # # # #
#   #   #
#########

ja en oikeastikaan välttämättä jaksaisi laittaa kaikkea mahdollista hienoa sinne peliin, kun se toimii ihan yhtä hyvin omalla tavallanikin..

Teuro [13.06.2009 16:53:51]

#

Et välttämättä nyt halua, mutta joskus voi tulla halua ja silloin tuolla periaatteella tehtynä jotkut muutokset voivat olla paljon helpompia, kuin tuosssa sinun versiossasi.

Sami [13.06.2009 22:30:31]

#

Jos välttämättä haluat taulukoida ne, niin mikset tee niistä taulukoista taulukkoa, jolloin voit valita oikean tason valitsemalla taulukosta oikean alkion?

Ruutu[][][] tasot = new Ruutu[][][]{
  // Alustukset...
};

Mutta silti tiedosto(i)sta lukeminen olisi merkittävästi fiksumpi tapa tehdä tuo ja sinunkin pitäisi jo osata toteuttaa se (esim. Scanner + switch/if).

P.S. Mitä väliä sillä on millä kielellä Teuro antaa esimerkkinsä, kun tarkoituksena ei ole välittää valmista toimivaa koodia, vaan idea siitä kuinka asian voisi toteuttaa. Tähän tarkoitukseen esim. C, C++, PHP, Java, pseudokoodi tai jokin basic-variantti kävisivät kaikki aivan yhtä hyvin.

hk [14.06.2009 01:15:04]

#

Koskaan ei ole tarvetta valita metodia parametrin perusteella, sillä on aina mahdollista määritellä yksi metodi tekemään täysin eri asiat parametrin perusteella, jolloin tulos on sama.

Intuitiivisesti väitän myös että väite "With that caveat in mind, reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible." on virheellinen.

Java on yleiskäyttöinen kieli ilman reflektiotakin, ja sillä on mahdollista toteuttaa mikä tahansa missä tahansa konekielessä mahdollinen algoritmi. Se voi olla työlästä, mutta koska konekielikäskyjä on rajallinen määrä, on myös mahdollista toteuttaa miten tahansa muokattavissa oleva Java-koodin pätkä perus-Javalla. En siis väitä, etteikö reflektio olennaisesti lyhentäisi tarvittavaa Java-koodia jossain tilanteessa.

Jackal von ÖRF [14.06.2009 15:11:28]

#

Monissa frameworkeissa reflektion käyttö on pakollista. Ajattele vaikka, miten JUnit voisi löytää suoritettavat testit ilman reflektiota. Tai miten Javan serialisaatio, ORM-frameworkit (esim. Hibernate), DI-frameworkit (esim. Guice) ynnä muut pitäisi toteuttaa, jos kielessä ei olisi reflektiota. Se vaatisi frameworkin käyttäjältä älyttömästi itseään toistavan koodin kirjoittamista tai esim. käännösaikaista koodin generointia.

Ja sitten kun reflektio ei enää riitä, niin lisäavuksi otetaan tavukoodin analysointi, generointi ja manipulointi. Joissain muissa kielissä (esim. Lisp) on parempi tuki ohjelman rakenteen muuttamiselle, mutta Javassa joudutaan käsittelemään tavukoodia.

Tommittaja [14.06.2009 17:54:47]

#

En osaa lukea tiedostoista. ja tuo switch if-juttu?

Laurelin [14.06.2009 18:14:25]

#

Sami taisi tarkoittaa vain, että käyttäisit Scannerin kaverina switch–casea tai if-lausetta.

Kelpaisiko sinulle Arto Wiklan Java-kursseilla käytettävä materiaali? Sieltä löytyy myös perusasiaa tiedostoista.

Sami [14.06.2009 18:37:32]

#

Tommittaja kirjoitti:

En osaa lukea tiedostoista. ja tuo switch if-juttu?

No opetetaanpa...

File tiedosto = new File("tiedosto.txt");
try {
	Scanner skanneri = new Scanner(tiedosto);

	// Ja sitten vaan käytät sitä skanneria...
} catch (FileNotFoundException e) {
	System.err.println("Tiedosto hukassa.");
}

Tietääkseni olet jo opetellut käyttämään Scanner-luokkaa, joten tiedoston lukeminen ei eroa millään tavalla merkkijonojen parsimisesta (paitsi että tiedoston lukeminen voi epäonnistua).

Tommittaja [14.06.2009 20:46:23]

#

kiitos tuosta! olen jo pitkään seissyt paikallani tässä opettelussa, sillä ei kirjaa, vaikkakin koko arto wiklan materiaalin saa netistä ;D... voisin kyllä ostaa sen kirjan jostain huuto.netistä, etten ihan jumiin jää.
muuten, kun se tiedosto, josta luetaan, on samassa kansiossa, kun se .class-tiedosto, niin eihän pathia tarvitse olla(siis muutakuin sen tiedoston nimi)?

PS: mikä hyöty on kirjoittaa esim:

catch (FileNotFoundException e)

kun voi kirjoittaa vain

catch (Exception e)

?

Metabolix [14.06.2009 20:52:45]

#

Tommittaja kirjoitti:

PS: mikä hyöty on kirjoittaa esim:

Jotta voi käsitellä erilaiset virheet eri tavalla ja vaikka tulostaa suomenkieliset virheilmoitukset ("tiedostoa ei löydy", "virhe tiedoston lukemisessa" jne.).

hk [14.06.2009 20:58:29]

#

Tommittaja kirjoitti:

PS: mikä hyöty on kirjoittaa esim:

catch (FileNotFoundException e)

kun voi kirjoittaa vain

catch (Exception e)

?

No ei mitään hyötyä, jos ohjelma toimii oikein. Mutta pyydystämällä vain ne poikkeukset, joita odotetaan, huomataan jos tuleekin muita, sellaisia joita ohjelmoija ei ole odottanut. Jos niitä tulee, on koodissa virhe, joka voisi peittyä, jos kaikki poikkeukset käsitellään tavalla, joka on tarkoitettu vain tiettyä tilannetta varten. Esim. joku poikkeus ei jossain tilanteessa aiheuta mitään toimenpiteitä, mutta se koskee vain sitä odotettua poikkeusta.

Tommittaja [14.06.2009 21:00:11]

#

juu, periaatteessa, itse laitan aina vain

catch (Exception e) {System.out.println("Virhe");}

voi olla myöskin, että en aina tiedä, mitä virheitä metodi voi tuottaa.

Edit: Sisuaski sanoi tuolla alussa, että "Mikset tee vain yhtä funktiota, ja syöttele sille noita taulukoita parametrina?"

miten? sillä sama parametri voisi olla hieman hankala tehdä, jos kerran jokaisen taulukon piirtoon tarvitsee erilaisen while-silmukan. jos tuo on mahdollista, neuvokaa vain, niin _yritän_ :)

kayttaja-2499 [14.06.2009 21:09:10]

#

Jos haluaa enempi tietoa poikkeuksesta,

e.printStackTrace();

Metabolix [14.06.2009 21:29:47]

#

Miksi taulukon piirtoon tarvitsisi erilaisen silmukan?

for (int i = 0; i < t.length; ++i) {
  for (int j = 0; j < t[i].length; ++j) {
    System.out.print(t[i][j]);
  }
  System.out.println();
}

Tommittaja [14.06.2009 21:44:11]

#

oho. kun olen saanut apua tuohon taulukon piirtoon, olen vain käyttänyt sitä semmoisenaan, joten ei ole tullut mieleenkään laittaa sinne taulu.length :D olen vain laittanut jotenkin oudosti...

Teuro [14.06.2009 22:26:15]

#

Tuskin olet tehnyt oudosti, mutta olet ehkä käyttänyt staattisia taulukon kokoja.

Tommittaja [14.06.2009 23:11:00]

#

mitä tarkoitat staattisilla taulukon kooilla?

Taulukoissani siis lukee näin:

while (elamat > 0) {
    for (int i=0; i<10; ++i) {
        for (int j=0; j<11; ++j) {
            System.out.print(taulu[i][j]);
            if (j == 11-1) System.out.print("\n");
        }
    }
    liikkuminen(taulu);
}

kun en itse ole tehnyt näitä, tämä on aika omituinen tapa tehdä... mutta toimii. tarkoititko noilla staattisilla taulukon kooilla noita

 for (int i=0; i<10; ++i) {
        for (int j=0; j<11; ++j) {

että se ei ole

for (int j=0; j<taulu.length; ++j)

PS: voisiko mitenkään laittaa tabulaattorit toimimaan viesteissä? inhottavaa kun ei toimi..

Teuro [14.06.2009 23:19:18]

#

Tommittaja kirjoitti:

mitä tarkoitat staattisilla taulukon kooilla? tarkoititko noilla staattisilla taulukon kooilla noita

for (int i=0; i<10; ++i) {
        for (int j=0; j<11; ++j) {

Juurikin tuota tarkoitin, että olet "kovakoodannut" ne taulukon koot ohjelmaan.

hk [15.06.2009 02:41:32]

#

Tommittaja kirjoitti:

juu, periaatteessa, itse laitan aina vain

catch (Exception e) {System.out.println("Virhe");}

voi olla myöskin, että en aina tiedä, mitä virheitä metodi voi tuottaa.

Silloin ei tietysti tapahdu mitään vahinkoa, jos jokainen poikkeus on virhetilanne, joka edellyttää koodin korjaamista. Silloin saat noinkin tiedon siitä, että jotain on pielessä. Tarkempaa tietoa siitä, mitä on tapahtunut, saa myös metodilla getMessage, siis vaikka System.out.println("virhe: "+e.getMessage());.

Mutta useinhan try-catch pannaan siksi, että niiden välissä olevassa koodissa on jokin tarkistettava poikkeus, siis try-catch on pakko sinne laittaa, ellei metodi heitä poikkeusta ylemmälle tasolle. Ja silloin kai laitat virheilmoitukseen, että on tapahtunut odottamasi virhe, vaikkapa "tiedostoa ei ole olemassa". Jos pyydystät kaikki poikkeukset, tulee tuo ilmoitus myös silloin, kun tapahtuu jokin muu poikkeus, jota et ole osannut odottaa.

Jos koodissa tapahtuu vaikka nollalla jako, niin silti tulee ainoa määrittelemäsi virheilmoitus, että tiedostoa ei löydy. Ja se voi olennaisesti vaikeuttaa virheen löytämistä, koska etsit väärää ongelmaa. Jos virhe tulee vain harvoissa tilanteissa, voi olla ettet löydä sitä lainkaan, vaikka se on kerran tapahtunut, mutta ei toistu pian, ja oletat sen olevan eri tyyppinen.

Poikkeus ei valmiissa ohjelmassa yleensäkään ole ohjelman päättävä virhe, vaan tilanne, joka käsitellään tietyllä tavalla. Jos nappaat kaikki poikkeukset ja käsittelet ne tavalla, jolla odotettu poikkeus käsitellään, käy huonosti jos koodissasi on virhe, ja tapahtuukin jokin muu poikkeus.

Teuro [16.06.2009 10:22:49]

#

Taulukkoajattelu pelialueesta on kieltämättä yksi vaihtoehto, mutta kokeilin tuota edellä mainitsemaani tapaa, jossa tiedostosta luetaan kentän tiedot, joiden pohjalta luodaan tarvittavat elementit kentälle. Kokeilun perusteella voisin jopa aika varmasti suositella kyseistä tapaa tällaisille peleille, joissa on seiniä ja esineitä, joita poimitaan kentältä.

Tommittajalla oli muistaakseni joku pelikin, jossa poimittiin hedelmiä kentältä? Tämä tapa sopisi minusta paremmin kyseiseen peliin. Tässä siis luodaan Kentta luokasta olio, joka lataa parametrinä annetun tiedoston muistiin, josta se siis luo uusia esimerkiksi seinäolioita. Kenttää voi vaihtaa helpolla antamalla uuden kentän ladattavaksi kenttäoliolle. Itse pelin tynkä on kirjoitettu c++ kielellä käyttäen allegron grafiikkakirjastoa apuna.

Tämä on lisäksi jossain määrin laajennettava järjestelmä, joten esimerkiksi uusia elementtejä on melko helppo lisätä järjestelmään. Käytännössä tämä vaatii tarvittavan luokan luomisen ja kenttätiedostoon kirjoittaa alustukset, sekä latausfunktioon rutiinit luomiselle.

Tällaisen järjestelmän haittana on tietysti se, että näkyvää ei saa aikaan kovinkaan nopeasti, koska tässä pitää tehdä aika paljon enemmän työtä. Mikäli jollekin heräsi kiinnostusta asiasta voin laittaa tuota jakoonkin jonnekin.

Tommittaja [16.06.2009 15:04:49]

#

Nyt on julkastu uus versio siitä mun pelistä "Quest of ASCII"... liikkumismetodi on, uusi kenttä valmistui :D aion tehdä pari kenttää varmaan tänään vielä :)
Vieraskirja on uudistettu, ja nyt KAIKKI voivat kirjoittaa sinne :).. ennen piti rekisteröityä sinne mun sivulle.

Edit: nyt siellä on tapahtumakalenterikin! siellä lukee kaikki, mitä on tapahtuu...

Edit: ehkä yhden kentän sittenkin teen(tänään siis), sillä pitää tehdä muitakin muutoksia ja juttuja :) paitsi että kesällä on aikaa aina tehdä näitä; osa kylläkin pitää tätä ohjelmointia lähes työnä(vapaa ajalla), vaikkakin minä teen sitä ihan mielelläni :D

Tommittaja [16.06.2009 19:58:38]

#

Julkaisin nyt sen 6-tasoisen version.. en viitsinyt laittaa vilkkuvia vihollisia liikaa, sillä pelkään sen hidastavan koodia hirveästi :D no, seuraavaksi uskallan... saatan kyllä olla laiskakin :P


Sivun alkuun

Vastaus

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

Tietoa sivustosta