Skip to content

Commit

Permalink
Texts translated
Browse files Browse the repository at this point in the history
  • Loading branch information
TrollRoll2 committed Jun 6, 2024
1 parent 781b673 commit 7708869
Show file tree
Hide file tree
Showing 31 changed files with 1,095 additions and 1,074 deletions.
68 changes: 35 additions & 33 deletions data/osa-10/1-luokkahierarkiat.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
---
path: '/osa-10/1-luokkahierarkiat'
title: 'Luokkahierarkiat'
title: 'Klasshierarkier'
hidden: false
---

<text-box variant='learningObjectives' name='Oppimistavoitteet'>
<text-box variant='learningObjectives' name='Inlärningsmål'>

Tämän osion jälkeen
Efter den här delen

- Tiedät mitä tarkoitetaan perinnällä
- Osaat kirjoittaa luokkia jotka perivät jonkin toisen luokan
- Tiedät miten eri piirteet periytyvät
- Vet du vad arv betyder i programmeringssammanhang
- Kommer du att kunna skriva klasser som ärver andra klasser
- Vet du hur arv påverkar egenskaperna i klasser

</text-box>

## Luokkien erikoistaminen
## Specialklasser för speciella ändamål

Joskus tulee vastaan tilanne, jossa luokan toimintaa olisi hyvä pyrkiä erikoistamaan, mutta vain osalle olioista. Tarkastellaan esimerkkinä tilannetta, jossa meillä on kaksi luokkaa - Opiskelija ja Opettaja. Yksinkertaistuksen vuoksi luokista on jätetty pois kaikki asetus- ja havainnointimetodit.
Ibland stöter man på en situation där man redan har definierat en klass, men sedan inser att man behöver speciella egenskaper i vissa, men inte alla, instanser av klassen. Och ibland inser man att man har definierat två stycken mycket liknande klasser med bara små skillnader. Som programmerare strävar vi efter att alltid upprepa oss så lite som möjligt, medan vi behåller tydlighet och läsbarhet. Så hur kan vi ta hänsyn till olika implementeringar av liknande objekt?

Låt oss ta en titt på två klassdefinitioner: `Student` och `Larare`. Getter- och sättar-metoder har utelämnats tills vidare för att hålla exemplet kort.

```python

Expand All @@ -38,7 +40,9 @@ class Opettaja:

```

Yksinkertaistetustakin esimerkistä huomataan, että luokilla on yhteisiä piirteitä - tässä tapauksessa nimi ja sähköpostiosoite. Monessa tilanteessa olisi hyvä, jos yhteisiä piirteitä voitaisin käsitellä yhdellä operaatiolla: oletetaan tilanne, jossa koulun sähköpostitunnus muuttuu. Toki voitaisiin kirjoittaa kaksi käsittelyfunktiota...
Även i ett avskalat exempel som ovan har vi redan en hel del upprepningar: båda klasserna innehåller attributen `namn` och `epost`. Det vore en bra idé att ha en enda attributdefinition, så att det räcker med en enda funktion för att redigera båda attributen.

Tänk dig till exempel att skolans e-postadress ändras. Alla adresser skulle behöva uppdateras. Vi skulle kunna skriva två separata versioner av i stort sett samma funktion:

```python

Expand All @@ -50,15 +54,15 @@ def korjaa_email2(o: Opettaja):

```

...mutta saman koodin toistaminen kahteen kertaan tuntuu turhalta työltä, ja lisää virheiden mahdollisuutta. Olisi siis hyvä, jos molempien luokkien mukaisia olioita voitaisiin käsitellä samalla metodilla.
Att skriva i stort sett samma sak två gånger är onödig upprepning, för att inte tala om att det fördubblar möjligheterna till fel. Det skulle vara en klar förbättring om vi kunde använda en enda funktion för att arbeta med instanser av båda klasserna.

