Objekt
- Objekt kirjeldab ära konkreetse loogilise kogumi
- näiteks õues olev punane auto on üks objekt
- selle taga olev roheline auto on teine objekt jne
- Tavaliselt mõtleme me arvust kui ühest väärtusest (nt 7)
- Objekt koosneb tavaliselt mitmest väärtusest
- värv, mark, mudel, pikkus, registrimass jne
clase objekt
{
“name”: |”ago”| “kati”|
“id-code”:| | |
“phone:”| | |
}
[{ago…}, {kati…}]
[“ago”, “kati”]
[111, 112]
.
.
.
[…, …]
Klass
- Klass kirjeldab ära struktuuri
- näiteks autol on värv, pikkus jne
- Klass (üldiselt) ei sisalda andmeid
- Klass on andmetüüp
- Samatüüpi andmed pärinevad köik ühest klassist
- punane auto on auto, roheline auto on auto jne
- Kuigi meil on maailmas mitu autot (objekti), siis meil on ü auto
OOP
- Objekt-orienteeritud programmeerimine (OOP) on programmeerimise paradigma, mis kasutab objekte
- Python on objekti-orienteeritud programmeerimiskeel (OOP)
- Pythonis kõik asjad on objektid
OOP tehnikad
- Kapseldamine (encapsulation)
- funktsionaalsus peidetakse
- Modulaarsus (modularity)
- programm jagatakse iseseisvateks tükkideks
- Polümorfism (polymorphism)
- alamklass saab meetodeid üle kirjutada
- Pärimine (inheritance)
- alamklass saab meetodeid üle kirjutada
- Abstraktioon
- aitab luua klassi, kasutatakse tarbetu teabe peitmiseks ja ainult vajaliku teabe kuvamiseks suhtlevatele kasutajatele
Sõne
- Sõne on objekt
- Kui loote uue sõne, siis tegelikult luuakse uus objekt, mille tüüp on str.
- Sõne “funktsioone” kutsutakse meetoditeks
- ehk siis klassis kirjeldatud funktsioonid on meetodid
s = "Hello"
print(type(s)) # < class 'str' >
print(id(s)) # 30773472
print(id(s.replace( "H", "h"))) # 61507648
- Loome sõne s ja küsime selle tüübi. Tüüp on str klass
- id tagastab objekti kohta unikaalse arvu. Kui id on erinev, siis on ka objekt erinev (st mälus erinevas kohas)
- replace teeb uue sõne, seda näeme ka id-ga
List
a = [1, 2, 3]
b = [1, 2, 3]
c = b
print(id(a)) # 44058024
a.append(4)
print(id(a)) # 44058024 still the same
print(id(b)) # 44059184
print(id(c)) # 44059184 - same as b
b.pop()
print(id(b)) # 44059184 - still the same
print(id(c)) # 44059184 - and same
Veel objekte
print(type(1)) # <class 'int'>
print(type(True)) # <class 'bool'>
print(type(1.2)) # <class 'float'>
print(type(None)) # <class 'NoneType'>
print(type(len)) # <class 'builtin_function_or_method'>
print(type(type)) # <class 'type'>
Klass kui andmetüüp
- Iga klass on andmetüüp
- Näiteks on Pythonis klass
str
- Iga konkreetne sõne, näiteks
"tere"
, on selle klassi objekt (ehk isend) - Ühest klassist saab luua lõpmata palju objekte
- Objekti kohta öeldakse ka isend ja instants
- Üldiselt mõeldakse “objekt”, “isend”, “instants” terminitega samu asju
- Erinevates allikates võivad neil erinevused olla
Teeme oma klassi
class Student:
pass
s = Student()
print(type(s)) # <class '__main__.Student'>
print(id(s)) # 12448112
t = Student()
print(type(t)) # <class '__main__.Student'>
print(id(t)) # 12423408
- Klass
Student
.pass
on tühi korraldus - Loome kaks isendit – nende
id
on erinev (nad on mälus erinevas kohas)
Objektide võrdlemine
- Objektide võrdlemine
==
võrdlusega kontrollib vaikimisi seda, kas nad viitavad samale objektile - Seda, mida täpselt kontrollitakse, saab üle kirjutada
- Näiteks sõne puhul kontrollitakse seda, kas sisu (st sümbolid) on samad jne
s1 = Student()
s2 = Student()
s3 = s1
print(s1 == s2) # False
print(s1 == s3) # True
print(s2 == s3) # False
Meetod
- Klassis sisalduvaid funktsioone nimetatakse meetoditeks
class Student:
"""Student class."""
def hello(self): # method, "self" is a special parameter
"""Method (function) which just prints out "Hello!"."""
print("Hello!")
s = Student() # s is an object of class Student
s.hello() # no "self" argument
self
- Kõik objekti meetodid sisaldavad esimest parameetrit
self
- selle parameetri nimi võib ka midagi muud olla; kasutage
self
- selle parameetri nimi võib ka midagi muud olla; kasutage
self
viitab isendile- Eelmises näites oli väljakutse
s.hello()
- kui
hello()
meetod käima pannakse, antakse selleles
kaasa
- kui
- Meetodi jaoks vajalike väärtuste jaoks lisatakse need peale
self
parameetrit
self
ja parameetrid
class Student:
def greet_friend(self, friend_name):
print(f"Hello, {friend_name}")
s = Student()
s.greet_friend("Kaia")
- Meetodi kirjelduses esimesel kohal on
self
, teisel kohalfriend_name
. - Kui kutsume välja
greet_friend
meetodit, siis esimesena kaasa antud argument läheb teise parameetrisse jne.
Konstruktor
- Objekti loomisel pannakse käima eriline meetod ehk konstruktor
- Meetod kirjeldatakse:
__init__(self)
- See meetod pannakse käima üks kord objekti loomisel
- Eelnevas näites
s = Student()
kutsub välja konstruktori - Konstruktori kirjeldamine ei ole kohustuslik
- Konstruktor peab tagastama
None
(eraldireturn
lauset ei kirjutata).
Konstruktor
- Kirjeldatakse nagu tavaline meetod
- Eraldi pole vaja välja kutsuda
class Student:
def __init__(self):
print("Initializing student..")
s = Student() # Initializing student..
Student()
kutsubStudent
klassi konstruktori välja.
Konstruktor, objekti muutujad
self
viitab loodavale/loodud objektile- Konstruktorisse saab kaasa anda argumente (nagu tavaline funktsioon)
- Esimene parameeter on alati
self
- Objekti muutujad on seotud ühe konkreetse objektiga (isendiga)
- Objekti muutujaid väärtustatakse:
self.name = ...
- Tavaliselt luuakse konstruktoris vajalikud väljad ära
- Objekti muutujaid saab teistes objekti meetodites kasutada
class Student:
def __init__(self, name, title):
self.name = name
self.title = title
ago = Student("Ago", "Sir")
print(ago.name)
leela = Student("Leela", "Captain")
print(leela.title)
- Konstruktori parameeter
self
viitab loodavale objektile. - Parameetrid
name
jatitle
salvestatakse objekti muutujateks:self.name
jaself.title
Objekti muutujad
class Shop:
def __init__(self, name, age, products_file=None):
self.products = []
self.name = name
self.established = 2020 - age
if products_file is not None:
# open the file and read products from it
pass
def inventory(self):
print(f"Inventory for {self.name} (est. {self.established}:")
for p in self.products:
print("product: ..")
Klass (class)
- Defineerib andmetüübi
- Šabloon, mida saab hiljem kasutada, et luua konkreetseid objekte (isendeid)
class Point2D:
"""Point in (x, y) coordinate space."""
def __init__(self, x, y):
self.x = x
self.y = y
def print_point(self):
print(f"({self.x:.2f}, {self.y:.2f})")
Objekt (object)
- Konkreetne isend, instants (instance)
- Luuakse klassi kirjeldusest
- Klassist võib luua lõpmata palju objekte
- Samast klassist loodud objektid on sarnase struktuuriga (neil on samad meetodid ja muutujad)
- Aga igal objektil on oma olek (muutujate väärtused)
p1 = Point2D(1.234, 0.23456)
p2 = Point2D(-1, 3)
p1.print_point() # (1.23, 0.23)
p2.print_point() # (-1.00, 3.00)
Klass ja objekt
class Point2D:
"""Point in (x, y) coordinate space)."""
def __init__(self, x, y):
self.x = x
self.y = y
def print_point(self):
print(f"({self.x:.2f}, {self.y:.2f})")
p1 = Point2D(1.234, 0.23456)
p2 = Point2D(-1, 3)
p1.print_point() # (1.23, 0.23)
p2.print_point() # (-1.00, 3.00)
Objektide võrdlemine
p3 = Point2D(3, 3)
p4 = Point2D(3, 3)
p5 = p4 # both refer to the same object in memory
print(p3 == p4) # False, although same values, objects are different
print(p4 == p5) # True
p3.x = 10
p3.print_point() # (10.00, 3.00)
p4.x = 11
p4.print_point() # (11.00, 3.00)
p5.print_point() # (11.00, 3.00), p5 points to p4
Erilised meetodid
- Python võimaldab klassis ära kirjeldada objekti käitumist erinevates olukordades
- Näiteks
__eq__
meetodit kasutatakse selleks, et võrrelda objekte==
võrdlusega __str__
meetodit kasutatakse, et saada objektist sõne kuju- Lisaks näiteks
__add__(self, other)
objektide liitmiseks jne __lt__(self, other)
väikem-kui võrdluseks__len__(self)
kui rakendatakselen(self)
Objektide võrdlus
- Punkti puhul oleks mõistlik realiseerida objektide võrdlus väärtuste järgi
- Kui kahel punktil on mõlemad koordinaadid samad, siis on ka objektid võrdsed.
class Point2D:
# constructor and print_point() same as previously
def __eq__(self, other):
if isinstance(other, Point2D):
return self.x == other.x and self.y == other.y
return False
__eq__
meetod käivitatakse võrdlemisel
p6 = Point2D(1, 2)
p7 = Point2D(1, 2)
print(p6 == p7) # True
print(p6 is p7) # False
p8 = p6
print(p6 is p8) # True
- Võrdleme nüüd kahte objekti
==
võrdlusega. Tulemus on tõene, kuna käivitub__eq__
meetod, mis võrdleb sisu. is
võrdlus kontrollib, kas viidatakse samale objektile
Objekt sõnena
__str__(self)
meetod võimaldab kirjeldada, mida objekti puhul sõnena tagastatakse- Näiteks printimisel kasutatakse seda
- Samuti
str(obj)
puhul. - Meetod tagastab sõne
- Vaikimisi
print(p1)
kuvab midagi sellist<__main__.Point2D object at 0x0050D5D0>
.
class Point2D:
# ...
def __str__(self):
return f"({self.x:.2f}, {self.y:.2f})"
p1 = Point2D(1, 2)
print(p1) # (1.00, 2.00)
- Pythonis on eriline meetod
__repr__
, mille eesmärk on tagastada üheselt mõistetav sõne.- Tihti tagastatakse sõne, millega saab objekti luua
eval()
funktsiooni abil
- Tihti tagastatakse sõne, millega saab objekti luua
- Kui
__str__
pole defineeritud, kutsutakse__repr__
välja. __str__
meetodi eesmärk on pigem olla informatiivne- Seega alati on mõistlik kirjeldada
__repr__
class Point2D:
def __repr__(self):
return f"Point2D({self.x}, {self.y})"
Klassi muutujad
- Klassi muutuja kirjeldatakse klassi sees väljaspool meetodeid
- Klassi muutujal on üks väärtus läbi terve programmi
- Sõltumata sellest, mitu objekti klassist luuakse, klassi muutujal on üks ühine väärtus
- Üldiselt ei ole vaja kasutada
Klassi muutuja näide
class Doorbell:
click_count = 0
def __init__(self):
self.click_count = 0
def ring(self):
print("Ringing..")
self.click_count += 1
Doorbell.click_count += 1
d1 = Doorbell()
d2 = Doorbell()
for _ in range(10): d1.ring()
for _ in range(4): d2.ring()
print(d1.click_count) # 10
print(d2.click_count) # 4
print(Doorbell.click_count) # 14
Objekti väärtuste pärimine/muutmine
- Kapseldamise eesmärk on peita objekti olek maailma eest ning lubada selle muutmine vaid läbi teatud meetodite.
- Objekti väärtuste muutmiseks kasutatakse tavaliselt getter ja settermeetodeid
- See annab võimaluse kontrollida, mida ja kuidas tagastatakse/muudetakse
class Student:
def __init__(self, name):
self.name = name
def set_name(self, name):
self.name = name
def get_name(self):
return self.name