Objektorientierte Programmierung: Erben von 2 Klassen - wie ist korrekte Vorgehensweise?

n0x0n

Mitglied
Hallo!


Dass in Java jede Klasse (außer Object) von genau einer Klasse erbt, weiß ich. Aber wie würde man das folgende Beispiel "richtig" Programmieren? Es bezieht sich auf die objektorientierte Programmierung. Ich hoffe, das ist erlaubt. ^^

Bei dem Beispiel werde ich mich sehr kurz halten und nur die benötigten Methoden aufschreiben um die Übersicht zu bewahren. Insbesondere sinnvolle Konstruktoren seien implementiert.

Die abstrakte Klasse RealFunction beinhaltet funktionen die von einer beliebigen Menge in die reellen Zahlen abbildet. In Java-Worten: von Obejct nach Double.
Java:
public abstract class RealFunction {
public abstract Double valueAt(Object x);
}

Die abstrakte Klasse RealFunction beinhaltet funktionen die von den reellen Zahlen in die reellen Zahlen abbildet. Sie beinhaltet zusätzlich die Methode integral, die die Funktion auf der Menge [lowerBound,upperBound] integriert. (z.B. via Romberg-Integral).
Java:
public abstract class UnivariateRealFunction extends RealFunction {
public Double valueAt(Object x){
if( ! (f instanceof Double) ){
mach irgendwas (z.B. Exception werfen)
}
return this.valueAt( (Double) x );
}
public abstract Double valueAt(Double x);
public Double integral(double lowerBound, double upperBound){ .... }
}


Die Klasse EuklidischeNorm (die die euklidische Norm von Object o darstellt (o muss dazu in einem passenden Format vorliegen) Euklidische Norm ? Wikipedia) würde von RealFunktion erben - denn es ist ja eine reelle Funktion.

Die Klasse Betrag ist eine univariate reelle Funktion. Insbesondere kann das Integral auf einem beschränkten Intervall berechnet werden. -> erbt von UnivariateRealFunction
Auf der anderen Seite ist der Betrag nicht weiter als die euklidische Norm auf den reellen Zahlen -> erbt von EuklidischeNorm.



Mit anderen Worten: die Klasse Betrag soll von 2 Klassen erben?!
Wie würde man dies "richtig/schön" programmieren?


Vielen Dank fürs lesen.
 
Ein Gedanke
Java:
// Interface mit Generics
interface UnivariateRealFunction<T>
{
    Double apply(T t);
}

// Beispiel
UnivariateRealFunction<Double> sine = new UnivariateRealFunction<Double>()
{
    @Override
    public Double apply(Double t) { return Math.sin(t); }
}


// Integral: 
interface Range<T> {
    T min();
    T max();
}

UnivariateRealFunction<Range<Double>> someIntegral = new GeneralDoubleIntegrator(sine, 0.001);
Double value = someIntegral.apply(Range.of(-1.0, 1.0));
Schick?
 
Danke für die Antworten.


Hab mir die deutsche Version angeschaut.^^
Wenn ich das recht verstanden habe, dann lautet deine Antwort: Je nach Problemstellung erbt Betrag entweder von EuklidischeNorm oder von UnivariateRealFunction. Wenn Betrag von EuklidischeNorm erben und das Integral berechnet werden soll, dann muss integral(...) extra implementiert werden.

Ein Gedanke
...
Schick?

Wow, ich versteh gar nichts.^^
Die Konstruktion
Java:
interface Range<T>
(Interface mit <T>) ist mir unbekannt. Kannst du mir vielleicht sagen wo das (auf einfache Art) erklärt wird?
 
Zuletzt bearbeitet:
Generics sind - wie der Name schon sagt - allgemeine Klassen, die in Abhängigkeit eines Datentypes die slebe Sache auf unterschieldiche Art machen. Bsp. reele Zahlen
für jede reele Zahl soll es eine Funktion addiere() geben. Für double-Werte soll eine neue double als Ergebnis entstehen, für ints soll ein int entstehen. Deswegen nun aber eine neue Klasse zu erfinden, nur weil die Datentypen anders sich, wäre aber quatsch, und darum hat man generics erfunden.
Verwendung finden diese übrigens in allen Arten von Listen oder Tabellen (eine Liste ist demnach nichts weiter als eine Sammlung von Daten, welchen Typ die Daten haben, legst du einmal zur Konstrktion fest). Das sieht dann so aus:
Java:
ArrayList<Integer> a = new ArrayList<Integer>();
Schonmal gesehen?
 
Ja, Range<T> bedeutet: Ein Intervall von zwei Elementen vom Typ "T", wobei "T" eben für "Double" stehen könnte, oder für irgendwas anderes, wofür sich "min" und "max" sinnvoll implementieren lassen. (Eigentlich könnte man das T noch durch Comparable einschränken, aber ist wohl nicht so wichtig)

War auch nur ein Gedanke: Ein Integral ist ja auch nur eine Funktion (die eine andere Funktion "enthält", und ein Intervall auf einen Double-Wert abbildet)
 