Luokat kuitenkin sisältävät myös piirteitä, joita toisella luokalla ei ole. Sen takia luokkien yhdistäminen ei tunnu järkevältä.
Båda klasserna har också attribut som är unika för dem. Att bara kombinera alla attribut i en enda klass skulle innebära att alla instanser av klassen då skulle ha onödiga attribut, bara olika för olika instanser. Det verkar inte heller vara en idealisk situation.

## Perintä
## Arv

Ratkaisu löytyy olio-ohjelmoinnin tekniikasta nimeltä _perintä_. Perinnällä tarkoitetaan sitä, että luokka _perii_ piirteet joltain toiselta luokalta. Näiden perittyjen piirteiden rinnalle luokka voi sitten toteuttaa uusia piirteitä.
Objektorienterade programmeringsspråk innehåller vanligtvis en teknik som kallas arv (eng. inheritance). En klass kan ärva egenskaper från en annan klass. Förutom dessa ärvda egenskaper kan en klass också innehålla egenskaper som är unika för den.

Opettaja- ja Opiskelija-luokilla voisi olla yhteinen _yliluokka_ `Henkilo`:
Med detta i åtanke är det rimligt att klasserna `Larare` och `Student` har en gemensam bas eller föräldraklass `Person`:

```python

Expand All @@ -70,9 +74,9 @@ class Henkilo:

```

Luokassa on toteutettu siis henkilöön liittyvät piirteet. Nyt luokat Opiskelija ja Opettaja voivat _periä_ luokan ja lisätä perittyjen ominaisuuksien rinnalle uusia piirteitä:
Den nya klassen innehåller de egenskaper som delas av de andra två klasserna. Nu kan `Student` och `Larare` ärva dessa egenskaper och dessutom lägga till sina egna. :

Perintä tapahtuu kirjoittamalla luokan nimen perään perittävän luokan nimi sulkuihin:
Syntaxen för arv innebär helt enkelt att basklassens namn läggs till inom parentes på rubrikraden:

```python

Expand Down Expand Up @@ -114,9 +118,9 @@ if __name__ == "__main__":

```

Koska sekä Opiskelija että Opettaja perivät luokan Henkilo, molemmilla on käytössään Henkilo-luokassa määritellyt piirteet, mukaanlukien metodi `vaihda_spostitunniste`.
Både `Student` och `Larare` ärver klassen `Person`, så båda har de egenskaper som definieras i klassen Person, inklusive metoden `uppdatera_epost_doman`. Samma metod fungerar för instanser av båda de härledda klasserna.

Tarkastellaan vielä toista esimerkkiä, jossa luokka Kirjahylly perii luokan Laatikko:
Låt oss titta på ett annat exempel. Vi har en `Bokhylla` som ärver klassen `BokLada`:

```python
class Kirja:
Expand Down Expand Up @@ -151,11 +155,11 @@ class Kirjahylly(Kirjalaatikko):

```

Luokassa Kirjahylly on määritelty metodi `lisaa_kirja`. Samanniminen metodi on määritelty myös yliluokassa `Kirjalaatikko`. Tällaisessa tapauksessa puhutaan metodin _uudelleenmäärittelystä_ tai ylikirjoituksesta (overwriting): aliluokan samanniminen metodi korvaa yliluokan vastaavan metodin.
Klassen `Bokhylla` innehåller metoden `tillägg_bok`. En metod med samma namn finns definierad i basklassen `BokLada`. Detta kallas överstyrning (eng. override): om en härledd klass har en metod med samma namn som basklassen, överstyr den härledda versionen originalet i instanser av den härledda klassen.

Esimerkissämme idea on, että kirjalaatikossa kirja asetetaan aina laatikossa päällimmäiseksi, mutta kirjahyllyssä voidaan määritellä asetuspaikka. Sen sijaan metodin `listaa_kirjat` uudelleenmäärittelyä ei ole nähty tarpeelliseksi - sama kirjojen listaus toimii niin laatikossa kuin hyllyssäkin (ainakin esimerkissämme).
Tanken i exemplet ovan är att en ny bok som läggs till i en BokLada alltid hamnar högst upp, men med en Bokhylla kan du själv ange platsen. Metoden `lista_böcker` fungerar likadant för båda klasserna, eftersom det inte finns någon överordnad metod i den härledda klassen.

