Vererbung

In der Physik sind häufig Vierer-Vektoren (=Lorentz-Vektor) gefragt, d.h. Dreier-Vektoren erweitert um Zeit bzw. Energie-Komponente. Mögliche LorentzVektor Klasse:

 class MyLVector {
 private:        // coordinates, hidden
   double t;   double x;   double y;   double z;
 public:  
   MyLVector();// The default constructor
   MyLVector(double c0, double c1, double c2, double c3);// Other constructor
   // methods:
   double Length() const;  //   get length of vector
   double T() const;
   double X() const;
   double Y() const;
   double Z() const;
   MyLVector Add( const MyLVector & p ) const;  // add two vectors
   double Angle( const MyLVector & p ) const;  // angle between  two vectors
   double Mass() const;  //   get mass of 4-vector
 };


Vierer-Vektor kann als Erweiterung des Dreier-Vektor angesehen werden. Viele Gemeinsamkeiten mit Dreier-Vector und ein paar Erweiterungen

Design Prinzip Code-Reuse statt cut&paste !


Also vielleicht besser My3Vector in MyLVector benutzen:

 class MyLVector {
 private:        // coordinates, hidden
   double t;
   My3Vector vec3;  // My3Vector as private member
 public:  
   MyLVector();// The default constructor
   MyLVector(double c0, double c1, double c2, double c3);// Other constructor
   // methods:
   double Length() const;  //   get length of vector
   double T() const;
   double X() const;
   double Y() const;
   double Z() const;
   MyLVector Add( const MyLVector & p ) const;  // add two vectors
   double Angle( const MyLVector & p ) const;  // angle between  two vectors
   //   ....
 };


\bgroup\color{green}\ensuremath{\Rightarrow}\egroup LorentzVektor enthält DreierVektor: "has-a" relationship (Aggregation).


// implementation
// Constructor
MyLVector::MyLVector(double c0, double c1, double c2, double c3) :
  vec3(c1, c2, c3), t(c0) // special initialization syntax 
{}

double MyLVector::Angle( const MyLVector & p ) const
{
  return( vec3.Angle(p.vec3)); // re-use code
}
double MyLVector::X() const
{
  return( vec3.X() ); // re-use code
}

Im Prinzip ok, allerdings viele stumpfsinnige Mapping-Funktionen von DreierVektor auf ViererVektor nötig.


3. Möglichkeit: Vererbung

ViererVektor   ist   DreierVektor mit ein paar Ergänzungen ....


#include "My3Vector.h" // My3Vector declarations
class MyLVector : public My3Vector { // inherit from My3Vector
 private:        
   double t;
 public:  
   MyLVector();// The default constructor
   MyLVector(double c0, double c1, double c2, double c3);// Other constructor
   // methods:
   double Mass() const;  //   get mass of 4-vector
   double Mass(const MyLVector & p) const;  //   get mass of two 4-vector
 };
// implementation
MyLVector::MyLVector(double c0, double c1, double c2, double c3) :
  My3Vector(c1, c2, c3), t(c0) // special initialization syntax 
{}
 double MyLVector::Mass() const // Method for mass:
 {
   return( sqrt( t*t - x*x - y*y - z*z ) );
 }


Jetzt übernimmt bzw. erbt MyLVector alle Funktionen von My3Vector, z.B. Winkelberechnung funktioniert sofort:
  MyLVector c(1.000001,1.,0.,0.), d(2.,1.,1.,0.);
  c.Angle(d);

Falls Methode geändert werden muss, z.B. MyLVector::Add, entsprechend neu implementieren, bei c.Add(d) wird dann die MyLVector Version benutzt.


Vererbung ( "is-a" relationship) bedeutet alle Eigenschaften und Funktionen einer Grund-Klasse ( base class) in eine weitere Klasse ( derived class) zu übernehmen. Daraus ergibt sich eine enorme Erweiterung der Funktionalität. Ausgehend von vorhandenen, simplen Grundklassen können relativ leicht neue Klassen abgeleitet werden, ohne jedesmal diesselben grundlegenden Funktionen neu zu implementieren.

Allerdings: Vererbung nicht übertreiben, nicht immer sinnvoll.


Exkurs: Rechteck und Quadrat
Zunächst naheliegend Quadrat von Rechteck  abzuleiten (=vererben), viele Funktionen und Eigenschaften gemeinsam. Aber grundsätzliche Probleme bei Verhalten, z.B.:



class Rechteck {
  // ...
  void setLength( double);
  void setWidth( double);
  // ...
  double length, width;
};


Was soll ein Quadrat mit diesen Funktionen machen ?

setLength(..) bei Quadrat ändert immer auch width und vice-versa. Verhalten nicht kompatibel mit Rechteck .

Wichtig für OO Programmieren ist konsistentes Verhalten von Klassen, dazu wird Vererbung eingesetzt. Es geht weniger um bequemes Übernehmen von Funktionalität.

Mathematisch ist Quadrat Unterklasse von Rechteck, aber nicht im Sinne von OOP !


Weiteres zu Vererbung:


GDuckeck 2019-08-01