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:
I1 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
Diese abstrakte Klasse hat vier Attribute, die selbsterklärend
sein sollten. Dabei wird die 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
N1 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 }
ist der Konstruktor (Zeilen N2-N6) das wichtigste, der die
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
B 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
In Zeile B5 wird ein Objekt namens 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.
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 }
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:
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.