Tarkastellaan esimerkkiä luokkien käyttämisestä:
Låt oss prova dessa klasser:

```python

Expand Down Expand Up @@ -203,13 +207,13 @@ Sinuhe (Mika Waltari)

</sample-output>

Myös Kirjahylly-luokasta muodostettujen olioiden kautta voidaan käyttää metodia `listaa_kirjat`, koska perinnän ansiosta se on olemassa myös luokan `Kirjahylly` aliluokissa.
Klassen Bokhylla har alltså också tillgång till metoden `lista_böcker`. Genom ärvning är metoden medlem i alla klasser som kommer från klassen `BokLada`.

## Piirteiden periytyminen
## Arv och räckvidd av egenskaper

Aliluokka perii yliluokalta kaikki piirteet. Aliluokasta voidaan viitata suoraan yliluokan piirteisiin, paitsi jos yliluokassa on määritelty piirteet yksityisiksi (käyttämällä kahta alaviivaa muuttujan nimen edessä).
En härledd klass ärver alla egenskaper från sin basklass. Dessa egenskaper är direkt åtkomliga i den härledda klassen, såvida de inte har definierats som privata i basklassen (med två understreck före egenskapens namn).

Niinpä esimerkiksi Kirjahylly-luokasta voitaisiin viitata yliluokan konstruktoriin sen sijaan että kirjoitettaisiin toiminnallisuus uudestaan:
Eftersom attributen för en Bokhylla är identiska med en BokLada, fanns det ingen anledning att skriva om konstruktorn för Bokhylla. Vi anropade helt enkelt basklassens konstruktor:

```python

Expand All @@ -220,9 +224,9 @@ Sinuhe (Mika Waltari)

```

Yliluokan konstuktoriin (tai yliluokkaan muutenkin) viitataan funktion `super()` avulla. Huomaa, että tässäkin tapauksessa parametri `self` lisätään automaattisesti.
Alla egenskaper i basklassen kan nås från den härledda klassen med funktionen `super()`. Argumentet `self` utelämnas från metodanropet, eftersom Python lägger till det automatiskt.

Tarkastellaan toisena esimerkkinä luokkaa Gradu, joka perii luokan Kirja. Aliluokasta kutsutaan yliluokan konstruktoria:
Men vad händer om attributen inte är identiska; kan vi fortfarande använda basklassens konstruktor på något sätt? Låt oss titta på en klass som heter `Avhandling` och som ärver klassen `Bok`. Den härledda klassen kan fortfarande anropa konstruktören från basklassen:

```python

Expand All @@ -243,9 +247,9 @@ class Gradu(Kirja):

```

Nyt Gradu-luokan konstruktorista kutsutaan yliluokan (eli luokan Kirja) konstruktoria, jossa asetetaan attribuuttien `nimi` ja `kirjailija` arvot. Sen jälkeen aliluokan konstruktorissa asetetaan attribuutin `arvosana` arvo - tätä luonnollisesti ei voida tehdä yliluokan konstruktorissa, koska yliluokalla ei tällaista attribuuttia ole.
Konstruktorn i `Avhandling`-klassen anropar konstruktorn i basklassen `Bok` med argumenten för `namn` och `forfattare`. Dessutom anger konstruktören i den härledda klassen värdet för attributet `vitsord`. Detta kan naturligtvis inte vara en del av basklassens konstruktor, eftersom basklassen inte har något sådant attribut.

Luokkaa voidaan käyttää esimerkiksi näin:
Ovanstående klass kan användas på följande sätt:


```python
Expand All @@ -269,9 +273,7 @@ Pekka Python

</sample-output>

