Klasy - dziedziczenie
Stronę tą wyświetlono już: 3986 razy
Na stronie Programowanie → Podstawy Pythona → Klasy omawiałem podstawy dotyczące tworzenia klas w Pythonie, nadeszła stosowna ku temu pora, aby zacząć omawiać sam mechanizm dziedziczenia w Pythonie. Zanim jednak uczynię to z najdzikszą rozkoszą, warto poskładać do kupy utworzony na wcześniej przeze mnie wspomnianej stronie kod dwóch klas tam utworzonych:
- class Matrix_tr:
- def __init__(self, m11 = 1, m12 = 0, m21 = 0, m22 = 1, dx = 0, dy = 0, alpha = None):
- if alpha is None: # if alpha angle is set on None value
- self.m11 = m11
- self.m12 = m12
- self.m21 = m21
- self.m22 = m22
- else: # in other case calculate m11 - m22 using alpha angle
- self.m11 = mt.cos(alpha)
- self.m12 = -mt.sin(alpha)
- self.m21 = - self.m12 # this should be sin of angle alpha
- self.m22 = self.m11 # this should be cos of angle alpha
- self.dx = dx # this is an offset for x
- self.dy = dy # this is an offset for y
- def __mul__(self, other): # multiplication operator (*)
- if isinstance(other, Point2D): # for object of Point2D class
- return Point2D(other.x * self.m11 + other.y * self.m12 + self.dx, other.x * self.m21 + other.y * self.m22 + self.dy)
- if isinstance(other, matrix_tr): # for object of matrix_tr class
- return matrix_tr(self.m11 * other.m11 + self.m12 * other.m21, self.m11 * other.m12 + self.m12 * other.m22, self.m21 * other.m11 + self.m22 * other.m21, self.m21 * other.m12 + self.m22 * other.m22, self.m11 * other.dx + self.m12 * other.dy + self.dx, self.m21 * other.dx + self.m22 * other.dy + self.dy)
- def __str__(self):
- return "| M11 = {m.m11:+{l}.5f} M12 = {m.m12:{l}.5f} dx = {m.dx:+{l}.5f} |\n| M21 = {m.m21:+{l}.5f} M22 = {m.m22:+{l}.5f} dy = {m.dy:+{l}.5f} |\n| M31 = {m31:+{l}.5f} M32 = {m32:+{l}.5f} {m33:+{l}.5f} |".format(m = self, l = 10, m31 = 0, m32 = 0, m33 = 1)
- class Point2D:
- tr = Matrix_tr()
- def __init__(self, x = None, y = None):
- self.x = float(input("Podaj współrzędną x: ")) if (x is None) else x
- self.y = float(input("Podaj współrzędną y: ")) if (y is None) else y
- def __del__(self):
- pass
- def __int__(self):
- return int((self.x * self.x + self.y * self.y) ** 0.5)
- def __float__(self):
- return (self.x * self.x + self.y * self.y) ** 0.5
- def __str__(self):
- return "Point2D(x={x}, y={y})".format(x = self.x, y = self.y)
- def __eq__(self, other):
- if isinstance(other, Point2D):
- return True if other.x == self.x and other.y == self.y else False
- else:
- return True if (float(self) == other) else False
- def __ne__(self, other):
- return not (self == other)
- def __lt__(self, other):
- return float(self) < float(other)
- def __gt__(self, other):
- return float(self) > float(other)
- def __le__(self, other):
- return not (self > other)
- def __gt__(self, other):
- return not (self < other)
- def __add__(self, other):
- if isinstance(other, Point2D):
- return Point2D(self.x + other.x, self.y + other.y)
- else:
- return Point2D(self.x + float(other), self.y + float(other))
- def __sub__(self, other):
- if isinstance(other, Point2D):
- return Point2D(self.x - other.x, self.y - other.y)
- else:
- return Point2D(self.x - float(other), self.y - float(other))
- def __mul__(self, other):
- if isinstance(other, Point2D):
- return self.x * other.x + self.y * other.y
- else:
- return Point2D(self.x * float(other), self.y * float(other))
- def __radd__(self, other):
- if isinstance(other, Point2D):
- return Point2D(self.x + other.x, self.y + other.y)
- else:
- return Point2D(self.x + float(other), self.y + float(other))
- def __rsub__(self, other):
- if isinstance(other, Point2D):
- return Point2D(other.x - self.x, other.y - self.y)
- else:
- return Point2D(float(other) - self.x, float(other) - self.y)
- def __rmul__(self, other):
- if isinstance(other, Point2D):
- return self.x * other.x + self.y * other.y
- else:
- return Point2D(self.x * float(other), self.y * float(other))
- def __iadd__(self, other):
- if isinstance(other, Point2D):
- self.x += other.x
- self.y += other.y
- else:
- self.x += float(other)
- self.y += float(other)
- return self
- def __isub__(self, other):
- if isinstance(other, Point2D):
- self.x -= other.x
- self.y -= other.y
- else:
- self.x -= float(other)
- self.y -= float(other)
- return self
- def __imul__(self, other):
- self.x *= float(other)
- self.y *= float(other)
- return self
- def __pos__(self):
- return Point2D(self.x, self.y)
- def __neg__(self):
- return Point2D(- self.x, - self.y)
- def __abs__(self):
- return Point2D(abs(self.x), abs(self.y))
- # Metody klasy
- def det(self, pt): # calculate determinant of two vectors
- if isinstance(pt, Point2D):
- return self.x * pt.y - pt.x * self.y
- elif instance(pt, tuple):
- return self.x * pt[1] - pt[0] * self.y
- def draw(self):
- print(Point2D.tr * self)
Mechanizm dziedziczenia oraz wywoływanie konstruktora klasy bazowej
Utwórzmy sobie klasę o jakże wymownej nazwie Point3D. Ta klasa będzie dziedziczyła po klasie Point2D w sposób następujący:
- class Point3D(Point2D):
- def __init__(self, x = None, y = None, z = None):
- Point2D.__init__(self, x, y) # constructor of base class
- self.z = float(input("Podaj współrzędną z: ")) if z is None else z
Można oczywiście dziedziczyć po wielu obiektach, wystarczy zaraz za nazwą klasy w nawiasie wypisać nazwy klas dziedziczonych oddzielone przecinkiem.
Wywoływanie metod klasy bazowej
Utwórzmy sobie taką oto metodę wewnętrzną klasy Point3D:
- def draw(self):
- Point2D.draw(self)
- print(self)
Jeżeli teraz napiszę taki oto kod:
- p3d = Point3D(1,2,3)
- p3d.draw()
- Point2D.draw(p3d)
W takim przypadku wyświetli się coś takiego:
Point2D(x=1, y=2) Point3D(x=1, y=2, z=3) Point2D(x=1, y=2)

