Luokan jäsenmuuttujina voi olla niin Pythonin sisäänrakennettuja muuttujia kuin itse tehtyjä luokkia - tätä kutsutaan koostamiseksi. Koostaminen on yksinkertaisin tapa sisällyttää luokkaan jo olemassa olevaa toiminnallisuutta. Toinen tapa on perintä.
Perinnässä toinen luokka perii toisen luokan ja saa käyttöönsä kaikki perityn luokan jäsenmuuttujat ja metodit. Perittyä luokkaa kutsutaan kantaluokaksi ja luokkaa, joka perii, aliluokaksi. Pythonissa perintä tehdään kirjoittamalla kantaluokka luokkamäärityksessä tehtävän luokan nimen jälkeen sulkeisiin.
Perintä on toimiva ohjelmointi tekniikka kun halutaan tehdä luokka, jolle halutaan toiminnallisuus, joka on jo olemassa olevilla luokilla. Perintä on siis tapa laajentaa tai parannella ohjelman osia. Toisaalta perinnän avulla säästää vaivaa tilanteissa, joissa tarvitaan kaksi lähes samankaltaista luokkaa; tekemällä molemmille luokille yhteinen aliluokka, jolla on luokille yhteinen toiminnallisuus.
Mietitään esimerkiksi tilannetta, jossa tarvitaan edellä näytetyn alipäästösuotimen lisäksi seuraavanlainen ylipäästösuodin hpFilter.
class hpFilter: _pointer = 0 _output = 0.0 def __init__(self, maxNumberOfValues = 10): self._numberOfValues = maxNumberOfValues self._values = [0.0] * maxNumberOfValues def getValue(self): return self._output def insertValue(self, x): self._pointer = (self._pointer + 1) % self._numberOfValues self._values[self._pointer] = x self._calculateOutput() return self._output def _calculateOutput(self): sum = 0.0 for i in self._values: sum += i self._output = self._values[pointer] - sum / self._numberOfValues def __add__(self, rside): return self._output + rside._output
Luokka hpFilter on hyvin samanlainen kuin lpFilter - ero on lähinnä vain suodatetun arvon laskemisessa. Sen sijaan, että luotaisiin näin erillisiä luokkia, olisi kätevämpää tehdä aluksi ns. abstrakti luokka, eli luokka, joka ei ole tarkoitettu käytettäksi sellaisenaan, vaan jota laajennetaan perinnän avulla. Tässä luokka abstractFilter, jossa on kaikki luokkien lpFilter ja hpFilter toiminnallisuus paitsi ulostulon laskeminen.
abstractfilter.py:
class abstractFilter: _pointer = 0 _output = 0.0 def __init__(self, maxNumberOfValues = 10): self._numberOfValues = maxNumberOfValues self._values = [0.0] * maxNumberOfValues def getValue(self): return self._output def insertValue(self, x): self._pointer = (self._pointer + 1) % self._numberOfValues self._values[self._pointer] = x self._calculateOutput() return self._output def __add__(self, rside): return self._output + rside._output
Nyt on helppo tehdä sekä lpFilter että hpFilter vain perimällä abstractFilter ja määrittämällä ulostulon laskevan funktion. Tässä yli- ja alipäästösuodin perinnän avulla toteutettuna.
lpfilter.py:
from abstractfilter import abstractFilter class lpFilter(abstractFilter): def _calculateOutput(self): sum = 0.0 for i in self._values: sum += i self._output = sum / self._numberOfValues
hpfilter.py:
from abstractfilter import abstractFilter class hpFilter(abstractFilter): def _calculateOutput(self): sum = 0.0 for i in self._values: sum += i self._output = self._values[pointer] - sum / self._numberOfValues
Tässä vaiheessa kannattanee sanoa, ettei esimerkeissä käytetty keskiarvon ottaminen välttämättä suodata täydellisesti joka tilanteessa. Esimerkeissä on käytetty kumminkin yksinkertaisia algoritmeja selkeyden vuoksi.
Pythonissa on myös mahdollisuus moniperintään, joka tarkoittaa, että luokka perii useita kantaluokkia. Perimällä yksi kantaluokka, aliluokka saa vain sen toiminnallisuuden; vastaavasti perimällä useampi, saadaan useamman kantaluokan toiminnallisuus. Moniperintä tehdään luettelemalla luokan nimen jälkeisissä sulkeissa yhden kantaluokan sijasta useampi pilkulla erotettuna.