Eine Klasse oder Interface konstruieren

Neue Frage »

Auf diesen Beitrag antworten »
Haevelin Eine Klasse oder Interface konstruieren

Folgende Aufgabe habe ich zu bearbeiten:

Gegeben sei die Implementierung der Klasse Nutzer, die unter anderem die Klassen K1 und K2 des Pakets paketB nutzt.
Um paketB einfacher ändern zu können, soll nur noch eine Klasse (oder Schnittstelle) Z nach außen angeboten werden. Dazu müssen im Code von Nutzer alle Typen K1 und K2 durch Z ersetzt werden. Schreiben Sie den vollständigen Code von Z so, dass sich die geänderte Implementierung von Nutzer genauso wie die alte verhält. Z soll natürlich K1 und K2 nutzen.

package paketA;
import package paketB.*;
public class Nutzer {
private K1 k1;
private K2 k2;
private int wert;
public Nutzer (K1 k1, K2 k2, int wert){
this.k1=k1;
this.k2=k2;
this.wert=wert;
}

public void aendern(int x){
if (k1.pruefen(x)){
this.wert=x;
k1.protokollieren();
}
}

public void analysieren(double x){
if (k2.pruefen(x)){
wert+=k2.berechnen(x);
k1.protokollieren();
}
}
}



Meine Idee ist zunächst die gewesen in Z den Umstand zu nutzen, dass K2 über ein double pruefen(x) aufruft, und K1 die gleiche Funktion über ein int. Weiter bin ich noch nicht gekommen.
 
Auf diesen Beitrag antworten »
Haevelin RE: Eine Klasse oder Interface konstruieren

Einen Ansatz habe ich jetzt so:


public class Z {
private K1 k1;
private K2 k2;
int wert;
double dwert;
public Z(K1 k1, int wert){
this.k1=k1;
this.wert=wert;
}

public Z(K2 k2, double dwert){
this.k2=k2;
this.dwert=dwert;
}



}



Irgendwie muss die Klasse Nutzer wissen, welches Z sie anlegt, d.h. auf welchen Konstruktor sie reagieren soll. Mir ist aber nicht klar, wie das der Klasse Z mitgeteilt wird.
Auf diesen Beitrag antworten »
Karlito

Hallo Haevelin,

das Problem ist u.A., dass Z keine Klasse, sondern nur ein Interface ist. Interfaces haben den Vorteil, dass egal welche Klasse sie Implementier, diese Klasse eben genau diese Schnittstelle, also die darin vorgegebenen Methoden haben muss. Schau dir mal folgende Beispiele an:

Das ist das Interface in paketB
code:
1:
2:
3:
4:
5:
6:
7:
package paketB;

public interface Z {
    public void execute();
}


Hier nun die Klassen, die das Interface implementieren:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
package paketB;

public class K1 implements Z { //implements Z zeigt an, dass hier das Interface Z implementiert wird und so die Klasse K1 den Typ K1 und Z hat

    @Override
    public void execute() //Implementation der Interfacemethode
    {
        System.out.println("Hallo, hier ist K1");
    }

    public void narf() //Die klasse kann auch beliebiges Anderes implementieren
    {
        System.out.println("Narf!");
    }
}


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
package paketB;

public class K2 implements Z {
    @Override
    public void execute() {
        System.out.println("Hallo, hier ist K2!");
    }
}


Und hier die Klasse Nutzer, welches das Interface benutzt:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
package paketA;

import paketB.K1;
import paketB.K2;
import paketB.Z;

public class Nutzer {

    public static void main(String[] args) {
        Z test; //Deklaration einer Variable vom Typ Z, wodurch man nur mit dem Interface arbeitet

        test = new K1();
        test.execute();
        //test.narf(); // geht nicht, da das Interface Z die Methode narf() nicht kennt

        K1 k1 = (K1)test; //Sollte man nicht machen hilft hier aber vlt beim verständnis
        k1.narf(); //Geht, da test ursprünglich vom Typ K1 war und k1 nun den Typ K1 hat, der die Methode narf() enthält

        test = new K2();
        test.execute();

        try {
            k1 = (K1)test;
            k1.narf(); //Wird nicht erreicht
        }
        catch (Exception ex)
        {
            System.out.println("ClassCastException, da test nun nicht mehr auch vom Typ K1");
            System.out.println(ex);
        }

    }
}


Ich hoffe das erklärt die Verwendung von Interfaces. Wenn noch weitere Fragen sind, kannst Du gern hier nachhaken.

Gruß,

Karlito
Auf diesen Beitrag antworten »
Haevelin RE: Eine Klasse oder Interface konstruieren

In meinem konkreten Fall:
Mein interface wäre leer und K1 und K2 implementieren es; also brauche ich keine @override.
Nur die Änderung von Nutzer kann ich nicht ganz nachvollziehen. Wo ist der Konstruktor geblieben? Und test einmal auf K1(), dann auf K2() festzulegen funktioniert nicht.
Wie sollte dann meine main Funktion aussehen. Bisher habe ich:


public class Aufgabe111 {

public static void main(String[] args) {
// TODO Auto-generated method stub
K1 k1 = new K1();
K2 k2= new K2();
Nutzer nutzer= new Nutzer(k1,k2,10);
nutzer.aendern(5);
nutzer.analysieren(5.0);
}

}
 
Auf diesen Beitrag antworten »
Karlito

Hallo Haevelin,

bitte bette deinen Code in eine [code][/code] Umgebung ein.

Ein leeres Interface ist nicht sinnvoll und auch gar nicht möglich. Interfaces abstrahieren gemeinsame Schnittstellen. Hat also Klasse A und Klasse B gemeinsame Methoden, so können diese im Interface definiert werden. Bei der Verwendung der Klassen muss dann nur noch mit dem Interface gearbeitet werden (man weist die Objektinstanz einer Variablen vom Typ des Interfaces zu).

Was sollen denn die Klassen K1 und K2 leisten? Und was hat die Klasse Nutzer denn damit zu tun?

Gruß,

Karlito
Auf diesen Beitrag antworten »
Haevelin

Hallo Karlito,

wir haben mittlerweile die Lösung bekommen. Die Idee ist es Z so zu konstruieren, dass es die Methoden von K1 und K2 überlädt, und dabei die spezifischen Methoden von K1 bzw. K2 aufruft. Ein Interface war dazu nicht nötig; es wäre sogar irreführend.
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »