class LorentzVec(object): "Class for 4 Vector and operations" def __init__( self, t=0., x=0., y=0., z=0.): self.x = x self.y = y self.z = z self.t = t def Add( self, lv ): newvec = LorentzVec( self.t+lv.t, self.x+lv.x, self.y+lv.y, self.z+lv.z) return newvec def Angle( self, lv ): ... def Mass( self ): ...
Viele Gemeinsamkeiten mit ThreeVec und ein paar Erweiterungen
Design Prinzip Code-Reuse statt cut&paste !
LorentzVector enthält ThreeVector:
"has-a" relationship
(Aggregation).
class LorentzVec(object): "Class for 4 Vector and operations" def __init__( self, t=0., x=0., y=0., z=0.): self.v3 = ThreeVector( x, y, z ) # contains ThreeVector self.t = t def Add( self, tv ): w = self.v3 + tv.v3 # add ThreeVectors first newvec = LorentzVec( self.t+tv.t, w.x, w.y, w.z) return newvec def Angle( self, tv ): return( self.v3.Angle( tv.v3) # use ThreeVector Method def Mass( self ): ...
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 ....
class LorentzVec(ThreeVec): # inherits from ThreeVec "Class for 4 Vector and operations" def __init__( self, t=0., x=0., y=0., z=0.): ThreeVec.__init__( self, x, y, z ) # initialize ThreeVec self.t = t def Add( self, tv ): w = ThreeVec.Add( self, tv ) # call ThreeVec method first newvec = LorentzVec( self.t+tv.t, w.x, w.y, w.z) return newvec # def Angle( self, tv ): no need to define here, available from ThreeVec def Mass( self ): ...
Jetzt übernimmt bzw.
erbt
LorentzVector alle Funktionen
von
ThreeVec, z.B. Winkelberechnung funktioniert sofort:
c = LorentzVec(1.000001,1.,0.,0.)
d = LorentzVec(2.,1.,1.,0.)
c.Angle(d)
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, im Zweifelsfall Aggregation verwenden.
class Rechteck: def __init__( self, w, l ): self.w = w self.l = l // ... def setLength( self, len): ... def setWidth( self, wid): ... };
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 !