Koska aliluokka `Gradu` perii kaikki yliluokan piirteet, se perii myös attribuutit `nimi` ja `kirjailija`. Arvot osalle attribuuteista annetaan yliluokan sisältä löytyvässä konstruktorissa.

Aliluokka voi myös viitata yliluokan metodiin, vaikka metodi olisikin määritelty uudestaan aliluokassa. Seuraavassa esimerkissä luokasta `Platinakortti` kutsutaan uudelleenmääritellyssä metodissa `bonuspisteet` yliluokan vastaavaa metodia.
Även om en härledd klass åsidosätter en metod i sin basklass kan den härledda klassen fortfarande anropa den åsidosatta metoden i basklassen. I följande exempel har vi ett grundläggande `BonusKort` och ett särskilt `PlatinumKort` för särskilt lojala kunder. Metoden `rakna_bonus` är åsidosatt i den härledda klassen, men den åsidosatta metoden anropar basmetoden:

```python

Expand Down Expand Up @@ -312,7 +314,7 @@ class Platinakortti(Bonuskortti):

```

Nyt platinakortin bonus lasketaan hyödyntämällä aluksi yliluokan vastaavaa metodia ja lisäämällä sitten ylimääräiset 5 prosenttia tähän bonukseen. Esimerkki luokkien käytöstä:
Bonusen för ett PlatinumKort beräknas alltså genom att anropa den överstyrda metoden i basklassen och sedan lägga till 5 procent extra till basresultatet. Ett exempel på hur dessa klasser används:

```python
if __name__ == "__main__":
Expand Down
28 changes: 14 additions & 14 deletions data/osa-10/2-nakyvyysmaareet.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
---
path: '/osa-10/2-nakyvyysmaareet'
title: 'Näkyvyysmääreet'
title: 'Åtkomstmodifierare'
hidden: false
---

<text-box variant='learningObjectives' name='Oppimistavoitteet'>
<text-box variant='learningObjectives' name='Inlärningsmål'>

Tämän osion jälkeen
Efter den här delen

- Tiedät mitä eroa on näkyvyysmääreillä yksityinen ja suojattu
- Tiedät, miten piirteiden näkyvyys määritetään Pythonissa
- Kommer du att förstå åtkomstmodifierarna privat och skyddad
- Vet du hur synligheten för egenskaper bestäms i Python

</text-box>

Aikaisemmin mainittiin, että yliluokassa yksityiseksi määritettyihin piirteisiin ei pääse käsiksi aliluokassa. Tarkastellaan esimerkkinä luokkaa `Muistikirja`, jossa muistiinpanojen säilyttämiseen käytettävä lista-attribuutti on piilotettu asiakkailta:
Om en egenskap definieras som privat i basklassen är den inte direkt åtkomlig i några härledda klasser, liksom kort nämndes i föregående avsnitt. Låt oss ta en titt på ett exempel. I klassen `Anteckningsbok` nedan lagras anteckningarna i en lista, och listattributet är privat:

```python

Expand All @@ -35,7 +35,7 @@ class Muistikirja:

```

Luokan sisäisen eheyden kannalta tietorakenteena toimivan listan piilottaminen asiakkaalta on sinänsä järkevää, koska luokka tarjoaa itse sopivat operaatiot muistiinpanojen lisäämiseksi ja selaamiseksi. Ongelmalliseksi tilanne muodostuu, jos yritetään kirjoittaa `Muistikirja`-luokan perivä luokka `ProMuistikirja`, johon halutaan lisätä muistiinpanojen etsiminen ja järjestäminen. Piilotettu attribuutti ei ole käytettävissä myöskään aliluokissa; metodi `etsi_muistiinpanot` antaa kutsuttaessa virheen:
Om klassens integritet är viktig är det vettigt att göra listattributen `anteckningar` privat. Klassen förser trots allt klienten med lämpliga metoder för att lägga till och bläddra i anteckningar. Detta tillvägagångssätt blir problematiskt om vi definierar en ny klass `AnteckningsbokPro`, som ärver `Anteckningsbok`-klassen. Det privata listattributet är inte tillgängligt för klienten, men det är inte heller tillgängligt för de härledda klasserna. Om vi försöker komma åt det, som i metoden `hitta_anteckningar` nedan, får vi ett felmeddelande:

```python
class MuistikirjaPro(Muistikirja):
Expand Down Expand Up @@ -66,11 +66,11 @@ AttributeError: 'MuistikirjaPro' object has no attribute '_MuistikirjaPro__muist



