<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
	<id>http://brain.fuw.edu.pl/edu/index.php?action=history&amp;feed=atom&amp;title=TI%2FWst%C4%99p_do_programowania_obiektowego%2FCwiczenia</id>
	<title>TI/Wstęp do programowania obiektowego/Cwiczenia - Historia wersji</title>
	<link rel="self" type="application/atom+xml" href="http://brain.fuw.edu.pl/edu/index.php?action=history&amp;feed=atom&amp;title=TI%2FWst%C4%99p_do_programowania_obiektowego%2FCwiczenia"/>
	<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=TI/Wst%C4%99p_do_programowania_obiektowego/Cwiczenia&amp;action=history"/>
	<updated>2026-05-03T15:21:25Z</updated>
	<subtitle>Historia wersji tej strony wiki</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=TI/Wst%C4%99p_do_programowania_obiektowego/Cwiczenia&amp;diff=1817&amp;oldid=prev</id>
		<title>Jarekz: Utworzono nową stronę &quot;=Ćwiczenia =  == Implementacja prostej hierarchii klas == Zaimplementuj mini hierarchię klas zamodelowaną na poniższym obrazku. Pamiętaj, żeby przy dziedziczeniu i...&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=TI/Wst%C4%99p_do_programowania_obiektowego/Cwiczenia&amp;diff=1817&amp;oldid=prev"/>
		<updated>2015-05-23T10:36:23Z</updated>

		<summary type="html">&lt;p&gt;Utworzono nową stronę &amp;quot;=Ćwiczenia =  == Implementacja prostej hierarchii klas == Zaimplementuj mini hierarchię klas zamodelowaną na poniższym obrazku. Pamiętaj, żeby przy dziedziczeniu i...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nowa strona&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=Ćwiczenia =&lt;br /&gt;
&lt;br /&gt;
== Implementacja prostej hierarchii klas ==&lt;br /&gt;
Zaimplementuj mini hierarchię klas zamodelowaną na poniższym obrazku. Pamiętaj, żeby przy dziedziczeniu i przedefiniowywaniu metod korzystać z metody super -- wyjaśnij, czemu takie wyjście jest lepsze niż bezpośrednie odwoływanie się do metody z nadklasy?&lt;br /&gt;
Pamiętaj o tym, aby odpowiednie metody atrybuty implementować jako metody / atrybuty odpowiednio klasy / obiektu.&lt;br /&gt;
Sprawdź, czy zmiana wartości atrybutu klasowego w podklasie jest widoczna w nadklasie, i na odwrót.&lt;br /&gt;
(Podkreślenie oznacza atrybut/metodę klasy, bez podkreślenia -- obiektu)&lt;br /&gt;
&lt;br /&gt;
[[Image:obiekty_diagram.png| 400px]]&lt;br /&gt;
&lt;br /&gt;
* Rozszerz którąś z klas o metodę __call__(), spróbuj wymyśleć &amp;quot;przydatny&amp;quot; sposób jej działania i je zaprezentuj.&lt;br /&gt;
* Rozszerz klasę A o metodę __dell__(), która będzie wypisywać napis &amp;quot;umieram&amp;quot;. &lt;br /&gt;
Co i dlaczego się stanie, gdy zrobisz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
a = A() &lt;br /&gt;
# z dokładnością do tego, że być może Twoja implementacja &lt;br /&gt;
# potrzebuje parametrów w konstruktorze&lt;br /&gt;
b = a&lt;br /&gt;
c = a&lt;br /&gt;
&lt;br /&gt;
del a&lt;br /&gt;
del b&lt;br /&gt;
del c&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
A kto i dlaczego krzyczy &amp;quot;umieram&amp;quot; w następującej sytuacji:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
a = A()&lt;br /&gt;
b = A()&lt;br /&gt;
b = a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Przykładziki na różne zagadnienia ==&lt;br /&gt;
&lt;br /&gt;
=== Atrybuty vs metody ===&lt;br /&gt;
Niech definicja klasy będzie następująca:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class SztucznyPrzyklad:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.atrybut1 = None&lt;br /&gt;
&lt;br /&gt;
    def metoda1(self):&lt;br /&gt;
        return &amp;quot;jestem metoda&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co i dlaczego będzie na zmiennej sp:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sp = SztucznyPrzyklad&lt;br /&gt;