Jetzt hab ich doch noch eine Frage.

Wenn das Integral als eine eigene Funktion angesehen wird, dann würde ich dasselbe für Summe, Produkt, etc. machen. Am Ende erhalte ich Klassen, die
einen Konstruktor (evtl mehrere) bei dem das Integral/Summe/... berechnet wird und
die Methode zugehörige Methode apply (bzw. valueAt)
enthalten. Mit anderen Worten fokussiere ich mich auf die Prozeduren/Methoden und nicht auf die Objekte. Das ist ja grade nicht Sinn von OOP.

Hab ich irgendetwas falsch verstanden? Was?
 
Nochmal: Das war nur ein spontaner Gedanke. Ob es für deine Zwecke Sinn macht, musst du dir überlegen. Grundsätzlich kann man ja ALLES über Funktionen abbilden (deswegen gibt's auch funktionale Sprachen 😉 ). Man könnte auch umgekehrt polemisch sagen: Warum willst du mit einer objektorientierten Sprache Funktionen bauen?

Aber ehrlich gesagt sehe ich nicht, was da dagegen spricht, bzw. was du mit "Prozeduren/Methoden und nicht auf die Objekte fokussieren" meintest, und wo da deine Bedenken liegen.
 
Mit anderen Worten fokussiere ich mich auf die Prozeduren/Methoden und nicht auf die Objekte. Das ist ja grade nicht Sinn von OOP./QUOTE]

Methoden gehören genauso zu OOP wie Klassen und Instanzen. Der "Trick" ist immer den richtigen Abstraktionsgrad zu finden, also die verschiedenen Aspekten mit den richtigen Konstrukten(Attribute/Methoden/Klassen/Instanzen etc.) darzustellen. Wie das allgemein geht kann dir niemand in einem Forum erklären. Darüber kann man Bücher schreiben und trotzdem gehört noch eine Menge Kreativität, Fingerspitzengefühl und so dazu, das kommt einfach mit der Zeit.
Für eine konkrete Antwort müsstest du noch mal weitgehender und konkreter beschreiben was du vor hast. Für ein Beispielproblem kann man zwar eine Lösung finden, ob diese Lösung im Gesamtkonzept aber sinnvoll ist weiß man nicht 🙂
 
Wow, ich versteh gar nichts.^^
Die Konstruktion
Java:
interface Range<T>
(Interface mit <T>) ist mir unbekannt. Kannst du mir vielleicht sagen wo das (auf einfache Art) erklärt wird?

In der Java-Welt spricht man zwar von "Generics", du solltest aber auch den allgemeinen Begriff kennen, und zwar "Typ-Polymorphismus". Wikipedia nennt es Parametrische Polymorphie, was es meiner Meinung nach nicht so gut trifft.

Die Grundidee ist einfach: Wenn ich z.B. eine Längen-Funktion für eine Liste schreiben will, ist der Code dafür völlig gleich, egal ob es sich um eine String-Liste, eine Zahlen-Liste oder eine Liste mit grünen Elefanten handelt. Deshalb abstrahiert man vom konkreten Typ, und gibt ihn einfach als eine Art "Argument" (einen Typparameter) für die Klasse oder das Interface mit, während man innerhalb der Klasse nur mit seinem "Variablennamen" hantiert (im obigen Beispiel wäre das [c]T[/c]). Man kann natürlich noch gewisse Einschränkungen machen wie "T muss eine Subklasse von Number sein" oder so.
 
Zuletzt bearbeitet:
Der "Trick" ist immer den richtigen Abstraktionsgrad zu finden, also die verschiedenen Aspekten mit den richtigen Konstrukten(Attribute/Methoden/Klassen/Instanzen etc.) darzustellen. Wie das allgemein geht kann dir niemand in einem Forum erklären. Darüber kann man Bücher schreiben und trotzdem gehört noch eine Menge Kreativität, Fingerspitzengefühl und so dazu, das kommt einfach mit der Zeit.
Ich denke, das trifft es auf den Punkt.

Eine konkrete Anwendug für das Beispiel gibt es nicht. Ich habe eine Übungsaufgabe (schon fertig), bei der ich die abstrakte Klasse RealFunction verwende. Sie steht für Funktionen, die von Double nach Double abbilden. Dieses Konstrukt wollte ich zum besseren Verständnis von OOP/Java (theoretisch) auf beliebe Funktionen erweiteren...

Aber ehrlich gesagt sehe ich nicht, was da dagegen spricht, bzw. was du mit "Prozeduren/Methoden und nicht auf die Objekte fokussieren" meintest, und wo da deine Bedenken liegen.
Ich habe ein Beispiel konstruiert, bei der dieser Stil unangepasst ist und mich zu sehr darauf konzentriert. => Mein Fehler! ^^
Werd wohl einfach noch Üben müssen und Erfahrung sammeln.

Das mit den Generics hab ich auch verstanden. Mal sehen, wann ich das anwenden kann. 😀
 

Neue Themen


Zurück
Oben