Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Wiki Markup
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.

{code}
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
{code}
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:


{code}
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
{code}
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:


{code}
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
{code}
hpfilter.py:

{code}
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
{code}
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.