#podpowiedz:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(sp)&lt;br /&gt;
&amp;lt;type 'classobj'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A teraz?:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sp = SztucznyPrzyklad()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; sp = SztucznyPrzyklad()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(sp)&lt;br /&gt;
&amp;lt;type 'instance'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co będzie na m1?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; m1 = sp.metoda1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(m1)&lt;br /&gt;
&amp;lt;type 'instancemethod'&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; m1 = sp.metoda1()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(m1)&lt;br /&gt;
&amp;lt;type 'str'&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A jak się ma sprawa z atrybutami?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; a1 = sp.atrybut1()&lt;br /&gt;
&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;&amp;lt;pyshell#23&amp;gt;&amp;quot;, line 1, in &amp;lt;module&amp;gt;&lt;br /&gt;
    a1 = sp.atrybut1()&lt;br /&gt;
TypeError: 'NoneType' object is not callable&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; a1 = sp.atrybut1&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; type(a1)&lt;br /&gt;
&amp;lt;type 'NoneType'&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rozszerzmy definicję z przykładu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class SztucznyPrzyklad:&lt;br /&gt;
    def __init__(self, parametr1, parametr2):&lt;br /&gt;
        self.atrybut1 = parametr1&lt;br /&gt;
        self.atrybut2 = parametr2&lt;br /&gt;
&lt;br /&gt;
    def metoda1(self):&lt;br /&gt;
        return &amp;quot;jestem metoda&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ff = 5&lt;br /&gt;
&lt;br /&gt;
def f():&lt;br /&gt;
    return 10&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że w takiej sytuacji:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
sp = SztucznyPrzyklad(f)&lt;br /&gt;
a = sp.atrybut1()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;wywołanie atrybutu&amp;quot; jest poprawne, ponieważ atrybut jest funkcją. Naley jednak to robić świadomie, i uważać na to, czy chcieliśmy się odwołać do obiektu funkcja, czy też do wyniku działania funkcji.&lt;br /&gt;
&lt;br /&gt;
Poniższe odwołanie jest wciąż poprawne, tylko zwraca nam obiekt typu funkcja&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a = sp.atrybut1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Metody obiektów i klasowe ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class Test(object):&lt;br /&gt;
  def method_one(self):&lt;br /&gt;
    print &amp;quot;Called method_one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  def method_two():&lt;br /&gt;
    print &amp;quot;Called method_two&amp;quot;&lt;br /&gt;
&lt;br /&gt;
a_test = Test()&lt;br /&gt;
a_test.method_one()&lt;br /&gt;
a_test.method_two()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wyjaśnij, czemu w powyższym przykładzie nie działa wywołanie a_test.method_two().&lt;br /&gt;
Jak można to poprawić?&lt;br /&gt;
&lt;br /&gt;
== Najprostszy dekorator ==&lt;br /&gt;
Niech będzie dana zdefiniwana poza klasą funkcja f:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def f(g):&lt;br /&gt;
  g.pole = True&lt;br /&gt;
  return g&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Do ciała klasy A z pierwszego ćwiczenia dodaj następujący fragment:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
  f(m1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zauważ, że w tak zdefiniowanej klasie A, jej metoda m1 ma atrybut pole, ustawiony na True.&lt;br /&gt;
Spróbuj osiągnąć ten sam efekt &lt;br /&gt;
* zamiast wywołania f(m1) używając konstrukcji z &amp;quot;@&amp;quot;&lt;br /&gt;
* zamiast wywołania f(m1) tworząc klasę f robiącą w metodzie __call__ to samo i używając konstrukcji z &amp;quot;@&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Wymyśl przydatne zastosowanie takiej techniki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Szukanie błędów ==&lt;br /&gt;
Znajdź, wyjaśnij i popraw błędy w poniższych kawałkach kodu. Podaj treść komunikatów o błędach, które wyświetla python -- wyjaśnij tę treść.&lt;br /&gt;
=== ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class DecoratorTest:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        pass&lt;br /&gt;
    def __call__(self, f):&lt;br /&gt;
        f.pole = 0&lt;br /&gt;
        return f()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@DecoratorTest&lt;br /&gt;
def f():&lt;br /&gt;
    return 42&lt;br /&gt;
f()&lt;br /&gt;
print f.pole&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class logged(object):&lt;br /&gt;
    def __init__(self, funkcja):&lt;br /&gt;
        self.funkcja = funkcja&lt;br /&gt;
    def __call__(self, *args, **kwargs):&lt;br /&gt;
        print &amp;quot;wywoanie&amp;quot;, self.funkcja.__name__&lt;br /&gt;
        x = self.funkcja(*args, **kwargs)&lt;br /&gt;
        print self.funkcja.__name__, &amp;quot;zwrcia&amp;quot;, x&lt;br /&gt;
        return x&lt;br /&gt;
@logged()&lt;br /&gt;
def f():&lt;br /&gt;
    return g() + g()&lt;br /&gt;
@logged()&lt;br /&gt;
def g():&lt;br /&gt;
    return 1&lt;br /&gt;
f()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jarekz</name></author>
		
	</entry>
</feed>