W razie problemów zapraszam na konsultacje.
Wszystko jest obiektem -?
a = 5
b = a
b += 2
print(a)
print(b)
a = [2, 3, 4]
b = a
print(a)
print(b)
a[1] = -3
print(a)
print(b)
b = [6, 7]
print(a)
print(b)
House
johnHouse
Konwencja
Kod nr 1:
class House:
pass
johnHouse = House()
Kod nr 2:
class House:
"""The class that describes houses."""
pass
d = House()
Kod nr 3:
class House:
"""The class that describes houses."""
area = 100
def get_price(self):
return 3000 * self.area
d = House()
print(d.get_price())
d2 = House()
d2.area = 123
print(d2.get_price())
Klasa – częściowa lub całkowita definicja dla obiektów. Definicja obejmuje dopuszczalny stan obiektów oraz ich zachowania. Obiekt, który został stworzony na podstawie danej klasy nazywany jest jej instancją. Klasy mogą być typami języka programowania - przykładowo, instancja klasy Owoc będzie mieć typ Owoc. Klasy posiadają zarówno interfejs, jak i strukturę. Interfejs opisuje, jak komunikować się z jej instancjami za pośrednictwem metod, zaś struktura definiuje sposób mapowania stanu obiektu na elementarne atrybuty.
Obiekt - jest to struktura zawierająca:
Źródło: Wikipedia.
Abstrakcja - polega na ukrywaniu lub pomijaniu mało istotnych informacji a skupieniu się na wydobyciu informacji, które są niezmienne i wspólne dla pewnej grupy obiektów.
Hermetyzacja lub inaczej mówiąc enkapsulacja polega na ukrywaniu nieistotnych informacji na temat obiektu w celu zminimalizowania efektów jego modyfikacji oraz na oddzieleniu tego co zawiera i co może zrobić obiekt od tego jak jest zbudowany i jak to robi.
Dziedziczenie pozwala rozszerzać możliwości klas poprzez implementacje osobnych klas rozszerzających. Dzięki dziedziczeniu możemy tworzyć nowe klasy w oparciu o już istniejące, bez potrzeby implementowania tych funkcjonalności, które zostały już zaimplementowane w klasach bazowych.
Polimorfizm pozwala traktować różnorodne dane w ten sam sposób, w zależności od kontekstu. W trakcie wykonywania programu automatycznie są znajdowane i interpretowane odpowiednie metody w zależności od tego jak chcemy traktować nasze dane.
Pola to inaczej zmienne w danej klasie.
Ćwiczenie. Stwórz klasę Point
z dwoma
polami x
i y
. Stwórz kilka obiektów w
zdefiniowanym typie.
Kod nr 1:
class Point:
x = 4
y = 2
p1 = Point()
p1.x = 3
p1.y = 7
p2 = Point()
Kod nr 2:
class Point:
pass
p1 = Point()
p1.x = 3
p1.y = 7
p2 = Point()
Ćwiczenie 2. Dla kodu nr 2 sprawdź czy możesz zostać się do pól/składowych obu obiektów.
Ćwiczenie 3. Stwórz klasę Book
, dodaj w
niej 5 dowolnych pól i poćwicz możliości z analogicznego do powyższych
ćwiczeń.
Czy możemy określić konkretny typ?
Tak, ale to są nowości, mogą być przedmiotem zmian i niebawem rozwijane (ang. type hinting).
Kod nr 3:
class Point:
x: int = 4
y: int = 2
p1 = Point()
p1.x = 3
p1.y = "ddd"
p2 = Point()
Ćwiczenia 4. Dla klasy Book
z
wcześniejszego ćwiczenia zmodyfikuj pola z określeniem typu.
Metody definiują zachowanie, umożliwiając im wykonywanie konkretnych zadań.
Czemu używa się określenie metody, a nie funkcje?
Funkcja – dla danych dwóch zbiorów \(X\) i \(Y\) przyporządkowanie każdemu elementowi zbioru \(X\) dokładnie jednego elementu zbioru \(Y\).
void
, czyli bez zbioru \(Y\)).Inaczej: metody to funkcje w klasach.
import math
class Point:
x = 4
y = 2
def reset(self):
self.x = 0
self.y = 0
def left(self, move):
self.x -= move
def move(self, mx, my):
self.x += mx
self.y += my
def dist(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
p1 = Point()
p1.reset()
print(p1.x, p1.y)
print(p1.dist())
p1.move(3, 4)
print(p1.x, p1.y)
print(p1.dist())
Ćwiczenie. Stwórz klasę Liczba
. Dodaj w
niej pole wartosc i przypisz mu wartość początkową 0. Stwórz metody o
nazwach Dodaj i Odejmij, każda z nich ma być z jednym parametrem typu
int, ich zadaniem jest odpowiednio powiększenie lub pomniejszenie pola
wartosc o podanych parametr. Przetestuj działanie funkcji.
import math
class Point:
x: int = 4
y: int = 2
def reset(self) -> None:
self.x = 0
self.y = 0
def left(self, move: int) -> None:
self.x -= move
def move(self, mx: int, my: int) -> None:
self.x += mx
self.y += my
def dist(self) -> float:
return math.sqrt(self.x ** 2 + self.y ** 2)
p1 = Point()
p1.reset()
print(p1.x, p1.y)
print(p1.dist())
p1.move(3, 4)
print(p1.x, p1.y)
print(p1.dist())
Ćwiczenie 2. Przerób klasę Liczba na wersję z typowaniem.
Spróbuj rozszerzyć klasę Point
o metodę której argument
będzie inny punkt.
import math
class Point:
x = 4
y = 2
def reset(self):
self.x = 0
self.y = 0
def dist(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
def dist2(self, other):
return math.sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
p1 = Point()
p1.move(-1, 1)
p2 = Point()
print(p1.dist())
print(p1.dist2(p2))
print(p1.dist2(p1))
import math
class Point:
x = 4
y = 2
def reset(self):
self.x = 0
self.y = 0
def dist(self, other=None):
if other is None:
return math.sqrt(self.x ** 2 + self.y ** 2)
else:
return math.sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
p1 = Point()
p1.move(-1, 1)
p2 = Point()
print(p1.dist())
print(p1.dist(p2))
print(p1.dist(p1))
Ćwiczenie 3. Do klasy Liczba dodaj funkcję “sumującą” bieżący obiekt z innym.