## Suojatut piirteet
## Skyddade egenskaper

Toisin kuin joistain muista ohjelmointikielistä, Pythonista ei suoraan löydy ominaisuutta joka piilottaa piirteet asiakkailta mutta samaan aikaan avaa ne mahdollisille aliluokille. Ratkaisuksi Python-yhteisö onkin päätynyt _konventioon_ eli yleisesti ymmärrettyyn merkintätapaan _suojatuille_ (eli _protected_) piirteille.
Många objektorienterade programmeringsspråk har en funktion, oftast ett speciellt nyckelord, för att skydda egenskaper. Detta innebär att en egenskap ska vara dold för klassens klienter, men hållas tillgänglig för dess underklasser. Python avskyr i allmänhet nyckelord, så ingen sådan funktion är direkt tillgänglig i Python. Istället finns det en konvention för att markera skyddade egenskaper på ett visst sätt.

Koska piirre voidaan piilottaa kirjoittamalla sen tunnisteen (eli nimen) eteen kaksi alaviivaa
Kom ihåg att en egenskap kan döljas genom att prefixera dess namn med två understreck:

```python

Expand All @@ -79,7 +79,7 @@ def __init__(self):

```

on yleisesti sovittu että yhdellä alaviivalla alkavat piirteet ovat tarkoitettu ainoastaan luokan ja sen aliluokkien käyttöön, eikä niitä tulisi käyttää suoraan sen ulkopuolelta.
Den överenskomna konventionen för att skydda en egenskap är att prefixera namnet med endast ett understreck. Nu är detta bara en konvention. Ingenting hindrar en programmerare från att bryta mot konventionen, men det anses vara en dålig programmeringspraxis.

```python

Expand All @@ -88,7 +88,7 @@ def __init__(self):

```

Alla on esitetty koko muistikirjaesimerkki uudestaan niin, että muistiinpanot on merkitty suojatuiksi yliluokassa yksityisen sijasta:
Nedan har vi hela Anteckningsbok-exemplet, med skyddade `_anteckningar` istället för privata `__anteckningar`:

```python

Expand Down Expand Up @@ -127,15 +127,15 @@ class MuistikirjaPro(Muistikirja):

```

Seuraavassa taulukossa on vielä esitetty piirteiden näkyvyys kaikkien eri suojausmääreiden tapauksessa:
Nedan har vi en praktisk tabell för synligheten av attribut med olika åtkomstmodifierare:

Näkyvyysmääre | Esimerkki | Näkyy asiakkaalle | Näkyy aliluokalle
:--:|:----:|:----:|:----:
Julkinen | `self.nimi` | kyllä | kyllä
Suojattu | `self._nimi` | ei | kyllä
Yksityinen | `self.__nimi` | ei | ei

Näkyvyysmääreet toimivat vastaavasti kaikkien piirteiden kanssa. Luokassa Henkilo oleva metodi `isot_alkukirjaimet` on suojattu, joten sitä voi käyttää myös aliluokassa Jalkapalloilija:
Åtkomstmodifierare fungerar på samma sätt med alla egenskaper. I klassen `Person` nedan har vi till exempel den skyddade metoden `kapitalisera_initialer` Den kan användas från den härledda klassen `Fotbollsspelare`:

```python

Expand Down
Loading

0 comments on commit 7708869

Please sign in to comment.