Programowanie obiektowe cz 2

Programowanie obiektowe cz 2

Do przygotowania przed zajęciami

* Python dla każdego. Podstawy programowania. – Michael Dawson – Helion **R** – Rozdział 8. Wprowadzenie. Koniec gry.

Cel i tematyka zajęć

Dzisiejsze laboratorium ma na celu zapoznanie Państwa z następującymi zagadnieniami:
* podstawy programowania obiektowego,
* atrybuty prywatne,
* metody prywatne,
* właściwości.

– Zadanie przypominające

* Utwórz program symulujący lokacje, tworzący je jako obiekty. Wyświetl użytkownikowi opis swojej lokacji. Stwórz 5 lokacji. Użytkownik ma mieć możliwość wybrania lokalizacji po jej nazwie w celu wyświetlenia opisu.

Hermetyzacja obiektów

Z hermetyzację spotkaliście się już Państwo wcześniej przy funkcjach. Tak jak w przypadku funkcji gdzie główny program powinien komunikować się za pomocą parametrów i wartości zwracanych, tak i w przypadku obiektów program (klient) nie powinien mieć dostępu i możliwości modyfikacji bezpośredniej atrybutów.

Metody i atrybuty prywatne

Nazwy atrybutów i metod prywatnych rozpoczynamy od podwójnego podkreślenia, ale w przeciwieństwie do metod specjalnych nie kończymy ich za pomocą podwójnego podkreślenia.

# Prywatny zwierzak
# Demonstruje zmienne i metody prywatne

class Critter(object):
"""Wirtualny pupil"""
def __init__(self, name, mood):
print("Urodził się nowy zwierzak!")
self.name = name # atrybut publiczny
self.__mood = mood # atrybut prywatny

def talk(self):
print("\nJestem", self.name)
print("W tej chwili czuję się", self.__mood, "\n")

def __private_method(self):
print("To jest metoda prywatna.")

def public_method(self):
print("To jest metoda publiczna.")
self.__private_method()

# mein
crit = Critter(name = "Reksio", mood = "szczęśliwy")
crit.talk()
crit.public_method()

input("\n\nAby zakończyć program, naciśnij klawisz Enter.")


Dostęp do tych metod spoza klasy w naszym przypadku __Critter__ jest utrudniony. Python zwraca błąd w sytuacji gdy chcemy odwołać się do atrybutu spoza klasy.

Dostęp do atrybutów prywatnych

Pomimo tego, że dostęp do atrybutów prywatnych jest utrudniony to nie jest on technicznie niemożliwy. Python ukrywa te atrybuty za specjalną sekwencją przedstawioną poniżej.

print(crit._Critter__mood)


Dostęp do metod prywatnych
Tak jak w przypadku atrybutów tak i w przypadku metod prywatnych z założenia powinny z nich korzystać elementy wewnątrz klasy. Dostęp z zewnątrz wygląda następująco

crit._Critter__private_method()
Kontrolowanie dostępu do atrybutów

Atrybuty prywatne powinny być używane tylko wtedy gdy jest to naprawdę konieczne. Jeśli nie ma konieczności używania atrybutu prywatnego, a chcielibyśmy ograniczyć np. możliwość modyfikacji wtedy z pomocą przychodzi nam właściwości atrybutów.

# Zwierzak z właściwością
# Demonstruje właściwości

class Critter(object):
"""Wirtualny pupil"""
def __init__(self, name):
print("Urodził się nowy zwierzak!")
self.__name = name

@property
def name(self):
return self.__name

@name.setter
def name(self, new_name):
if new_name == "":
print("Pusty łańcuch znaków nie może być imieniem zwierzaka.")
else:
self.__name = new_name
print("Zmiana imienia się powiodła.")

def talk(self):
print("\nCześć! Jestem", self.name)

# część główna
crit = Critter("Reksio")
crit.talk()

print("\nImię mojego zwierzaka to:", end= " ")
print(crit.name)

print("\nPróbuję zmienić imię mojego zwierzaka na Pucek...")
crit.name = "Pucek"
print("Imię mojego zwierzaka to:", end= " ")
print(crit.name)

print("\nPróbuję zmienić imię mojego zwierzaka na pusty łańcuch znaków...")
crit.name = ""
print("Imię mojego zwierzaka to:", end= " ")
print(crit.name)

input("\n\nAby zakończyć program, naciśnij klawisz Enter.")


