© 1999-2009, Flemming Koch Jensen
Alle rettigheder forbeholdtNedarvning
Vejledende løsninger
1
Først laver vi klassen Punkt:
public class Punkt { private double x, y; public Punkt( double x, double y ) { this.x = x; this.y = y; } public Punkt( Punkt p ) { this( p.x, p.y ); } public void move( double deltaX, double deltaY ) { x += deltaX; y += deltaY; } public String toString() { return "(" + x + ", " + y + ")"; } }Ingen af subklasserne får brug for at arbejde direkte med x og y; hvorfor vi holder os til den strenge indkapsling med private.
Bemærk at vi ved toString anvender de almindelige paranteser i overensstemmelse med den sædvalige notation for punkter i koordinatsystemet.
Dernæst laver vi klassen Cirkel:
public class Cirkel extends Punkt { private double radius; public Cirkel( Punkt punkt, double radius ) { super( punkt ); this.radius = radius; } public double getRadius() { return radius; } public double areal() { return Math.PI * radius * radius; } public double omkreds() { return 2.0 * Math.PI * radius; } public String toString() { return "[" + super.toString() + ", radius=" + radius + "]"; } }Igen anvender vi private. Her er det specielt fordi der ikke nedarves fra Cirkel; hvorfor der ikke er grund til at gøre andet.
I set-konstruktoren anvender vi super-klassens copy-konstruktor, da den passer til det Punkt vi modtager som parameter. Bemærk at toString anvender super-klassens toString.
Dernæst laver vi klassen Rektangel:
public class Rektangel extends Punkt { private double bredde, højde; public Rektangel( Punkt punkt, double bredde, double højde ) { super( punkt ); this.bredde = bredde; this.højde = højde; } public double areal() { return bredde * højde; } public double omkreds() { return 2 * ( bredde + højde ); } public String toString() { return "[" + super.toString() + ", " + bredde + "x" + højde + "]"; } }Igen private instansvariable.
Igen brug af superklassens copy-konstruktor. Igen bruger toString superklassens toString.
Endelig har vi en test-anvendelse.
public class Main { public static void main( String[] argv ) { Punkt origo = new Punkt( 0, 0 ); System.out.println( origo ); Cirkel enhedsCirkel = new Cirkel( origo, 1 ); System.out.println( enhedsCirkel ); System.out.println( "Enhedscirklens omkreds: " + enhedsCirkel.omkreds() ); System.out.println( "Enhedscirklens areal: " + enhedsCirkel.areal() ); Punkt p = new Punkt( 10, 5 ); Rektangel rek = new Rektangel( p, 5, 3 ); System.out.println( rek ); System.out.println( "Arealet af rektangel (5x3): " + rek.areal() ); System.out.println( "Omkreds af rektangel (5x3): " + rek.omkreds() ); rek.move( -3, 3 ); System.out.println( rek ); } } (0.0, 0.0) [(0.0, 0.0), radius=1.0] Enhedscirklens omkreds: 6.283185307179586 Enhedscirklens areal: 3.141592653589793 [(10.0, 5.0), 5.0x3.0] Arealet af rektangel (5x3): 15.0 Omkreds af rektangel (5x3): 16.0 [(7.0, 8.0), 5.0x3.0]
2 Først laver vi klassen Organisme:
package organismer; public class Organisme { private boolean levende; protected int alder; public Organisme() { levende = true; alder = 0; } public void dø() { levende = false; } public boolean gro() { alder++; return true; } public String toString() { String s = "[" + alder + " år, "; if ( levende ) s += "levende"; else s += " død"; s += "]"; return s; } }Vi lader de to instansvariable være protected af hensyn til subklasserne. gro implementeres, så den øger alderen med én. Der foretages ingen check af død ved alderdom, da subklassen Plante ikke kan dø af alderdom. Af samme grund returnerer metoden altid true.
Dernæst laver vi klassen Plante:
package organismer; public class Plante extends Organisme { public void dø() { if ( alder > 3 ) super.dø(); } public String toString() { return "[Plante: " + super.toString() + "]"; } }dø overrides så planten ikke kan spises i de første tre leveår. Dette gøres ved at ignorere forsøg på at spise den, med mindre alder er større end tre.
Dernæst laver vi klassen Dyr:
package organismer; public class Dyr extends Organisme { private int maxAlder; public Dyr( int maxAlder ) { this.maxAlder = maxAlder; } public boolean gro() { super.gro(); if ( alder > maxAlder ) { dø(); return false; } else return true; } public String toString() { return "[" + super.toString() + ", max. levetid: " + maxAlder + "]"; } }Alle dyr har en maximal levealder, og denne implementeres som en instansvariabel maxAlder, som sættes af set-konstruktoren. Metoden gro bliver fælles for alle dyr. Dette skyldes at den er generel, idet den arbejder ud fra den maximum alder der optræder i instansvariabelen.
Dernæst laver vi klassen Rovdyr:
package organismer; public class Rovdyr extends Dyr { public Rovdyr() { super( 10 ); } public void spis( PlanteSpiser ps ) { ps.dø(); } public String toString() { return "[Rovdyr: " + super.toString() + "]"; } }Default-konstruktoren sætter den maximale levealder til ti år, vha. superklassens set-konstruktor. Metoden spis kalder PlanteSpiseren og beder den om at dø.
Dernæst laver vi klassen PlanteSpiser:
package organismer; public class PlanteSpiser extends Dyr { public PlanteSpiser() { super( 20 ); } public void spis( Plante p ) { p.dø(); } public String toString() { return "[PlanteSpiser: " + super.toString() + "]"; } }Default-konstruktoren sætter den maximale levealder til tyve år, vha. superklassens set-konstruktor. Analogt til Rovdyrs spis-metode, kalder PlanteSpiser også dø-metoden på sit "bytte". Det skal bemærkes, at det ikke betyder noget for metoden om Planten er gammel nok til at blive spist. PlanteSpiser er lige glad, planten overlever blot hvis den er giftig.
Endelig har vi en test-anvendelse:
import organismer.*; public class Main { public static void main( String[] argv ) { Plante p = new Plante(); System.out.println( p ); PlanteSpiser ps = new PlanteSpiser(); System.out.println( ps ); Rovdyr r = new Rovdyr(); System.out.println( r ); System.out.println( "Spisetid..." ); ps.spis( p ); r.spis( ps ); System.out.println( p ); System.out.println( ps ); System.out.println( r ); for ( int i=0; i<15; i++ ) { p.gro(); ps.gro(); r.gro(); } System.out.println( "15 år er gået..." ); System.out.println( p ); System.out.println( ps ); System.out.println( r ); } } [Plante: [0 år, levende]] [PlanteSpiser: [[0 år, levende], max. levetid: 20]] [Rovdyr: [[0 år, levende], max. levetid: 10]] Spisetid... [Plante: [0 år, levende]] [PlanteSpiser: [[0 år, død], max. levetid: 20]] [Rovdyr: [[0 år, levende], max. levetid: 10]] 15 år er gået... [Plante: [15 år, levende]] [PlanteSpiser: [[15 år, død], max. levetid: 20]] [Rovdyr: [[15 år, død], max. levetid: 10]]