NewtonPolynom
,
(Newton)Interpolation
(Polynominterpolation)private, public, protected
von Daten und Methoden eines Objektes
NewtonPolynom
von Funktion1
, um Polynome
in der speziellen Newton'schen Darstellung zu konstruieren (und
auszuwerten):
1 public class NewtonPolynom extends Funktion1{ 2 private int Grad; 3 private double x[]; //Knoten 4 private double c[]; 5 //(p=c[0]+c[1]*(x-x[0])+.... +c[n]*(x-x[0])*...*(x-x[n-1]) 6 public NewtonPolynom(double[] x, double[] c{ 7 super(); //max.Def.Bereich 8 Grad=x.length-1; 9 this.x=x; 10 this.c=c; 11 }//Ende Konstruktor 12 public double getY(double z){ 13 double y; 14 // Ausfüllen mit Horner Schema 15 return y; 16 }//Ende getY 17 }//ende class NewtonPolynom
Das Ausfüllen von Zeile 14 wird der Übungsaufgabe 11 überlassen.
Einzige neue Java-Aspekte sind die Zugriffsrechte in Form von
Modifiern. Sie dienen der Kapselung, d.h. der
Abschottung gewisser Methoden und Attribute gegen Zugriffe durch
andere Objekte. Durch den Zusatz private gilt eine Sichtbarkeit nur innerhalb
der zugehörigen Klasse. Als guten Programmierstil gilt es, alle
Daten nur durch Methoden (wie z.B. Konstruktoren) festzulegen und zu
ändern. Die Daten werden daher i.a. als private
oder
auch, falls sie noch in Unterklassen (allgemein in Paketen
(pachages)) sichtbar sein sollen, als protected gekennzeichnet. Der Modifier
public signalisiert, dass von allen Klassen
aus hierauf zugegriffen werden kann. Es sind die
öffentlichen Methoden mit ihren Parameterlisten und ihren
Rückgabewerten, die der Verbindung nach außen
dienen. Natürlich sollte die Methode getY()
in Zeile
12 öffentlich sein.
Will man das Newton'sche Interpolationspolynom berechnen, muss man
"nur" noch die Koeffizienten double[] c
mit dem
Schema der Dividierten Differenzen berechnen.
Danach könnte man etwa auf die Methode
getWertetabelle()
(Aufgabe 7) in der Klasse
Funktion1
zugreifen.
Dies könnte in einer Applikationsklasse geschehen. Wir wollen jedoch
einen komplexeren Weg gehen, indem wir "Interpolation" durch eine
abstrakte Klasse erfassen und dann die "Newtoninterpolation"
durch eine Unterklasse beschreiben:
Diese abstrakte Klasse hat vier Attribute, die selbsterklärend sein sollten. Dabei wird dieI1 public abstract class Interpolation I2 protected int n; //Ordnung I3 protected double[] x;//Knoten I4 protected double[] y;//Werte I5 protected Funktion1 InterpolationsFunktion; I6 protected Interpolation(double[] x, double[] y){ I7 n=x.length-1; I8 this.x=x; I9 this.y=y; I10 }//Ende Konstruktor I11 }//Ende class Interpolation
InterpolationsFunktion
bei
einer Polynominterpolation ein (Newton'sches) Polynom sein, bei der
späteren Splineinterpolation aber etwas anderes. Später wird
diese Klasse u.a. um die grafische Methode Zeichne()
erweitert.
In der Unterklasse
ist der Konstruktor (Zeilen N2-N6) das wichtigste, der dieN1 public class NewtonInterpolation extends Interpolation{ N2 public NewtonInterpolation (double[] x, double[] y){ N3 super(x,y); N4 double[] c = DividierteDifferenzen(); N5 InterpolationsFunktion = new NewtonPolynom(x,c); N6 } N7 private double[] DividierteDifferenzen(){ N8 double[] c=new double[n+1]; N9 //Ausfüllen!! N10 return c; N11 }//Ende DividierteDifferenzen() N12 }
InterpolationsFunktion
(Attribut der Klasse Interpolation
) mit Hilfe der Methode
DividierteDifferenzen()
(auszufüllen in Aufgabe 11) als NewtonPolynom
berechnet! Beachte, dass
mit Hilfe von super()
in Zeile N3 auf den
Konstruktor der abstrakten Klasse Interpolation
zugegriffen wird.
Der Modifier private
ist nur dann sinnvoll, wenn sich
niemand für die Koeffizienten double[] c
des Newton'schen Interpolationspolynoms interessieren sollte,
s. Aufgabe 12.
Jetzt sieht eine Appikationsklasse etwa so aus
In Zeile B5 wird ein Objekt namensB 1 class Bsp6{ B 2 static void main(String[] args){ B 3 double[] x={0 ,0.1,0.2,0.3,0.4}; B 4 double[] y={-1, 1 , 4 , 3 , 2 }; B 5 NewtonInterpolation NIP =new NewtonInterpolation(x,y); B 6 double[] z = NIP.InterpolationsFunktion. getWertetabelle(0,0.5,10); B 7 for(int i=0;i<=10;i++) System.out.println("z["+i+"]="+z[i]); B 8 System.out.println(); B 9 }//Ende main() B10 }//Ende class Bsp6
NIP
der Klasse NewtonInterpolation
geschaffen, um auf die öffentliche Methode
getWertetabelle()
ihrer Variable
InterpolationsFunktion
in der doppelten
Punktnotation der Zeile B6 zuzugreifen. Der Vorteil
eines solchen Vorgehens kommt aber erst dann zum Tragen, wenn
man etwa in Zeile B5 später "Newton" durch "Spline"
ersetzt.
Als letztes verweise ich auf die sehr einfache Deklaration
der beiden Felder x
und y
in den Zeilen
B3 und B4 - ohne Verwendung von new
.
Wir wollen die Wurzelfunktion in den 5 Knoten 0, 0.1,...,0.4 durch ein Polynom vom Grade 4 interpolieren und die Graphen der Wurzelfunktion und des Interpolationspolynoms sowie die 5 Interpolationspunkte darstellen.
Hier werden die drei grafischen Darstellungen der Wurzelfunktion (Zeile 13), des Interpolationspolynoms (Zeile 14) und der Interpolationspunkte (Zeile 15) in einer Liste (Zeile 12) zusammengestellt. Die Zeile 17 ist sehr mächtig und bewirkt, dass die Zeichnung in einem Fenster zu sehen ist. Das Ergebnis sieht so aus:1 public class Bsp7{ 2 public static void main(String[] args){ 3 double[] x={0 ,0.1,0.2,0.3,0.4};//Knoten 4 double xMin=0; double xMax=0.5; 5 Wurzel f1 = new Wurzel(xMin,xMax); 6 double[] y=new double[x.length]; 7 for (int i=0;i<=x.length-1;i++) y[i]=f1.getY(x[i]); 8 NewtonInterpolation NIP= new NewtonInterpolation(x,y); 9 NIP.InterpolationsFunktion.setIntervall(xMin,xMax); 10 //setIntervall ist eine Methode der Klasse Funktion 11 NIP.InterpolationsFunktion.Name="IP"; 12 Liste fr=new Liste(); 13 fr.addDarstellbar(f1); 14 fr.addDarstellbar(NIP.InterpolationsFunktion); 15 InterpolPunkte f3=new InterpolPunkte(x,y); 16 fr.addDarstellbar(f3); 17 Grafik g=new Grafik(fr); 18 } 19 }
Dieses Programm zeigt auch einige bemerkenswerte Dinge des OOP:
NIP.InterpolationsFunktion
ist ein Objekt der Klasse
Newtonpolynom
, welche von der Klasse
Funktion
(ab jetzt ersetzen wir das Provisorium
Funktion1
durch Funktion
) abgeleitet
wird. Damit erbt NIP.InterpolationsFunktion
das
Attribut Name
(s. Zeile 11) und die Methode
setIntervall()
(s. Zeile 9). Letztere dient hier dazu,
den horizontalen Bereich der Grafik zu bestimmen. Beachte, dass es
sich jetzt so richtig "bezahlt" macht, dass die Klasse
Newtonpolynom
als Unterklasse von Funktion
definiert wurde. Wenn wir später
LineareSplineInterpolation
oder
KubischeSplineInterpolation
als Unterklasse von
Interpolation
einführen, können wir dieses
Programm praktisch vollständig übernehmen:
NewtonInterpolation
braucht nur durch
SplineInterpolation
ersetzt zu werden.
Noch erstaunlicher ist jedoch die Methode addDarstellbar()
des Objektes fr
vom Typ Liste
in den Zeilen
13, 14 und 16, weil die Parameter alle von unterschiedlichem
Typ sind: die ersten beiden sind Objekte verschiedener Unterklassen
von Funktion
, während f3
ein
Objekt vom Typ InterpolPunkte
ist.
Schauen wir uns zur Erklärung den Teil von
Liste.java
an, der sich auf diese Methode bezieht,
so sehen wir, dass als Parameter von addDarstellbar()
ein Objekt vom Typ Darstellbar
vorgesehen ist.
Darstellbar
definiert ein Interface, welches
in der abstrakten Klasse Funktion
mittels
als eine Art Oberklasse angesehen werden kann. Da auch die Klasseclass Funktion implements Darstellbar
InterpolPunkte
dieses Interface implementiert,
sind f1, f2, f3
alle vom Typ Darstellbar
und können als Parameter von addDarstellbar()
aufreten. Das nennt man Polymorphie.
Ich will das Interface-Konzept hier nicht vertiefen und verweise auf Lehrbücher.
Über die wichtigsten öffentlichen Methoden und Daten der Black-Box-Klassen gibt es eine Übersicht.