Właściwości tworzymy poprzez wpisanie dekoratora @property a po nim metody umożliwiającej odczyt elementu w naszym przypadku jest to name(self). Możemy tworzyć również metody umożliwiające ograniczone możliwości modyfikacji. Taką metodę możecie Państwo zobaczyć w powyższym kodzie nazywa się ona name(self, new_name). Tą metodę również poprzedzamy dekoratorem, a mianowicie @name.setter

Dostęp do właściwości

Stosując właściwości można realizować dostęp do atrybutów. Dzięki stworzeniu właściwości name możemy uzyskać dostęp do atrybutu prywatnego: name. Teraz poniższy kod wyświetli informacje o imieniu naszego zwierzaka.

print(crit.name)

Zadania do samodzielnego wykonania na laboratoriach

* przeanalizuj kod i omów go na zajęciach:

# Opiekun zwierzaka
# Wirtualny pupil, którym należy się opiekować

class Critter(object):
"""Wirtualny pupil"""
def __init__(self, name, hunger = 0, boredom = 0):
self.name = name
self.hunger = hunger
self.boredom = boredom

def __pass_time(self):
self.hunger += 1
self.boredom += 1

@property
def mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness < 5:
m = "szczęśliwy"
elif 5 <= unhappiness <= 10:
m = "zadowolony"
elif 11 <= unhappiness <= 15:
m = "podenerwowany"
else:
m = "wściekły"
return m

def talk(self):
print("Nazywam się", self.name, "i jestem", self.mood, "teraz.\n")
self.__pass_time()

def eat(self, food = 4):
print("Mniam, mniam. Dziękuję.")
self.hunger -= food
if self.hunger < 0:
self.hunger = 0
self.__pass_time()

def play(self, fun = 4):
print("Hura!")
self.boredom -= fun
if self.boredom < 0:
self.boredom = 0
self.__pass_time()

def main():
crit_name = input("Jak chcesz nazwać swojego zwierzaka?: ")
crit = Critter(crit_name)

choice = None
while choice != "0":
print("""\n
Opiekun zwierzaka

0 - zakończ
1 - słuchaj swojego zwierzaka
2 - nakarm swojego zwierzaka
3 - pobaw się ze swoim zwierzakiem
""")

choice = input("Wybierasz: ")
print()

# wyjdź z pętli
if choice == "0":
print("Do widzenia.")

# słuchaj swojego zwierzaka
elif choice == "1":
crit.talk()

# nakarm swojego zwierzaka
elif choice == "2":
crit.eat()

# pobaw się ze swoim zwierzakiem
elif choice == "3":
crit.play()

# nieznany wybór
else:
print("\nNiestety,", choice, "nie jest prawidłowym wyborem.")

main()
input("\n\nAby zakończyć program, naciśnij klawisz Enter.")


* Ulepsz powyższy program umożliwiając opiekunowi ustawienie ilości pożywienia podawanego zwierzakowi i czasu poświęconego na zabawę z nim. Wartości te powinny wpływać na szybkość spadku poziomu głodu i nudy u zwierzaka.
* Napisz program symulujący telewizor, tworząc go jako obiekt. Użytkownik powinien mieć możliwość wprowadzenia numeru kanału, oraz regulacji głośności. Zaimplementuj mechanizm umożliwiający utrzymywanie numeru kanału i głośności we właściwych zakresach. Zakresy to: numer kanału od 1-20, głośność od 0-100

– Przykłady używane na laboratoriach

Przykłady pochodzą z książki
* Podstawową książką wykorzystywaną na laboratorium będzie: „Python dla każdego. Podstawy programowania Wydanie III”, autor Michael Dawson, Wydawnictwo Helion **(R)**

Zadanie domowe

**Wszystkie zadania domowe należy archiwizować ponieważ w dalszej części laboratoriów będziecie je Państwo rozbudowywać**
* Utwórz w programie opiekun zwierzaka mechanizm “tylnych drzwi”, który pokazuje dokładnie wartości atrybutów obiektu. Zrealizuj to poprzez wyświetlenie obiektu po wprowadzeniu przez użytkownika ukrytej wartości (nieopisanej w menu). **WSKAZÓWKA** dodaj specjalną metodę str do klasy critter (o tej metodzie mówiliśmy na poprzednich zajęciach).
* Python dla każdego. Podstawy programowania. – Michael Dawson – Helion **R** – Rozdział 9.