Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java Static Ongelma

Sivun loppuun

hevonen [16.11.2008 21:03:30]

#

Koodi vertaa kahta nimeä, jotka saadaan skannerilta. Jos nimi2 -olio on aikaisemmin nimi -oliota, niin tulostetaan true. Muuten tulostetaan false. Koodi on

import java.util.*;
class Compare {

   public static Scanner scanner = new Scanner(System.in);

   private String nimi;
   private String nimi2;

   // ----------------

   public Compare(String nimi, String nimi2){
       this.nimi=nimi;
	   this.nimi2=nimi2;
   }

   public boolean vertaus() {
      nimi = scanner.toString();
      nimi2 = scanner.toString();
      if(nimi.compareTo(nimi2) > 0)
         return true;
      else
         return false;
   }

   public static void main(String[] args){
	   vertaus();
   }
}

Eclipse pyytää muuttamaan vertaus -metodin staattiseksi. Tämä muutos taas johtaa noin kuuteen virheeseen. Ehkä virhe liittyy jotenkin konstruktoreihin.

Mistä virhe voisi johtua?

Teuro [16.11.2008 21:19:53]

#

Et ainakan luo tuosta Compare-luokasta yhtään oliota, joten et voi tietenkään käyttää luokan metodeita ilman oliota. Tämä lienee sinulle jo tuttua. Mietipä sen ohjelman rakenne ihan alusta asti, koska voin jo nyt sanoa, että ammut itseäsi jalkaan tuolla koodaustavalla.

Metabolix [16.11.2008 21:21:05]

#

Olisiko vähitellen aika opetella, mikä ero on luokalla ja oliolla?

Voisi jopa sanoa, että luokka on koodia ja olio on muistia. Koodissa kerrotaan, millaisia muuttujia ja funktioita tiettyyn luokkaan kuuluu. Staattiset jäsenet ovat vain luokkaan sidonnaisia, ja ne sijaitsevat siis yhdessä kohti tietokoneen muistia. Muut jäsenet sen sijaan käsittelevät aina yhtä oliota (luokan edustajaa), ja jokaisella luokan instanssilla on siis oma kopio omasta datastaan tietokoneen muistissa. Käytetäänpä taas biologiaa esimerkkinä:

// Luokka ElioX kuvaa yhtä eliölajia nimeltä X.
class ElioX {
  // Kaikilla lajin yksilöillä on sama kromosomimäärä, joten se on staattinen.
  // Koko ohjelma sisältää YHDEN kerran tämän luvun, se on koko luokan yhteinen.
  private static int kromosomien_maara = 12;

  // Jokainen yksilö voi painaa eri verran, joten massa EI ole staattinen.
  // Jokaisella ElioX:n instanssilla on muistissa OMA massansa.
  private float massa;

  // Tämä funktio kertoo jotain luokkakohtaista tietoa.
  // Tämä voi käyttää vain staattisia jäseniä.
  public static int hae_kromosomien_maara() {
    return kromosomien_maara; // mieti: kenen kromosomien määrä?
  }

  // Tämä funktio kertoo jotain yksittäisestä oliosta.
  // Tämän kutsumiseen tarvitaan siksi olio, jonka dataa käytetään.
  public float hae_massa() {
    return massa; // mieti: kenen massa?
  }
}

Staattisia jäseniä voidaan käyttää sellaisinaan luokasta, kun taas muiden jäsenten käyttöön tarvitaan olio:

class koe {
  public static void main(String[] args) {
    ElioX.hae_kromosomien_maara();
    ElioX a = new ElioX();
    a.hae_massa();
  }
}

Ilmeisesti käyt jonkinlaista Java-kurssia. Saanen kummastella: miten Javaa voi opetella noin kauan oppimatta tällaista perusasiaa?

hunajavohveli [16.11.2008 21:24:38]

#

Onko tarkoituksesi käyttää olioita vai pelkästään luokkaa? Metodissa vertaus() käsittelet olion muuttujia, mutta kutsut sitä mainista suoraan kertomatta, mihin olioon sitä pitäisi soveltaa. Jos et tarvitse olioita, muuta kaikki muuttujat ja metodit staattisiksi. Muussa tapauksessa luo olio, ja kutsu vertaus()-metodia sitten kyseisellä oliolla.

hevonen [16.11.2008 23:09:09]

#

Kiitos kommenteistanne!
@hunjavohveli: tarkoitukseni on käyttää vain olioita.

Huomasin heikkouksia koodissani:
1. p.s.v. mainista puuttuu olion luonti
=> syy: en huomioinut static ja muun staffin eroa
2. scannerin importointi ei jostain syystä toimi minulla tällä:

import java.util.*;

