I've been learning how to implement composition into my python programming, but I'm struggling to understand why it's preferred over inheritance.
For example, here is my code so far:
class Particle:
# Constructor (public)
def __init__(self, _name, _charge, _rest_energy, _mass, _velocity):
# Attributes (private)
self.__name = _name
self.__charge = _charge
self.__restEnergy = _rest_energy
self.__mass = _mass
self.__velocity = _velocity
# Getter functions (public)
def getName(self):
return self.__name
def getCharge(self):
return self.__charge
def getRestEnergy(self):
return self.__restEnergy
def getMass(self):
return self.__mass
def getVelocity(self):
return self.__velocity
# Setter procedures (public)
def setName(self, _name):
self.__name = _name
def setCharge(self, _charge):
self.__charge = _charge
def setRestEnergy(self, _rest_energy):
self.__restEnergy = _rest_energy
def setMass(self, _mass):
self.__mass = _mass
def setVelocity(self, _velocity):
self.__velocity = _velocity
class Quark:
# Constructor (public)
def __init__(self, _name, _charge, _strangeness):
# Attributes (private)
self.__name = _name
self.__charge = _charge
self.__strangeness = _strangeness
# Getter functions (public)
def getName(self):
return self.__name
def getCharge(self):
return self.__charge
def getStrangeness(self):
return self.__strangeness
class Hadron:
# Constructor (public)
def __init__(self, _name, _charge, _rest_energy, _mass, _velocity, _quarks):
# Attributes (private)
self.__particle = Particle(_name, _charge, _rest_energy, _mass, _velocity)
self.__quarks = _quarks
# Getter functions (public)
def getParticle(self):
return self.__particle
def getQuark(self):
return self.__quarks
def getStrangeness(self):
_quarks = self.__quarks
_strangeness = 0
for _quark in _quarks:
_strangeness += _quark.getStrangeness()
return _strangeness
def getRelCharge(self):
_quarks = self.__quarks
_relCharge = 0
for _quark in _quarks:
_relCharge += _quark.getCharge()
return _relCharge
def getName(self):
return self.__particle.getName()
def getCharge(self):
return self.__particle.getCharge()
def getRestEnergy(self):
return self.__particle.getRestEnergy()
def getMass(self):
return self.__particle.getMass()
def getVelocity(self):
return self.__particle.getVelocity()
# Setter functions (public)
def setName(self, _name):
self.__particle.setName(_name)
def setCharge(self, _charge):
self.__particle.setCharge(_charge)
def setRestEnergy(self, _rest_energy):
self.__particle.setRestEnergy(_rest_energy)
def setMass(self, _mass):
self.__particle.setMass(_mass)
def setVelocity(self, _velocity):
self.__particle.setVelocity(_velocity)
I'm not sure if I've gotten the wrong end of the stick here or what, but it seems incredibly wasteful, when I could just inherit from the Particle class.
Am I doing something wrong?
Which you use depends on what relationship you're trying to model.
Composition isn't always the better option. "Composition over inheritance" is often repeated because inheritance is often abused with the idea that it reduces the amount of code that you need to write. That's entirely the wrong motivation to base your decision on though.
If you have two classes, A
and B
, a rough, general guide is:
B
is an A
, you probably want inheritance.B
has an A
, you probably want composition.In your case here, from my extraordinarily limited knowledge of particle physics, a Hadron
is a Particle
, so inheritance is probably a better fit. A Hadron
doesn't contain/have a Particle
, so I think you're trying to work against the grain by forcing composition here.