Objektumorientált programozás (OOP)
Az objektumorientált programozás (angolul Object-Oriented Programming – OOP) egy programozási megközelítés, amely objektumok használatán alapul.
Ezek az objektumok adatokat (attribútumokat) és az adatokkal kapcsolatos műveleteket (metódusokat) tartalmazzák.
Az OOP előnye, hogy segíti a programokat átláthatóbbá, újrafelhasználhatóvá és könnyen karbantarthatóvá tenni.
Alapfogalmak
- Osztály (class): Tervrajz vagy sablon, ami alapján objektumokat hozunk létre.
- Objektum (példány): Az osztály konkrét példánya, amely rendelkezik a tervben megadott tulajdonságokkal.
- Attribútum: Az objektum tulajdonsága (például név, életkor, szín).
- Metódus: Az objektum által végrehajtható művelet (például fut, beszél).
- Konstruktor: Egy speciális metódus, ami automatikusan fut le objektum létrehozásakor.
- Öröklődés: Egy új osztály létrehozása egy meglévő alapján, ahol az új osztály átveszi az eredeti tulajdonságait és metódusait.
- UML diagram: Egy grafikus ábra, ami bemutatja az osztályok közötti kapcsolatokat és struktúrákat.
UML diagram
Az UML (Unified Modeling Language) diagramok segítenek az osztályok és objektumok közötti kapcsolatok vizuális ábrázolásában.
Az UML diagramok különböző típusai léteznek, de a leggyakoribb a class diagram (osztálydiagram), amely az osztályok közötti kapcsolatokat mutatja be.
Az osztálydiagramok általában a következő elemeket tartalmazzák:
- Osztályok nevei
- Attribútumok nevei és típusai
- Metódusok nevei és típusai
---
title: UML diagram
---
classDiagram
class Kutya {
+String attributum1
+String attributum2
+metodus1()
+metodus2()
}
Példa
Vegyük például a kutyákat!
Képzeljük el a kutyákat:
- Osztály:
Kutya
- Attribútumok:
nev, szin, eletkor
- Metódusok:
ugat(), fut()
Az osztályhoz tartozó UML diagram:
---
title: UML diagram
---
classDiagram
class Kutya {
+String nev
+String szin
+Int eletkor
+ugat()
+fut()
}
Python megvalósítás
Osztály létrehozása
Osztály létrehozásához használd a class kulcsszót:
Megjegyzés
- Az osztályok neve mindig nagybetűvel kezdődik
- Az osztályok neve mindig egyes számú (Nem
Kutyak, hanem Kutya)
Objektum létrehozása, példányosítása:
class Kutya:
pass
kutyus = Kutya()
print(kutyus)
Metódusok
Konstruktor
A fenti példák osztályok és objektumok a legegyszerűbb formájukban, és nem igazán hasznosak a valós alkalmazásokban.
Az osztályok jelentésének megértéséhez meg kell értenünk a beépített __init__() függvényt.
Minden osztálynak van egy __init__() nevű függvénye, amely mindig végrehajtásra kerül az osztály indításakor.
Használd az __init__() függvényt, hogy értékeket rendelj az objektum tulajdonságaihoz, vagy más műveleteket, amelyeket az objektum létrehozásakor kell elvégezni:
| class Person: # osztály
def __init__(self, name, age): # konstruktor
self.name = name # atribútum
self.age = age # atribútum
p1 = Person("John", 36) # példányosítás
print(p1.name)
print(p1.age)
|
Megjegyzés
Az __init__() függvény automatikusan meghívásra kerül minden alkalommal, amikor az osztályt új objektum létrehozására használják.
str metódus
Az __str__() metódus meghatározza, hogy az objektum hogyan jelenik meg, amikor az print() függvényt használják rá.
Próbáljuk ki a fenti példát, hogy most mi jelenik meg!
| class Person: # osztály
def __init__(self, name, age): # konstruktor
self.name = name # atribútum
self.age = age # atribútum
p1 = Person("John", 36) # példányosítás
print(p1) # <__main__.Person object at 0x7f8b3c6b3b50>
|
Az előzőekben megjelent az objektum memóriacíme, de mi szeretnénk, ha az objektumunk tartalma jelenne meg.
Ehhez használjuk az __str__() metódust:
| class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name} {self.age} éves"
# Péládányosítás
p1 = Person("John", 36)
print(p1)
|
Saját metódusok
Az objektumok metódusokat is tartalmazhatnak. Az objektumokban lévő metódusok az objektumhoz tartozó függvények.
Hozzunk létre egy metódust a Person osztályban:
| class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def myfunc(self):
print("Hello my name is " + self.name)
p1 = Person("John", 36)
p1.myfunc()
|
Megjegyzés
A self paraméter az osztály aktuális példányára való hivatkozás, és az osztályhoz tartozó változók elérésére szolgál.
Attribútum
Az objektum attribútumának módosítása
Az objektumok tulajdonságait így módosíthatod:
Példa
| class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def myfunc(self):
print("Hello my name is " + self.name)
p1 = Person("John", 36)
p1.age = 40
print(p1.age)
|
Star Wars feladat
Tervezés
Nyissuk meg a korábbi órákban használt star-wars.csv állományt.
Tervezzünk hozzá egy osztályt! Elsőkén az UML diagramot rajzoljuk meg, majd készítsük el az osztályt!
UML
A táblázat (CSV) fejlécéből indulva rajzoljuk meg az osztályt!
---
title: UML diagram
---
classDiagram
class Karakter {
+String nev
+String rend
+String lezerkard
+Int midiklorian
}
Osztály
| class Karakter: #(1)
def __init__(self, nev: str, rend: str, lezerkard: str, midiklorian: int): #(2)
self.nev = nev #(3)
self.rend = rend #(3)
self.lezerkard = lezerkard #(3)
self.midiklorian = int(midiklorian) #(3)
def __str__(self): #(4)
return f"{self.nev} {self.rend} {self.lezerkard} {self.midiklorian}"
|
- osztály
- konstruktor
- attribútum
__str__ metódus
Logika
| class Karakter:
def __init__(self, nev: str, rend: str, lezerkard: str, midiklorian: int):
self.nev = nev
self.rend = rend
self.lezerkard = lezerkard
self.midiklorian = int(midiklorian)
def __str__(self):
return f"{self.nev} {self.rend} {self.lezerkard} {self.midiklorian}"
karakterek = [] # karakter osztálypéldányok
# fájl tartalmának beolvasása
file = open("star-wars.csv", "r", encoding="utf-8") # fájl megnyitása olvasásra
elsosor = file.readline() # fejléc olvasása (különben az első sor is bekerülne a listába)
for sor in file: # többi sor beolvasása
darabolt = sor.strip().split(",") # sor feldarabolása
karakterek.append( Karakter(darabolt[0], darabolt[1], darabolt[2], int(darabolt[3])) ) # karakter hozzáadása a listához
file.close()
# karakterek kiíratása
for peldany in karakterek:
print(peldany)
|
Átlagszámítás
Adjuk hozzá az előző kódhoz az átlagos midiklorian számítását!
Példa
| osszeg = 0
db = len(karakterek)
for peldany in karakterek:
osszeg += peldany.midiklorian
print(f"Az átlagos midiklorian szám: {osszeg/db}")
|
Teljes kód
| class Karakter:
def __init__(self, nev: str, rend: str, lezerkard: str, midiklorian: int):
self.nev = nev
self.rend = rend
self.lezerkard = lezerkard
self.midiklorian = int(midiklorian)
def __str__(self):
return f"{self.nev} {self.rend} {self.lezerkard} {self.midiklorian}"
peldanyok = [] # karakter osztálypéldányok
# -------------------------------------------------------------------------------
# fájl tartalmának beolvasása
file = open("star-wars.csv", "r", encoding="utf-8") # fájl megnyitása olvasásra
elsosor = file.readline() # fejléc olvasása (különben az első sor is bekerülne a listába)
for sor in file: # többi sor beolvasása
darabolt = sor.strip().split(",") # sor feldarabolása
peldanyok.append( Karakter(darabolt[0], darabolt[1], darabolt[2], int(darabolt[3])) ) # karakter hozzáadása a listához
file.close()
# -------------------------------------------------------------------------------
# átlagos midiklorian számítás
osszeg = 0
db = len(peldanyok)
for peldany in peldanyok:
osszeg += peldany.midiklorian
print(f"Az átlagos midiklorian szám: {osszeg/db}")
|
Minium keresés
Keressük meg azt a karaktert, akinek a legkevesebb a midiklorian száma! Adjuk meg az ő nevét és midiklorian számát!
Példa
| legkisebb = peldanyok[0] # első karakter kezdetben a legkisebb
for p in peldanyok: # karakterek bejárása
if p.midiklorian < legkisebb.midiklorian: # ha kisebb a midiklorian szám mint a legkisebbé nyilvánított karakteré
legkisebb = p # akkor ez lesz az új legkisebb
print(f"A legkisebb midiklorian számú karakter: {legkisebb.nev} ({legkisebb.midiklorian})")
|
Teljes kód
| class Karakter:
def __init__(self, nev: str, rend: str, lezerkard: str, midiklorian: int):
self.nev = nev
self.rend = rend
self.lezerkard = lezerkard
self.midiklorian = int(midiklorian)
def __str__(self):
return f"{self.nev} {self.rend} {self.lezerkard} {self.midiklorian}"
peldanyok = [] # karakter osztálypéldányok
# -------------------------------------------------------------------------------
# fájl tartalmának beolvasása
file = open("star-wars.csv", "r", encoding="utf-8") # fájl megnyitása olvasásra
elsosor = file.readline() # fejléc olvasása (különben az első sor is bekerülne a listába)
for sor in file: # többi sor beolvasása
darabolt = sor.strip().split(",") # sor feldarabolása
peldanyok.append( Karakter(darabolt[0], darabolt[1], darabolt[2], int(darabolt[3])) ) # karakter hozzáadása a listához
file.close()
# -------------------------------------------------------------------------------
legkisebb = peldanyok[0] # első karakter kezdetben a legkisebb
for p in peldanyok: # példányok bejárása
if p.midiklorian < legkisebb.midiklorian: # ha kisebb a midiklorian szám mint a legkisebbé nyilvánított karakteré
legkisebb = p # akkor ez lesz az új legkisebb
print(f"A legkisebb midiklorian számú karakter: {legkisebb.nev} ({legkisebb.midiklorian})")
|
Lézerkard színek számlálása
Számoljuk meg, hogy milyn típusú lézerkard színek vannak és ezekből hány darab található!
Úgy készítsük el a programot, hogy egy új szín hozáadásakor ne kelljen a kódot módosítani!
Tipp
Használjunk szótárat a lézerkard színek és darabszámok tárolására!
Példa
| lezerkard_szinek = {} # szótár a lézerkard színek és darabszámok tárolására
for p in peldanyok: # példányok bejárása
szin = p.lezerkard # lézerkard szín lekérése
if szin in lezerkard_szinek: # ha már szerepel a szín a szótárban
lezerkard_szinek[szin] += 1 # növeljük a darabszámot
else:
lezerkard_szinek[szin] = 1 # új szín hozzáadása a szótárhoz
|
Skywalkerek számlálása
Számoljuk meg, hogy hány Skywalker családnévvel rendelkező karakter van a fájlban!
Példa
| skywalker_db = 0 # Skywalkerek száma
for p in peldanyok: # példányok bejárása
if "Skywalker" in p.nev: # ha a név tartalmazza a Skywalker szót
skywalker_db += 1 # növeljük a számlálót
print(f"Skywalkerek száma: {skywalker_db}")
|
Példányok rendezése
Az előző feladatokhoz használt kódot egészítsük ki azzal, hogy a karaktereket rendezzük a midiklorian számuk szerint növekvő sorrendbe, majd írjuk ki a rendezett listát!
Példa
| peldanyok.sort(key=lambda x: x.midiklorian) # rendezés midiklorian szám szerint
for p in peldanyok: # példányok bejárása
print(p) # kiíratás
|