vaan täytyy käyttää jostain syystä tarkkaa kutsumista:

import java.util.Scanner;

Minulle nousi tuosta Metabolixin koodista yksi kysymys mieleen:
1. Voiko final -määrrettä käyttää tuon staattisuuden sijasta? Esimerkiksi kuvaamaan kromosomien määrää. Eihän final -muuttuja muutu. Ehkä syy on, että staattiset jäsenet ovat vain luokkaan sidonnaisia, kun taas final jäsenet eivät.

Metabolix [16.11.2008 23:15:32]

#

Final ei ole sama asia, koska staattisia muuttujia voi muuttaa. Aiemmassa esimerkissäni voisi olla vaikkapa tällainen järjestelmä:

// class ElioX { ...
  private static int elavia_lajin_edustajia = 0;

  ElioX() {
    elavia_lajin_edustajia += 1;
    System.out.format("%d ElioX:ää elossa\n", elavia_lajin_edustajia);
  }
  protected void finalize() throws Throwable {
    elavia_lajin_edustajia -= 1;
    super.finalize();
  }

hevonen [17.11.2008 00:29:10]

#

@Hyvä esimerkki: se kuvaa osuvasti staticin ja finalin eroa. Se nosti myös muutaman kysymyksen.
1. Mitä tarkoittaa tämä "%d"?
2. Miten protected määre eroaa private määreestä? Ehkä luokkahierarkiassa protected sallii perinnän.
3. Mitä throws Throwable tekee koodin lopussa? Arvelen, että näin tyhjennetään muistia manuaalisesti.

Päärynämies [17.11.2008 00:44:53]

#

1. Tuo "%d" on tarkoittaa tuossa, että siihen sijoitetaan tuo elavia_lajin_edustajia ja että se on kokonaisluku. Tuota tulostusta voidaan siis muotoilla eri tavoin, siitä jo metodin nimikin. Lisää infoa muotoilusta löytyy osoitteesta http://java.sun.com/javase/6/docs/api/java/util/Formatter.html#syntax. Sitä samaa Javan dokumentaatiota kuin aiemminkin sinulle linkitin.

http://java.sun.com/javase/reference/api.jsp Tuolta kannattaa katsella ja opetella käyttämään. Alussa ainakin kuvittelisin, että nuo Core Api Docs on tärkein asia tuolta. Tuohonkin löytyi vastaus kun etsi oikein luokan, joka oli siis System, sieltä tuon out ja sen metodin format. Huomattava apu on. Alussa voi tuntua hankalalta, myös alun jälkeenkin. Uhraa vaikka jokunen hetki sille, että käyt etsimässä tuolta jo tuntemiesi luokkien dokumentaatiota.

Eclipsessäkin on jotain dokumentaatiota mukana, jos sitä käytät.

Noita muita en ala arvaamaan, vaikka jonkinlainen käsitys onkin, Javaa kun itselläkin on vasta hyvin vähän takana. Paremmin tietävät vastatkoon siis.

tsuriga [17.11.2008 00:55:42]

#

2. http://javala.cs.tut.fi/en/show.do;?category­=luokat_ja_oliot#nakyvyys
3. http://javala.cs.tut.fi/en/show.do;?category­=poikkeukset

hevonen [17.11.2008 01:11:26]

#

@Päärynämies, tsuriga: Kiitos Linkeistä ja opastuksesta!

Päärynämies herätti uuden kysymyksen: Mitä dokumentaatiota minun kannattaa lukea tuosta Päärynämiehen linkistä? 6, 5,...,vai 1.3? Arvelisin, että suurin numero ehdottaa tuoreinta versiota Javasta.

Metabolix [17.11.2008 01:14:55]

#

hevonen kirjoitti:

Arvelisin, että suurin numero ehdottaa tuoreinta versiota Javasta.

Kyllä, joten juuri sitä kannattaa luultavasti lukeakin. Viitonen ja kuutonen tosin taitavat näiltä osin olla vielä aika lähellä toisiaan.

Jackal von ÖRF [17.11.2008 02:08:45]

#

Ja kyseisestä APIsta etenkin pakkauksien java.lang, java.util ja java.io sisältö kannattaa opetella ulkoa - ainakin sillä tasolla, että tietää mitä luokkia niissä on ja mitä mikin luokka tekee. Muista pakkauksista riittä tässä vaiheessa tietää pakkaustasolla, että mitä tavaraa pakkauksessa on, jotta tietää myöhemmin mistä etsiä, kun niille tulee tarvetta.

Tästä olikin jo juttua: https://www.ohjelmointiputka.net/keskustelu/18099-lista-javan-apin-tärkeimmistä-methodeista


Sivun alkuun

Vastaus

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

Tietoa sivustosta