Tytuł:
Python w zadaniach. Programowanie dla młodzieży. Poziom podstawowy
Autor:
Urszula Wiejak, Adrian Wojciechowski

Tytuł:
Python i praca z danymi. Przetwarzanie, analiza, modelowanie i wizualizacja. Wydanie III
Autor:
Avinash Navlani, Armando Fandango, Ivan Idris

Tytuł:
Black Hat Python. Język Python dla hakerów i pentesterów. Wydanie II
Autor:
Justin Seitz, Tim Arnold

Tytuł:
Python z życia wzięty. Rozwiązywanie problemów za pomocą kilku linii kodu
Autor:
Lee Vaughan

Tytuł:
Python dla nastolatków. Projekty graficzne z Python Turtle
Autor:
Krzysztof Łos

Tytuł:
Python i Excel. Nowoczesne środowisko do automatyzacji i analizy danych
Autor:
Felix Zumstein

Tytuł:
Python dla testera
Autor:
Piotr Wróblewski

Tytuł:
Python 3. Projekty dla początkujących i pasjonatów
Autor:
Adam Jurkiewicz

Tytuł:
Machine learning, Python i data science. Wprowadzenie
Autor:
Andreas C. Müller, Sarah Guido

Tytuł:
Python na maturze. Rozwiązania i analiza wybranych zadań programistycznych
Autor:
Roland Zimek