← IT

Objektově orientované programování

Doplněný obsah — není z archivu podkladů, napsáno podle ŠVP. Vhodné ověřit u vyučujícího.

Pozn. ke kódu: obecné principy jsou popsané slovně, ke každému klíčovému pojmu je pak ukázka reálného kódu v Pythonu a v C# vedle sebe – oba jazyky se ve výuce běžně používají a princip OOP je v nich (i ve všech dalších běžných OOP jazycích) stejný.

Třída a objekt

Python:

class Auto:
    def zrychli(self, o_kolik):
        self.rychlost += o_kolik

# vytvoření objektu (instance) třídy Auto
auto1 = Auto()
auto1.barva = "červená"      # atribut
auto1.rychlost = 0
auto1.zrychli(20)             # volání metody
print(auto1.rychlost)         # 20

C#:

class Auto
{
    public string Barva;      // atribut
    public int Rychlost;

    public void Zrychli(int oKolik)   // metoda
    {
        Rychlost += oKolik;
    }
}

// vytvoření objektu (instance) třídy Auto
Auto auto1 = new Auto();
auto1.Barva = "červená";
auto1.Rychlost = 0;
auto1.Zrychli(20);
Console.WriteLine(auto1.Rychlost);   // 20

Konstruktor

Python: konstruktor se jmenuje vždy __init__ a jeho prvním parametrem je self (odkaz na vytvářený objekt):

class Auto:
    def __init__(self, zadana_barva):    # konstruktor
        self.barva = zadana_barva
        self.rychlost = 0

    def zrychli(self, o_kolik):
        self.rychlost += o_kolik

auto1 = Auto("červená")   # zavolá se __init__
auto1.zrychli(20)
print(auto1.barva, auto1.rychlost)   # červená 20

C#: konstruktor má stejný název jako třída a nemá návratový typ:

class Auto
{
    public string Barva;
    public int Rychlost;

    public Auto(string zadanaBarva)   // konstruktor
    {
        Barva = zadanaBarva;
        Rychlost = 0;
    }

    public void Zrychli(int oKolik)
    {
        Rychlost += oKolik;
    }
}

Auto auto1 = new Auto("červená");   // zavolá se konstruktor
auto1.Zrychli(20);
Console.WriteLine($"{auto1.Barva} {auto1.Rychlost}");   // červená 20

Přetěžování metod a konstruktoru

Python nemá klasické přetěžování (novější definice metody/konstruktoru se stejným jménem by tu předchozí jen přepsala) – řeší se výchozími hodnotami parametrů:

class Auto:
    def __init__(self, barva="bílá"):   # výchozí hodnota nahrazuje přetížení
        self.barva = barva

auto1 = Auto()             # barva = "bílá"
auto2 = Auto("červená")    # barva = "červená"

C# skutečné přetěžování podporuje – v jedné třídě může být víc konstruktorů/metod se stejným jménem:

class Auto
{
    public string Barva;

    public Auto()                     // konstruktor bez parametrů
    {
        Barva = "bílá";
    }

    public Auto(string zadanaBarva)   // přetížený konstruktor s parametrem
    {
        Barva = zadanaBarva;
    }
}

Auto auto1 = new Auto();             // Barva = "bílá"
Auto auto2 = new Auto("červená");    // Barva = "červená"

Zapouzdření

Python:

class Auto:
    def __init__(self):
        self._rychlost = 0   # podtržítko = konvence pro "privátní" atribut

    def get_rychlost(self):            # getter
        return self._rychlost

    def set_rychlost(self, hodnota):   # setter s validací
        if hodnota < 0:
            raise ValueError("Rychlost nemůže být záporná")
        self._rychlost = hodnota

auto1 = Auto()
auto1.set_rychlost(50)
print(auto1.get_rychlost())   # 50

C#:

class Auto
{
    private int rychlost;   // private = přístupné jen uvnitř třídy

    public int Rychlost     // vlastnost (property) = getter + setter dohromady
    {
        get { return rychlost; }
        set
        {
            if (value < 0)
                throw new ArgumentException("Rychlost nemůže být záporná");
            rychlost = value;
        }
    }
}

Auto auto1 = new Auto();
auto1.Rychlost = 50;
Console.WriteLine(auto1.Rychlost);   // 50

Dědičnost

Python:

class Vozidlo:
    def __init__(self, znacka):
        self.znacka = znacka
        self.rychlost = 0

    def zrychli(self, o_kolik):
        self.rychlost += o_kolik

class Auto(Vozidlo):    # Auto dědí od Vozidlo
    def __init__(self, znacka, pocet_dveri):
        super().__init__(znacka)   # volání konstruktoru předka
        self.pocet_dveri = pocet_dveri

auto1 = Auto("Škoda", 5)
auto1.zrychli(30)       # zděděná metoda
print(auto1.znacka, auto1.rychlost, auto1.pocet_dveri)

C#:

class Vozidlo
{
    public string Znacka;
    public int Rychlost;

    public Vozidlo(string znacka)
    {
        Znacka = znacka;
    }

    public void Zrychli(int oKolik)
    {
        Rychlost += oKolik;
    }
}

class Auto : Vozidlo    // Auto dědí od Vozidlo
{
    public int PocetDveri;

    public Auto(string znacka, int pocetDveri) : base(znacka)   // volání konstruktoru předka
    {
        PocetDveri = pocetDveri;
    }
}

Auto auto1 = new Auto("Škoda", 5);
auto1.Zrychli(30);      // zděděná metoda
Console.WriteLine($"{auto1.Znacka} {auto1.Rychlost} {auto1.PocetDveri}");

Polymorfismus

Python:

class Zvire:
    def vydej_zvuk(self):
        return "..."

class Pes(Zvire):
    def vydej_zvuk(self):     # přepsání (override) metody předka
        return "Haf!"

class Kocka(Zvire):
    def vydej_zvuk(self):
        return "Mňau!"

zvirata = [Pes(), Kocka()]
for zvire in zvirata:
    print(zvire.vydej_zvuk())   # Haf! / Mňau! - podle skutečného typu objektu

C#:

class Zvire
{
    public virtual string VydejZvuk()   // virtual = potomci ji mohou přepsat
    {
        return "...";
    }
}

class Pes : Zvire
{
    public override string VydejZvuk()   // přepsání (override) metody předka
    {
        return "Haf!";
    }
}

class Kocka : Zvire
{
    public override string VydejZvuk()
    {
        return "Mňau!";
    }
}

List<Zvire> zvirata = new List<Zvire> { new Pes(), new Kocka() };
foreach (Zvire zvire in zvirata)
{
    Console.WriteLine(zvire.VydejZvuk());   // Haf! / Mňau! - podle skutečného typu objektu
}

Kolekce objektů

Python:

seznam_aut = []
seznam_aut.append(Auto("červená"))
seznam_aut.append(Auto("modrá"))

for auto in seznam_aut:
    auto.zrychli(10)

C#:

List<Auto> seznamAut = new List<Auto>();
seznamAut.Add(new Auto("červená"));
seznamAut.Add(new Auto("modrá"));

foreach (Auto auto in seznamAut)
{
    auto.Zrychli(10);
}

Návrh programu s využitím OOP

Verzovací systém