Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys

9.3.3 Koostaminen

Seuraava mahdollisuus olisi uuden luokan koostaminen ( aggregation) vanhasta aikaluokasta ja sekunneista. Tämä mahdollisuus meillä on aina käytössä vaikkei alkuperäistä lähdekoodia olisikaan käytössä. Tätä vaihtoehtoa pitää aina vakavasti harkita.

Valitettavasti emme voi aivan täysin onnistua. Nimittäin alkuperäisen luokan tulosta oli niin tyhmästi toteutettu, että se tulosti aina rivinvaihdon. Tämmöistä hölmöyttä ei pitäisi mennä koskaan tekemään ja siksipä alkuperäinen luokka pitää joka tapauksessa palauttaa valmistajalle remonttiin. No luokan valmistaja muutti tulosta-metodia siten, että se oletuksena tulostaa rivinvaihdon (merk. lf = line feed), mutta pyydettäessä jättää sen tekemättä. Näin vanha koodi voidaan käyttää muuttamattomana.

Palaamme tulostusongelmaan myöhemmin ja keksimme silloin paremman ratkaisun, jota olisi pitänyt käyttää jo alunperin.

olioalk\Aika5.java - rivinvaihto ehdolliseksi

	  /**
	   * Tulostaa ajan muodossa 15:05
	   * @param lf tulostetaanko rivinvaihto vai ei
	   */
	  public void tulosta(boolean lf) {
	    System.out.print("" + h + ":" + (m<10?"0":"")+m);
	    if ( lf ) System.out.println();
	  }
	
	  /**
	   * Tulostaa ajan muodossa 15:05 sekä aina rivinvaihdon
	   */
	  public void tulosta() {
	    tulosta(true);
	  }

Nyt voimme kirjoittaa uuden luokan, joka koostetaan luokasta Aika5 ja sekunneista:

olioalk\AikaSek7.java - laajentaminen koostamalla

	/**
	 * Luokan laajentaminen koostamalla
	 * @author  Vesa Lappalainen
	 * @version 1.0, 01.02.2003
	 */
	public class AikaSek7 {
	
	  private Aika5 hm = new Aika5();
	  private int s;
	
	  /**
	   * Asettaa uuden ajan ja pitää huolen että aika on aina oikeaa muotoa.
	   * @param h asetettavat tunnit
	   * @param m asetettavat minuutit
	   * @param s asetettavat sekunnit
	   */
	  public void aseta(int h,int m, int s) {
	    hm.aseta(h,m); this.s = s; lisaa(0,0);
	  }
	
	  public void aseta(int h,int m) { aseta(h,m,0); }
	  public void aseta(int h)       { aseta(h,0);   }
	
	  public AikaSek7() { }
	
	  /**
	   * Alustaa ajan
	   * @param h tunnit
	   * @param m minuutit
	   * @param s sekunnit
	   */
	  public AikaSek7(int h,int m, int s) { // Muodostaja
	    aseta(h,m,s);
	  }
	
	  public AikaSek7(int h,int m) { aseta(h,m,0); }
	  public AikaSek7(int h)       { aseta(h,0,0); }
	
	  /**
	   * Tulostaa ajan muodossa 15:05
	   * @param lf tulostetaanko rivinvaihto vai ei
	   */
	  public void tulosta(boolean lf) {
	    hm.tulosta(false);
	    System.out.print(":" + (s<10?"0":"")+s);
	    if ( lf ) System.out.println();
	  }
	
	  /**
	   * Tulostaa ajan muodossa 15:05 sekä aina rivinvaihdon
	   */
	  public void tulosta() { tulosta(true);  }
	
	  /**
	   * Lisää aikaan valitun minuuttimäärän
	   * @param lisa_min lisättävä minuuttimäärä
	   * @param lisa_sek lisättävä sekunttimäärä
	   */
	  public void lisaa(int lisa_min,int lisa_sek)  {
	    s += lisa_sek;
	    hm.lisaa(lisa_min+s/60);
	    s %= 60;
	  }
	
	  public void lisaa(int lisa_min)  { lisaa(lisa_min,0); }
	
	  public static void main(String[] args) {
	    Aika5 a1 = new Aika5();
	    Aika5 a2 = new Aika5(13);
	    Aika5 a3 = new Aika5(14,175);
	
	    a1.tulosta();  a2.tulosta();  a3.tulosta();
	    a1.aseta(12,15); a2.aseta(16,-15);
	    a1.tulosta(); a2.tulosta();
	
	    AikaSek7 a4 = new AikaSek7(14,55,45); a4.tulosta();
	    a4.lisaa(3,30); a4.tulosta();
	  }
	}

Luokassa on niin vähän ominaisuuksia, että uudessa luokassamme olemme joutunee itse asiassa tekemään kaiken uudelleen ja on kyseenalaista olemmeko hyötyneet vanhasta luokasta lainkaan. Tämä on onneksi lyhyen esimerkkimme vika, todellisilla luokilla säästö kokonaan uudestaan kirjoitettuun verrattuna olisi moninkertainen.


Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys