Dlaczego programowanie obiektowe¶
Po co stosować klasy? Czy nie wystaczyły by zmienne i funkcje? Programy, które powstają na początku nauki programowania obiektowego są najczęściej dłuższe i bardziej skomplikowane niż analogiczny program złożony w funkcji. Programy obiektowe mają jednak pewne ważne zalety
Kapsułkowanie¶
Poniższy kod to implementacja prostego generatora liczb losowych.
Z matematycznego punktu widzenia, generator taki to dość prosta funkcja wyrażona wzorem: \(x_i = ( a x_{i-1} + c ) mod m\), gdzie
\(a, c\) oraz \(m\) to pewne stałe a \(x_i\) oraz \(x_{i-1}\) to aktualna i poprzednia wartość losowa.
Zaimplementowanie tej funkcji wymaga przechowywania wartości z poprzedniego wywołania. Stosując klasę, możemy wygodnie przechowywać
\(x_{i-1}\) jako pole, podobnie zresztą jak stałe \(a, c, m\) (które jak widać nie dość, że są prywatne, to użytkownik nie może ich zmienić - brak funkcji set())
1class Rnd :
2
3 def __init__(self, start = 1) :
4 self.__a = 8121 # Paramers from Wikipedia, random0 set
5 self.__c = 28411
6 self.__m = 134456
7 self.start = start
8
9 def eval(self) :
10 self.start = (self.__a * self.start + self.__c) % self.__m
11 return self.start
12
13 def rand_max(self) : return self.__m - 1
14
15if __name__ == "__main__" :
16 rnd = Rnd()
17 for i in range(10) : print(rnd.eval())
Kolejny przykład, kiedy kapsułkowanie okazuje się być bardzo przydatne, to sortowanie obiektów, np listy punktów wg odległości od zadanego położenia.
W trakcie sortowania wielokrotnie wykonywane jest przestawienie miejscami elementów. Położenia x, y można trzymać w oddzielnych tablicach (listach), wtedy:
1# Współrzędne trzymane w listach
2x, y, z = [rand() for i in range(10)], [rand() for i in range(10)], [rand() for i in range(10)]
3# zamienia wektory pod indeksami i oraz j
4tmp = x[i]
5x[i] = x[j]
6x[j] = tmp
7tmp = y[i]
8y[i] = y[j]
9y[j] = tmp
10tmp = z[i]
11z[i] = z[j]
12z[j] = tmp
a można zamieniać całe obiekty:
1# Lista wektorów
2v = [ Vec3(rand(),rand(),rand()) for i in range(10) ]
3# zamienia wektory pod indeksami i oraz j
4tmp = v[i]
5v[i] = v[j]
6v[j] = tmp
W Pythonie można osiągnąć to jeszcze prościej:
1# Lista wektorów
2v = [ Vec3(rand(),rand(),rand()) for i in range(10) ]
3# zamienia wektory pod indeksami i oraz j
4v[i], v[j] = v[j], v[i]
W praktyce oczywiście wykorzytujemy biblioteczną funkcję sort lub lista.sorted(), która dokonuje takich przestawień.