<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>obiekty - Kama Kaczmarek</title>
	<atom:link href="https://kamakaczmarek.net/tag/obiekty/feed/" rel="self" type="application/rss+xml" />
	<link>https://kamakaczmarek.net/tag/obiekty/</link>
	<description>Strona z materiałami dla uczniów i nauczycieli</description>
	<lastBuildDate>Fri, 10 Apr 2026 07:45:13 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>13. Python &#8211; obiektowo</title>
		<link>https://kamakaczmarek.net/13-python-obiektowo/</link>
		
		<dc:creator><![CDATA[Kama]]></dc:creator>
		<pubDate>Mon, 08 Jan 2024 12:50:35 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[obiekty]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">https://kamakaczmarek.net/?p=3640</guid>

					<description><![CDATA[<p>Programowanie obiektowe – OOP (object-oriented programming) – pozwala na przedstawienie rzeczywistości i relacji w niej zachodzących za pomocą obiektów. Dokumentacja. Po co nam programowanie obiektowe? Programowanie obiektowe (ang. Object-Oriented Programming, OOP) wprowadza strukturę i organizację do kodu, co ułatwia jego tworzenie, rozwijanie i utrzymanie. Poniżej znajdziesz wyjaśnienie, po co stosować programowanie obiektowe, z przykładami jego [&#8230;]</p>
<p>Artykuł <a href="https://kamakaczmarek.net/13-python-obiektowo/">13. Python &#8211; obiektowo</a> pochodzi z serwisu <a href="https://kamakaczmarek.net">Kama Kaczmarek</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<section class="entry-content ">
<p>Programowanie obiektowe – OOP (object-oriented programming) – pozwala na przedstawienie rzeczywistości i relacji w niej zachodzących za pomocą obiektów. <a href="https://docs.python.org/3/tutorial/classes.html" target="_blank" rel="noopener">Dokumentacja.</a></p>
<h2>Po co nam programowanie obiektowe?</h2>
<p>Programowanie obiektowe (ang. <em>Object-Oriented Programming</em>, OOP) wprowadza strukturę i organizację do kodu, co ułatwia jego tworzenie, rozwijanie i utrzymanie. Poniżej znajdziesz wyjaśnienie, <strong>po co stosować programowanie obiektowe</strong>, z przykładami jego głównych zalet:</p>
<hr />
<h3>1. <strong>Organizacja i modularność</strong></h3>
<ul>
<li>OOP pozwala dzielić kod na mniejsze, logiczne fragmenty (klasy), które odpowiadają rzeczywistym obiektom lub pojęciom.</li>
<li>Dzięki temu kod jest bardziej przejrzysty i łatwiejszy w zarządzaniu.</li>
</ul>
<p><strong>Przykład</strong>: W grze komputerowej można mieć klasy <code class="prettyprint lang-sql" style="font-size: 0.85em;">Gracz</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">Przeciwnik</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">Broń</code>. Każda z nich zawiera tylko dane i funkcje związane z tym obiektem.</p>
<hr />
<h3>2. <strong>Reużywalność kodu</strong></h3>
<ul>
<li>Możesz tworzyć klasy i wykorzystywać je wielokrotnie w różnych projektach lub częściach programu.</li>
<li><strong>Dziedziczenie</strong> umożliwia tworzenie nowych klas na podstawie istniejących, dzięki czemu kod jest bardziej elastyczny.</li>
</ul>
<p><strong>Przykład</strong>: Klasa <code class="prettyprint lang-sql" style="font-size: 0.85em;">Pojazd</code> może mieć podklasy <code class="prettyprint lang-sql" style="font-size: 0.85em;">Samochód</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">Motocykl</code>, które dziedziczą podstawowe cechy pojazdu (np. prędkość, masa), ale dodają swoje specyficzne funkcje.</p>
<hr />
<h3>3. <strong>Łatwiejsze rozwijanie aplikacji</strong></h3>
<ul>
<li>W OOP zmiany są łatwiejsze do wprowadzenia, ponieważ każda klasa działa jako oddzielny moduł.</li>
<li>Jeśli potrzebujesz zmienić zachowanie jednego elementu, modyfikujesz tylko odpowiednią klasę, bez wpływu na inne części programu.</li>
</ul>
<p><strong>Przykład</strong>: Dodanie nowej broni w grze wymaga jedynie stworzenia nowej klasy na podstawie istniejącego schematu, np. <code class="prettyprint lang-sql" style="font-size: 0.85em;">Broń</code>.</p>
<hr />
<h3>4. <strong>Ukrywanie szczegółów (enkapsulacja)</strong></h3>
<ul>
<li>OOP pozwala ukrywać szczegóły implementacji, dzięki czemu kod jest bardziej bezpieczny i trudniejszy do przypadkowego uszkodzenia.</li>
<li>Dane w klasach są chronione, a dostęp do nich odbywa się przez ściśle określone metody.</li>
</ul>
<p><strong>Przykład</strong>: W klasie <code class="prettyprint lang-sql" style="font-size: 0.85em;">KontoBankowe</code> saldo konta jest ukryte, a użytkownik może je zmieniać tylko za pomocą metod <code class="prettyprint lang-sql" style="font-size: 0.85em;">wpłać()</code> i <code class="prettyprint lang-sql" style="font-size: 0.85em;">wypłać()</code>.</p>
<hr />
<h3>5. <strong>Naturalne odwzorowanie rzeczywistości</strong></h3>
<ul>
<li>OOP naśladuje sposób, w jaki myślimy o świecie, opierając się na obiektach, ich cechach i zachowaniach.</li>
<li>Dzięki temu kod staje się bardziej intuicyjny i łatwiejszy do zrozumienia.</li>
</ul>
<p><strong>Przykład</strong>: Klasa <code class="prettyprint lang-sql" style="font-size: 0.85em;">Kot</code> ma cechy takie jak kolor futra (atrybuty) i umiejętności jak miauczenie (metody).</p>
<hr />
<h3>6. <strong>Łatwość debugowania i testowania</strong></h3>
<ul>
<li>Dzięki temu, że klasy są niezależne, błędy w jednym obiekcie nie wpływają na inne.</li>
<li>Testowanie poszczególnych modułów (klas) jest prostsze niż testowanie całości kodu.</li>
</ul>
<hr />
<h3>7. <strong>Polimorfizm – elastyczność w działaniu</strong></h3>
<ul>
<li>Polimorfizm umożliwia różnym obiektom używanie tej samej metody, ale w różny sposób.</li>
<li>Pozwala to na pisanie bardziej uniwersalnego i elastycznego kodu.</li>
</ul>
<p><strong>Przykład</strong>: Metoda <code class="prettyprint lang-sql" style="font-size: 0.85em;">atakuj()</code> może działać inaczej w klasie <code class="prettyprint lang-sql" style="font-size: 0.85em;">Rycerz</code> i <code class="prettyprint lang-sql" style="font-size: 0.85em;">Mag</code>, mimo że jest wywoływana w ten sam sposób.</p>
<hr />
<h3>8. <strong>Ułatwienie pracy zespołowej</strong></h3>
<ul>
<li>W dużych projektach, podział kodu na klasy ułatwia współpracę, ponieważ każdy programista może pracować nad innymi obiektami, nie wchodząc sobie w drogę.</li>
</ul>
<hr />
<h3>Podsumowanie</h3>
<p>Programowanie obiektowe jest użyteczne, gdy:</p>
<ul>
<li>Tworzysz duże, złożone systemy.</li>
<li>Chcesz pisać kod, który łatwo rozwijać, utrzymywać i testować.</li>
<li>Potrzebujesz odzwierciedlić rzeczywiste pojęcia lub obiekty w swoim kodzie.</li>
</ul>
<p>Jeśli jednak tworzysz mały, prosty skrypt, nie zawsze konieczne jest stosowanie OOP – wtedy wystarczą inne podejścia, jak programowanie proceduralne.</p>
<h2>Klasa i obiekt</h2>
<p>Kiedy mówimy o <strong>klasie </strong>musimy wyobrazić ją sobie jak ogólny zarys/opis jakiegoś obiektu, zbiór cech wspólnych dla np. człowieka. Gdybyśmy mieli klasę człowiek moglibyśmy określić ogólne cechy jakie definiują ludzi, czyli np. to że śpi, że ma głos, oczy, włosy, ręce, nogi itd.</p>
<p><strong>Obiekt </strong>jest instancją danej klasy, czyli konkretnym człowiekiem np. Janem Kowalskim, który ma brązowe włosy, jest typem „skowronka” i ma niebieskie oczy. Te cechy nie są bezpośrednio związane z klasą, a z obiektem (instancją/wystąpieniem klasy).</p>
<p>Można powiedzieć, że Jan Kowalski jest zmienną typu klasy, czyli obiektem typu człowiek.</p>
<p>Przykład utworzenia klasy:</p>
<pre class="prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="pun">#</span><span class="com">tworzymy klasę<br />class Test: #nazwa klasy wielką literą bez nawiasów<br />    # własności, czyli zmienne<br />    to_jest_wlasnosc = "jestem własnością klasy Test"<br />    lista_test = ["kot", "pies", "królik"]<br />    dict_test = {"k1": "v1", "k2": "v2"}<br />    __prywatna = "nie ma do mnie dostępu z zewnątrz"<br /><br />#tworzymy nowy obiekt na bazie klasy<br />nowy_obiekt = Test()<br /><br /># wyświetlamy własności klasy, w Python nie ma modyfikatorów dostępu jeżeli chcemy zrobić wartość prywatną stawiamy 2 x podkreślnik np __nazwa<br /><br />print(nowy_obiekt.to_jest_wlasnosc)<br />print(nowy_obiekt.lista_test)<br />print(nowy_obiekt.lista_test[2])<br />print(nowy_obiekt.dict_test)<br />print(nowy_obiekt.dict_test["k2"])<br /># print(nowy_obiekt._prywatna) #to se ne da</span></code></pre>
<div>
<div>&nbsp;&nbsp;</div>
</div>
<h2>Metody</h2>
<p>Klasa może definiować metody, czyli nic innego jak funkcje z podejścia proceduralnego. Kiedy tworzymy obiekt nadajemy mu dostęp do metod danej klasy.</p>
<p>Trochę praktyki:</p>
<pre class="prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="com">#tworzymy klasę<br />class Test:<br />    # własności, czyli zmienne<br />    to_jest_wlasnosc = "jestem własnością klasy Test"<br />    lista_test = ["kot", "pies", "królik"]<br />    dict_test = {"k1": "v1", "k2": "v2"}<br />    __prywatna = "nie ma do mnie dostępu z zewnątrz"<br /><br />    # metody, czyli funkcje&nbsp; &nbsp; <br />    def to_jest_metoda(self,): &nbsp;# pierwszy parametr to zawsze self - to <strong>referencja do instancji obiektu</strong> <br />                                (tak jak $this-&gt; w PHP)&nbsp; <br />        print(self.to_jest_wlasnosc) <br /> &nbsp; <br />    def wyswietlam_private(self):&nbsp; &nbsp; &nbsp; &nbsp; <br />        print(self.__prywatna + ", ale ja działam w środku")&nbsp; &nbsp; <br /><br />    # @<code class="prettyprint lang-sql" style="font-size: 0.85em;">property </code>to dekorator, który mówi - nie traktuj mnie jak metodę, traktuj mnie jak własność. Dekorator @<code class="prettyprint lang-sql" style="font-size: 0.85em;">property</code> pozwala traktować metodę jak atrybut, dzięki czemu możemy kontrolować dostęp do danych zachowując prostą składnię: <code class="prettyprint lang-sql" style="font-size: 0.85em;">obiekt.get_kot</code> zamiast <code class="prettyprint lang-sql" style="font-size: 0.85em;">obiekt.get_kot()</code><br />@property <br />def get_kot(self): &nbsp;# metoda zwróci nam własność&nbsp; &nbsp; &nbsp; &nbsp; <br />return self.lista_test[0]&nbsp; &nbsp; <br /><br /># metoda z parametrami&nbsp; &nbsp; <br />def add_test_to_list(self, name):&nbsp; &nbsp; &nbsp; &nbsp; <br />self.lista_test.append(name)&nbsp; &nbsp; &nbsp; &nbsp; <br />return self.lista_test&nbsp; &nbsp; <br /><br />def test(self):&nbsp; &nbsp; &nbsp; &nbsp; <br />pass <br /><br />#tworzymy nowy obiekt na bazie klasy<br />nowy_obiekt = Test()<br /><br /># wyświetlamy własności klasy, w Python nie ma modyfikatorów dostępu jeżeli chcemy zrobić wartość prywatną stawiamy 2 x podłogę np __nazwa<br /><br />print(nowy_obiekt.to_jest_wlasnosc)<br /><br />print(nowy_obiekt.lista_test)<br />print(nowy_obiekt.lista_test[2])<br /><br />print(nowy_obiekt.dict_test)<br />print(nowy_obiekt.dict_test["k2"])<br /><br /># print(nowy_obiekt.__prywatna) #to spowoduje błąd AttributeError<br /><br />nowy_obiekt.to_jest_metoda()<br />nowy_obiekt.wyswietlam_private() &nbsp;# tak już możemy wyświetlić coś prywatnego<br />kot = nowy_obiekt.get_kot &nbsp;# nie podaję() bo otrzymam wartość<br />print("Nie jestem właścicielką", kot)<br />nowy_obiekt.add_test_to_list("rybki") &nbsp;#dodajemy zwierzę do listy<br />print(nowy_obiekt.lista_test)</span></code></pre>
</section>



<section></section>



<h2 class="wp-block-heading prettyprint">Metody magiczne &#8211; czyli konstruktor, destruktor i reszta &#8211; dunder methods</h2>



<p>Metody magiczne to nic innego jak funkcje, które należą do danej klasy. Charakteryzują się zapisem, który rozpoczyna się od dwóch znaków podkreślnika i kończy dwoma znakami podkreślnika np. __nazwa__</p>



<p class="has-text-align-center">dunder = <strong>d</strong>ouble <strong>under</strong>scores</p>



<p>&nbsp;<code class="prettyprint lang-sql" style="font-size: 0.85em;"><strong>__new__</strong>(cls, ...)</code></p>



<p>metoda jest wywoływana podczas tworzenia nowych obiektów(tworzenia nowej instancji klasy) jako pierwsza, przed inną z magicznych metod czyli __init__ i jej zadaniem jest stworzenie i zwrócenie nowej instancji danej klasy, która to zaraz potem jest przekazywana do metody __init__ jako pierwszy argument (self).</p>



<h4 class="wp-block-heading"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><strong>__init__</strong>(self, ...)</code></h4>



<p>najbardziej znana z magicznych metod, nazywana jest <strong>konstruktorem</strong>. Jej zadaniem jest inicjalizacja obiektu z pomocą argumentów przekazanych przy wywołaniu klasy. Uruchamiana jest automatycznie podczas tworzenia nowego obiektu.</p>



<h4 class="wp-block-heading"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><strong>__del__</strong>(self)</code></h4>



<p>wywoływana jest, gdy obiekt kończy swój cykl życia i za zadanie ma zrobienie porządku po nim. Nazywana jest <strong>destruktorem</strong>.</p>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><strong>__str__</strong></code><strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">(self)</code><code class="prettyprint lang-sql" style="font-size: 0.85em;"></code> i <code class="prettyprint lang-sql" style="font-size: 0.85em;">__repr</code><code class="prettyprint lang-sql" style="font-size: 0.85em;">__</code><code class="prettyprint lang-sql" style="font-size: 0.85em;">(self)</code></strong></h3>



<p class="prettyprint"><strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">__str__</code></strong> &#8211; zwraca &#8222;ładną&#8221;, czytelną dla użytkownika reprezentację obiektu<br /><strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">__repr__</code></strong> &#8211; zwraca techniczną reprezentację obiektu, idealna do debugowania</p>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Ksiazka:<br /><span class="token">    def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> tytul<span class="token">,</span> autor<span class="token">,</span> rok<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>tytul <span class="token">=</span> tytul
        self<span class="token">.</span>autor <span class="token">=</span> autor
        self<span class="token">.</span>rok <span class="token">=</span> rok
    
    <span class="token">def</span> <span class="token">__str__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token"># To zobaczy użytkownik</span>
        <span class="token">return</span> <span class="token string-interpolation">f'"</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">tytul</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">" - </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">autor</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> (</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">rok</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">)'</span>
    
    <span class="token">def</span> <span class="token">__repr__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token"># To zobaczy programista podczas debugowania</span>
        <span class="token">return</span> <span class="token string-interpolation">f'Ksiazka(tytul="</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">tytul</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">", autor="</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">autor</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">", rok=</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">rok</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">)'</span>


ksiazka <span class="token">=</span> Ksiazka<span class="token">(</span><span class="token">"Wiedźmin"</span><span class="token">,</span> <span class="token">"Andrzej Sapkowski"</span><span class="token">,</span> <span class="token">1990</span><span class="token">)</span>

<span class="token">print</span><span class="token">(</span><span class="token">str</span><span class="token">(</span>ksiazka<span class="token">)</span><span class="token">)</span>   <span class="token"># "Wiedźmin" - Andrzej Sapkowski (1990)</span>
<span class="token">print</span><span class="token">(</span><span class="token">repr</span><span class="token">(</span>ksiazka<span class="token">)</span><span class="token">)</span>  <span class="token"># Ksiazka(tytul="Wiedźmin", autor="Andrzej Sapkowski", rok=1990)</span>
<span class="token">print</span><span class="token">(</span>ksiazka<span class="token">)</span>   </code></pre>
</div>
</div>



<h3 class="wp-block-heading">&nbsp;<strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">__eq__</code></strong> i inne operatory porównania</h3>



<p class="whitespace-normal break-words">Pozwalają porównywać obiekty za pomocą operatorów <code class="prettyprint lang-sql" style="font-size: 0.85em;">==</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">&lt;</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">&gt;</code> itp.</p>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token">class</span> <span class="token">Osoba</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> imie<span class="token">,</span> wiek<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>imie <span class="token">=</span> imie
        self<span class="token">.</span>wiek <span class="token">=</span> wiek
    
    <span class="token">def</span> <span class="token">__eq__</span><span class="token">(</span>self<span class="token">,</span> other<span class="token">)</span><span class="token">:</span>
        <span class="token"># Definiuje zachowanie operatora ==</span>
        <span class="token">if</span> <span class="token">isinstance</span><span class="token">(</span>other<span class="token">,</span> Osoba<span class="token">)</span><span class="token">:</span>
            <span class="token">return</span> self<span class="token">.</span>wiek <span class="token">==</span> other<span class="token">.</span>wiek
        <span class="token">return</span> <span class="token">False</span>
    
    <span class="token">def</span> <span class="token">__lt__</span><span class="token">(</span>self<span class="token">,</span> other<span class="token">)</span><span class="token">:</span>
        <span class="token"># Definiuje zachowanie operatora &lt; (less than)</span>
        <span class="token">if</span> <span class="token">isinstance</span><span class="token">(</span>other<span class="token">,</span> Osoba<span class="token">)</span><span class="token">:</span>
            <span class="token">return</span> self<span class="token">.</span>wiek <span class="token">&lt;</span> other<span class="token">.</span>wiek
        <span class="token">return</span> NotImplemented
    
    <span class="token">def</span> <span class="token">__gt__</span><span class="token">(</span>self<span class="token">,</span> other<span class="token">)</span><span class="token">:</span>
        <span class="token"># Definiuje zachowanie operatora &gt; (greater than)</span>
        <span class="token">if</span> <span class="token">isinstance</span><span class="token">(</span>other<span class="token">,</span> Osoba<span class="token">)</span><span class="token">:</span>
            <span class="token">return</span> self<span class="token">.</span>wiek <span class="token">&gt;</span> other<span class="token">.</span>wiek
        <span class="token">return</span> NotImplemented
    
    <span class="token">def</span> <span class="token">__str__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">return</span> <span class="token string-interpolation">f"</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">imie</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> (</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">wiek</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> lat)"</span>


anna <span class="token">=</span> Osoba<span class="token">(</span><span class="token">"Anna"</span><span class="token">,</span> <span class="token">25</span><span class="token">)</span>
jan <span class="token">=</span> Osoba<span class="token">(</span><span class="token">"Jan"</span><span class="token">,</span> <span class="token">30</span><span class="token">)</span>
ola <span class="token">=</span> Osoba<span class="token">(</span><span class="token">"Ola"</span><span class="token">,</span> <span class="token">25</span><span class="token">)</span>

<span class="token">print</span><span class="token">(</span>anna <span class="token">==</span> ola<span class="token">)</span>  <span class="token"># True (ten sam wiek)</span>
<span class="token">print</span><span class="token">(</span>anna <span class="token">==</span> jan<span class="token">)</span>  <span class="token"># False</span>
<span class="token">print</span><span class="token">(</span>anna <span class="token">&lt;</span> jan<span class="token">)</span>   <span class="token"># True (Anna jest młodsza)</span>
<span class="token">print</span><span class="token">(</span>jan <span class="token">&gt;</span> anna<span class="token">)</span>   <span class="token"># True (Jan jest starszy)</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading">&nbsp;<strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">__len__</code></strong></h3>



<p class="whitespace-normal break-words">Pozwala użyć funkcji <code class="prettyprint lang-sql" style="font-size: 0.85em;">len()</code> na Twoim obiekcie.</p>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token">class</span> <span class="token">Playlista</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> nazwa<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>nazwa <span class="token">=</span> nazwa
        self<span class="token">.</span>utwory <span class="token">=</span> <span class="token">[</span><span class="token">]</span>
    
    <span class="token">def</span> <span class="token">dodaj_utwor</span><span class="token">(</span>self<span class="token">,</span> utwor<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>utwory<span class="token">.</span>append<span class="token">(</span>utwor<span class="token">)</span>
    
    <span class="token">def</span> <span class="token">__len__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">return</span> <span class="token">len</span><span class="token">(</span>self<span class="token">.</span>utwory<span class="token">)</span>
    
    <span class="token">def</span> <span class="token">__str__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">return</span> <span class="token string-interpolation">f'Playlista "</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">nazwa</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">" (</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">len</span><span class="token string-interpolation interpolation">(</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">)</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> utworów)'</span>


moja_playlista <span class="token">=</span> Playlista<span class="token">(</span><span class="token">"Ulubione"</span><span class="token">)</span>
moja_playlista<span class="token">.</span>dodaj_utwor<span class="token">(</span><span class="token">"Piosenka 1"</span><span class="token">)</span>
moja_playlista<span class="token">.</span>dodaj_utwor<span class="token">(</span><span class="token">"Piosenka 2"</span><span class="token">)</span>
moja_playlista<span class="token">.</span>dodaj_utwor<span class="token">(</span><span class="token">"Piosenka 3"</span><span class="token">)</span>

<span class="token">print</span><span class="token">(</span><span class="token">len</span><span class="token">(</span>moja_playlista<span class="token">)</span><span class="token">)</span>  <span class="token"># 3</span>
<span class="token">print</span><span class="token">(</span>moja_playlista<span class="token">)</span>       <span class="token"># Playlista "Ulubione" (3 utworów)</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading">&nbsp;<strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">__getitem__</code> i <code class="prettyprint lang-sql" style="font-size: 0.85em;">__setitem__</code></strong></h3>



<p class="whitespace-normal break-words">Pozwalają używać nawiasów kwadratowych <code class="prettyprint lang-sql" style="font-size: 0.85em;">[]</code> do dostępu do elementów.</p>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token">class</span> <span class="token">Slownik</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>dane <span class="token">=</span> <span class="token">{</span><span class="token">}</span>
    
    <span class="token">def</span> <span class="token">__getitem__</span><span class="token">(</span>self<span class="token">,</span> klucz<span class="token">)</span><span class="token">:</span>
        <span class="token"># Pozwala na: obiekt[klucz]</span>
        <span class="token">return</span> self<span class="token">.</span>dane<span class="token">.</span>get<span class="token">(</span>klucz<span class="token">,</span> <span class="token">"Brak wartości"</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">__setitem__</span><span class="token">(</span>self<span class="token">,</span> klucz<span class="token">,</span> wartosc<span class="token">)</span><span class="token">:</span>
        <span class="token"># Pozwala na: obiekt[klucz] = wartosc</span>
        self<span class="token">.</span>dane<span class="token">[</span>klucz<span class="token">]</span> <span class="token">=</span> wartosc
    
    <span class="token">def</span> <span class="token">__str__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">return</span> <span class="token">str</span><span class="token">(</span>self<span class="token">.</span>dane<span class="token">)</span>


slownik <span class="token">=</span> Slownik<span class="token">(</span><span class="token">)</span>
slownik<span class="token">[</span><span class="token">"imie"</span><span class="token">]</span> <span class="token">=</span> <span class="token">"Anna"</span>        <span class="token"># Wywołuje __setitem__</span>
slownik<span class="token">[</span><span class="token">"miasto"</span><span class="token">]</span> <span class="token">=</span> <span class="token">"Warszawa"</span>

<span class="token">print</span><span class="token">(</span>slownik<span class="token">[</span><span class="token">"imie"</span><span class="token">]</span><span class="token">)</span>          <span class="token"># Wywołuje __getitem__ -&gt; "Anna"</span>
<span class="token">print</span><span class="token">(</span>slownik<span class="token">[</span><span class="token">"nieistniejacy"</span><span class="token">]</span><span class="token">)</span> <span class="token"># "Brak wartości"</span>
<span class="token">print</span><span class="token">(</span>slownik<span class="token">)</span>                  <span class="token"># {'imie': 'Anna', 'miasto': 'Warszawa'}</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading">&nbsp;<strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">__add__</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">__sub__</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">__mul__</code></strong> &#8211; operatory matematyczne</h3>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token">class</span> <span class="token">Wektor</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> x<span class="token">,</span> y<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>x <span class="token">=</span> x
        self<span class="token">.</span>y <span class="token">=</span> y
    
    <span class="token">def</span> <span class="token">__add__</span><span class="token">(</span>self<span class="token">,</span> other<span class="token">)</span><span class="token">:</span>
        <span class="token"># Definiuje operator +</span>
        <span class="token">if</span> <span class="token">isinstance</span><span class="token">(</span>other<span class="token">,</span> Wektor<span class="token">)</span><span class="token">:</span>
            <span class="token">return</span> Wektor<span class="token">(</span>self<span class="token">.</span>x <span class="token">+</span> other<span class="token">.</span>x<span class="token">,</span> self<span class="token">.</span>y <span class="token">+</span> other<span class="token">.</span>y<span class="token">)</span>
        <span class="token">return</span> NotImplemented
    
    <span class="token">def</span> <span class="token">__mul__</span><span class="token">(</span>self<span class="token">,</span> skalar<span class="token">)</span><span class="token">:</span>
        <span class="token"># Definiuje operator *</span>
        <span class="token">if</span> <span class="token">isinstance</span><span class="token">(</span>skalar<span class="token">,</span> <span class="token">(</span><span class="token">int</span><span class="token">,</span> <span class="token">float</span><span class="token">)</span><span class="token">)</span><span class="token">:</span>
            <span class="token">return</span> Wektor<span class="token">(</span>self<span class="token">.</span>x <span class="token">*</span> skalar<span class="token">,</span> self<span class="token">.</span>y <span class="token">*</span> skalar<span class="token">)</span>
        <span class="token">return</span> NotImplemented
    
    <span class="token">def</span> <span class="token">__str__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">return</span> <span class="token string-interpolation">f"Wektor(</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">x</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">, </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">y</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">)"</span>


v1 <span class="token">=</span> Wektor<span class="token">(</span><span class="token">1</span><span class="token">,</span> <span class="token">2</span><span class="token">)</span>
v2 <span class="token">=</span> Wektor<span class="token">(</span><span class="token">3</span><span class="token">,</span> <span class="token">4</span><span class="token">)</span>

v3 <span class="token">=</span> v1 <span class="token">+</span> v2        <span class="token"># Wektor(4, 6)</span>
v4 <span class="token">=</span> v1 <span class="token">*</span> <span class="token">3</span>         <span class="token"># Wektor(3, 6)</span>

<span class="token">print</span><span class="token">(</span>v3<span class="token">)</span>
<span class="token">print</span><span class="token">(</span>v4<span class="token">)</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading">&nbsp;<strong><code class="prettyprint lang-sql" style="font-size: 0.85em;">__call__</code> </strong>&#8211; obiekt jako funkcja</h3>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token">class</span> <span class="token">Powitanie</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> jezyk<span class="token">=</span><span class="token">"polski"</span><span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>jezyk <span class="token">=</span> jezyk
    
    <span class="token">def</span> <span class="token">__call__</span><span class="token">(</span>self<span class="token">,</span> imie<span class="token">)</span><span class="token">:</span>
        <span class="token"># Pozwala wywoływać obiekt jak funkcję</span>
        <span class="token">if</span> self<span class="token">.</span>jezyk <span class="token">==</span> <span class="token">"polski"</span><span class="token">:</span>
            <span class="token">return</span> <span class="token string-interpolation">f"Cześć, </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">imie</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">!"</span>
        <span class="token">elif</span> self<span class="token">.</span>jezyk <span class="token">==</span> <span class="token">"angielski"</span><span class="token">:</span>
            <span class="token">return</span> <span class="token string-interpolation">f"Hello, </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">imie</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">!"</span>
        <span class="token">else</span><span class="token">:</span>
            <span class="token">return</span> <span class="token string-interpolation">f"Witaj, </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">imie</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">!"</span>


powitanie_pl <span class="token">=</span> Powitanie<span class="token">(</span><span class="token">"polski"</span><span class="token">)</span>
powitanie_en <span class="token">=</span> Powitanie<span class="token">(</span><span class="token">"angielski"</span><span class="token">)</span>

<span class="token"># Wywołujemy obiekty jak funkcje!</span>
<span class="token">print</span><span class="token">(</span>powitanie_pl<span class="token">(</span><span class="token">"Anna"</span><span class="token">)</span><span class="token">)</span>  <span class="token"># Cześć, Anna!</span>
<span class="token">print</span><span class="token">(</span>powitanie_en<span class="token">(</span><span class="token">"John"</span><span class="token">)</span><span class="token">)</span>  <span class="token"># Hello, John!</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading">&nbsp;Tabela najważniejszych metod specjalnych:</h3>



<figure class="wp-block-table bg-bg-100 min-w-full border-separate border-spacing-0 text-sm leading-[1.88888] whitespace-normal"><table class="has-fixed-layout"><thead><tr><th>Metoda</th><th>Opis</th><th>Przykład użycia</th></tr></thead><tbody><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__init__</code></td><td>Konstruktor</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj = Klasa()</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__str__</code></td><td>Reprezentacja tekstowa</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">print(obj)</code>, <code class="prettyprint lang-sql" style="font-size: 0.85em;">str(obj)</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__repr__</code></td><td>Reprezentacja dla debugowania</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">repr(obj)</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__len__</code></td><td>Długość obiektu</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">len(obj)</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__eq__</code></td><td>Równość</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj1 == obj2</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__lt__</code></td><td>Mniejsze niż</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj1 &lt; obj2</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__gt__</code></td><td>Większe niż</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj1 &gt; obj2</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__add__</code></td><td>Dodawanie</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj1 + obj2</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__sub__</code></td><td>Odejmowanie</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj1 - obj2</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__mul__</code></td><td>Mnożenie</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj * 5</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__getitem__</code></td><td>Dostęp przez indeks</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj[key]</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__setitem__</code></td><td>Ustawianie przez indeks</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj[key] = value</code></td></tr><tr><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">__call__</code></td><td>Wywołanie jak funkcja</td><td><code class="prettyprint lang-sql" style="font-size: 0.85em;">obj()</code></td></tr></tbody></table></figure>



<p>Odsyłam Was do fajnego artykułu <a href="https://printpython.pl/python/magiczne-metody-czyli-szczypta-magii-w-pythonie/" target="_blank" rel="noopener">Magiczne metody – czyli szczypta magii w Pythonie</a>.</p>



<h2 class="wp-block-heading">Modyfikatory dostępu</h2>



<div>
<div>W Python nie ma modyfikatorów dostępu, możemy użyć &#8222;_&#8221; lub &#8222;__&#8221; &#8211; pojedynczy podkreślnik to uzgodnienia programistów żeby nie ingerować w taką własność lub metodę, użycie podwójnego podkreślnika (np. <code class="prettyprint lang-sql" style="font-size: 0.85em;">__moja_metoda</code>) powoduje, że Python zmienia jej nazwę w taki sposób, że dodaje do niej nazwę klasy w postaci prefiksu. Na przykład, jeśli mamy klasę <code class="prettyprint lang-sql" style="font-size: 0.85em;">MojaKlasa</code> i zdefiniujemy w niej metodę <code class="prettyprint lang-sql" style="font-size: 0.85em;">__moja_metoda</code>, Python zmieni jej nazwę na <code class="prettyprint lang-sql" style="font-size: 0.85em;">_MojaKlasa__moja_metoda</code>. Dzięki temu unika się konfliktów nazw w przypadku dziedziczenia.</div>
</div>



<p>Ale trochę praktyki:</p>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="pln">class MojaKlasa:<br />    def __init__(self):<br />        self.publiczne_pole = 42<br />        self.__ukryte_pole = 24<br /><br />    def publiczna_metoda(self):<br />        print("To jest publiczna metoda.")<br /><br />    def __ukryta_metoda(self):<br />        print("To jest ukryta metoda.")<br /><br />obiekt = MojaKlasa()<br />print(obiekt.publiczne_pole) # Możemy odczytać publiczne pole<br />print(obiekt.__ukryte_pole) # To spowoduje błąd, ale można odczytać to pole inaczej<br />obiekt.publiczna_metoda() # Możemy wywołać publiczną metodę
obiekt.__ukryta_metoda() # To spowoduje błąd, ale można wywołać tę metodę inaczej
</span></code></pre>



<p>Jest jednak sposób na dostęp do tych &#8222;ukrytych&#8221; pól i metod. Python faktycznie zmienia ich nazwy, dodając przed nimi nazwę klasy, w której się znajdują, co sprawia, że stają się trudniejsze do dostępu. Na przykład, pole <code class="prettyprint lang-sql" style="font-size: 0.85em;">__ukryte_pole</code> zostanie zmienione na <code class="prettyprint lang-sql" style="font-size: 0.85em;">_MojaKlasa__ukryte_pole</code>. Możesz uzyskać dostęp do tych elementów w ten sposób:</p>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="pun">print(obiekt._MojaKlasa__ukryte_pole)<br />obiekt._MojaKlasa__ukryta_metoda();</span></code></pre>



<p>Jednak w praktyce zaleca się unikania dostępu do ukrytych pól i metod, ponieważ łamie to konwencję i może prowadzić do problemów w przyszłości. Lepiej jest trzymać się konwencji i zakładać, że te elementy są przeznaczone do użytku wewnętrznego w ramach klasy lub modułu.</p>



<h2 class="wp-block-heading">Dziedziczenie</h2>



<p>Tak jak w życiu – jako potomkowie dziedziczymy po naszych przodkach pewne cechy (tak naprawdę to 50% od matki i 50% od ojca), tak samo klasy dziedziczą pola i metody, ale mogą zostać uzupełnione o inne elementy, których przodek nie posiada.</p>



<p>Aby klasa dziedziczyła po innej należy w nawiasie podać nazwę klasy przodka:</p>



<div>
<pre class="prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Zwierze:</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; rodzaj= "lądowe"</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def odglos(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; return "brak"</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Pies(Zwierze):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def odglos(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; return "hał"</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Ryba(Zwierze):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">  &nbsp; rodzaj= "wodne"</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def odglos(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; return "bulbul"</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">pies = Pies()</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">ryba = Ryba()</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">print(f"""Odgłos psa to {pies.odglos()}, należy do rodzaju: {pies.rodzaj}.</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Odgłos ryby to {ryba.odglos()}, należy do rodzaju: {ryba.rodzaj}.""")</code></pre>
</div>



<p><span class="Y2IQFc" lang="pl">Python obsługuje również formę <span style="text-decoration: underline;"><strong>wielokrotnego dziedziczenia</strong></span>. Definicja klasy zawierająca wiele klas bazowych wygląda następująco:</span></p>



<pre class="wp-block-preformatted prettyprint"><span class="k">class</span> <span class="nc">DerivedClassName</span><span class="p">(</span><span class="n">Base1</span><span class="p">,</span> <span class="n">Base2</span><span class="p">,</span> <span class="n">Base3</span><span class="p">):<br />    pass</span></pre>



<p><span class="Y2IQFc" lang="pl">W większości przypadków, można myśleć o wyszukiwaniu atrybutów odziedziczonych z klasy nadrzędnej jako o wyszukiwaniu w głąb, od lewej do prawej, a nie o wyszukiwaniu dwukrotnie w tej samej klasie, gdzie hierarchia się nakłada. Zatem jeśli atrybut nie zostanie znaleziony w DerivedClassName, jest on wyszukiwany w Base1, następnie (rekurencyjnie) w bazowych klasach Base1, a jeśli tam go nie znaleziono, szukano go w Base2 i tak dalej.</span></p>



<p>Poniżej znajduje się przykład z wykorzystaniem dziedziczenia, a w tym:</p>



<ul class="wp-block-list">
<li>konstruktora(__init__) &#8211; do którego przekazywane są argumenty</li>



<li>super() &#8211; który odwoła się do konstruktora klasy bazowej, a w ogólnym użyciu pozwala odwołać się do każdej metody przodka</li>



<li>isinstance &#8211; pozwala sprawdzić czy obiekt jest instancją danej klasy, zwraca True lub False</li>
</ul>



<div>
<pre class="prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Budynek:</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def __init__(self, rok_budowy):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; self._rok_budowy = rok_budowy</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"Utworzono obiekt {self}.")</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def rok_budowy(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; return self._rok_budowy</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Szpital(Budynek):</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def __init__(self, rok_budowy):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; super().__init__(rok_budowy)</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; self._kondygnacje = "Budynek szpitala 2 kondygnacyjny"</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def info(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"Metoda w klasie {__class__.__name__}")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"Obiekt {self} - kondygnacje: {self._kondygnacje}")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"Rok budowy = {super().rok_budowy()}")</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def test(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print("To jest wywołanie metody z klasy nadrzędnej w klasie Szpital")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"rok_budowy = {super().rok_budowy()}")</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Blok(Budynek):</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def __init__(self, rok_budowy):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; super().__init__(rok_budowy)</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; self._kondygnacje = "Blok 5 kondygnacji"</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def info(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"Metoda w klasie {__class__.__name__}")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"Obiekt {self} - kondygnacje: {self._kondygnacje}")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"Rok budowy = {super().rok_budowy()}")</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; def test(self):</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print("To jest wywołanie metody z klasy nadrzędnej w klasie Blok")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; &nbsp; &nbsp; print(f"rok_budowy = {super().rok_budowy()}")</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;"># definiujemy obiekty oraz tworzymy listę</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek01 = Blok(2001)</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek02 = Blok(2002)<br /></code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek03 = Szpital(2010)</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek04 = Szpital(2012)</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">"""</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Utworzono obiekt &lt;__main__.Blok object at 0x0000026706EDAED0&gt;.</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Utworzono obiekt &lt;__main__.Blok object at 0x0000026706EDBD90&gt;.</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Utworzono obiekt &lt;__main__.Szpital object at 0x0000026706EEC190&gt;.</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Utworzono obiekt &lt;__main__.Szpital object at 0x0000026706EEC1D0&gt;.</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">"""</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">spis_budynkow = [</code><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek01, </code><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek02, </code><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek03, </code><code class="prettyprint lang-sql" style="font-size: 0.85em;">budynek04,]</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">for budynek in spis_budynkow:</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">  &nbsp; print(f"isinstance({budynek}, Szpital) = {isinstance(budynek, Szpital)}") </code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">  &nbsp; print(f"isinstance({budynek}, Blok) = {isinstance(budynek, Blok)}") </code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">  &nbsp; print(f"isinstance({budynek}, Budynek) = {isinstance(budynek, Budynek)}") &nbsp;</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; print("----------")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">"""</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Blok object at 0x0000026706EDAED0&gt;, Szpital) = False</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Blok object at 0x0000026706EDAED0&gt;, Blok) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Blok object at 0x0000026706EDAED0&gt;, Budynek) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">----------</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Blok object at 0x0000026706EDBD90&gt;, Szpital) = False</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Blok object at 0x0000026706EDBD90&gt;, Blok) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Blok object at 0x0000026706EDBD90&gt;, Budynek) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">----------</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Szpital object at 0x0000026706EEC190&gt;, Szpital) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Szpital object at 0x0000026706EEC190&gt;, Blok) = False</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Szpital object at 0x0000026706EEC190&gt;, Budynek) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">----------</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Szpital object at 0x0000026706EEC1D0&gt;, Szpital) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Szpital object at 0x0000026706EEC1D0&gt;, Blok) = False</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">isinstance(&lt;__main__.Szpital object at 0x0000026706EEC1D0&gt;, Budynek) = True</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">"""</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">for budynek in spis_budynkow:</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; print("-----------------------------")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; budynek.test()</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; print("-----")</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">&nbsp; &nbsp; budynek.info()</code><br /><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">"""</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----------------------------</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">To jest wywołanie metody z klasy nadrzędnej w klasie Blok</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">rok_budowy = 2001</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Metoda w klasie Blok</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Obiekt &lt;__main__.Blok object at 0x0000026706EDAED0&gt; - kondygnacje: Blok 5 kondygnacji</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Rok budowy = 2001</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----------------------------</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">To jest wywołanie metody z klasy nadrzędnej w klasie Blok</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">rok_budowy = 2002</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Metoda w klasie Blok</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Obiekt &lt;__main__.Blok object at 0x0000026706EDBD90&gt; - kondygnacje: Blok 5 kondygnacji</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Rok budowy = 2002</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----------------------------</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">To jest wywołanie metody z klasy nadrzędnej w klasie Szpital</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">rok_budowy = 2010</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Metoda w klasie Szpital</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Obiekt &lt;__main__.Szpital object at 0x0000026706EEC190&gt; - kondygnacje: Budynek szpitala 2 kondygnacyjny</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Rok budowy = 2010</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----------------------------</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">To jest wywołanie metody z klasy nadrzędnej w klasie Szpital</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">rok_budowy = 2012</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">-----</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Metoda w klasie Szpital</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Obiekt &lt;__main__.Szpital object at 0x0000026706EEC1D0&gt; - kondygnacje: Budynek szpitala 2 kondygnacyjny</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">Rok budowy = 2012</code><br /><code class="prettyprint lang-sql" style="font-size: 0.85em;">"""</code></pre>
</div>



<h2 class="wp-block-heading text-xl font-bold text-text-100 mt-1 -mb-0.5">Kompozycja vs Dziedziczenie</h2>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Czym jest kompozycja?</h3>



<p class="whitespace-normal break-words"><strong>Kompozycja</strong> to technika budowania złożonych obiektów z prostszych, poprzez <strong>zawieranie</strong> innych obiektów jako atrybutów. Zamiast mówić &#8222;klasa A <strong>jest</strong> klasą B&#8221; (dziedziczenie), mówimy &#8222;klasa A <strong>ma</strong> obiekt B&#8221; (kompozycja).</p>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Kiedy używać kompozycji, a kiedy dziedziczenia?</h3>



<h4 class="wp-block-heading text-base font-bold text-text-100 mt-1">Używaj <strong>dziedziczenia</strong>, gdy:</h4>



<ul class="wp-block-list [&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-2.5 pl-7">
<li>Istnieje relacja &#8222;jest&#8221; (<em>is-a</em>): Pies <strong>jest</strong> Zwierzęciem</li>



<li>Klasa potomna jest specjalizacją klasy bazowej</li>



<li>Chcesz współdzielić wspólny interfejs</li>
</ul>



<h4 class="wp-block-heading text-base font-bold text-text-100 mt-1">Używaj <strong>kompozycji</strong>, gdy:</h4>



<ul class="wp-block-list [&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc space-y-2.5 pl-7">
<li>Istnieje relacja &#8222;ma&#8221; (<em>has-a</em>): Samochód <strong>ma</strong> Silnik</li>



<li>Potrzebujesz funkcjonalności z wielu źródeł</li>



<li>Chcesz większej elastyczności</li>
</ul>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Przykład 1: Problem z dziedziczeniem</h3>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token"># ZŁE PODEJŚCIE - nadmierne dziedziczenie</span>
<span class="token">class</span> <span class="token">Zwierze</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">jedz</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Jem"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Ptak</span><span class="token">(</span>Zwierze<span class="token">)</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">lataj</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Lecę"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Pingwin</span><span class="token">(</span>Ptak<span class="token">)</span><span class="token">:</span>
    <span class="token"># Problem! Pingwin nie lata, ale dziedziczy metodę lataj()</span>
    <span class="token">pass</span>

<span class="token"># Pingwin dziedziczy lataj(), mimo że nie powinien latać</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Przykład 2: Rozwiązanie z kompozycją</h3>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token"># DOBRE PODEJŚCIE - kompozycja</span>

<span class="token">class</span> <span class="token">Latanie</span><span class="token">:</span>
    <span class="token triple-quoted-string">"""Komponent odpowiedzialny za latanie"""</span>
    <span class="token">def</span> <span class="token">lataj</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Lecę w powietrzu"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Plywanie</span><span class="token">:</span>
    <span class="token triple-quoted-string">"""Komponent odpowiedzialny za pływanie"""</span>
    <span class="token">def</span> <span class="token">plywaj</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Pływam w wodzie"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Zwierze</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> nazwa<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>nazwa <span class="token">=</span> nazwa
    
    <span class="token">def</span> <span class="token">jedz</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token string-interpolation">f"</span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">nazwa</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> je"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Orzel</span><span class="token">(</span>Zwierze<span class="token">)</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> nazwa<span class="token">)</span><span class="token">:</span>
        <span class="token">super</span><span class="token">(</span><span class="token">)</span><span class="token">.</span>__init__<span class="token">(</span>nazwa<span class="token">)</span>
        <span class="token"># Orzeł MA zdolność latania (kompozycja)</span>
        self<span class="token">.</span>latanie <span class="token">=</span> Latanie<span class="token">(</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">wykonaj_lot</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>latanie<span class="token">.</span>lataj<span class="token">(</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Pingwin</span><span class="token">(</span>Zwierze<span class="token">)</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> nazwa<span class="token">)</span><span class="token">:</span>
        <span class="token">super</span><span class="token">(</span><span class="token">)</span><span class="token">.</span>__init__<span class="token">(</span>nazwa<span class="token">)</span>
        <span class="token"># Pingwin MA zdolność pływania (kompozycja)</span>
        self<span class="token">.</span>plywanie <span class="token">=</span> Plywanie<span class="token">(</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">wykonaj_plywanie</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>plywanie<span class="token">.</span>plywaj<span class="token">(</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Kaczka</span><span class="token">(</span>Zwierze<span class="token">)</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> nazwa<span class="token">)</span><span class="token">:</span>
        <span class="token">super</span><span class="token">(</span><span class="token">)</span><span class="token">.</span>__init__<span class="token">(</span>nazwa<span class="token">)</span>
        <span class="token"># Kaczka MA obie zdolności!</span>
        self<span class="token">.</span>latanie <span class="token">=</span> Latanie<span class="token">(</span><span class="token">)</span>
        self<span class="token">.</span>plywanie <span class="token">=</span> Plywanie<span class="token">(</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">wykonaj_lot</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>latanie<span class="token">.</span>lataj<span class="token">(</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">wykonaj_plywanie</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>plywanie<span class="token">.</span>plywaj<span class="token">(</span><span class="token">)</span>


<span class="token"># Użycie:</span>
orzel <span class="token">=</span> Orzel<span class="token">(</span><span class="token">"Bielik"</span><span class="token">)</span>
orzel<span class="token">.</span>jedz<span class="token">(</span><span class="token">)</span>           <span class="token"># Bielik je</span>
orzel<span class="token">.</span>wykonaj_lot<span class="token">(</span><span class="token">)</span>    <span class="token"># Lecę w powietrzu</span>

pingwin <span class="token">=</span> Pingwin<span class="token">(</span><span class="token">"Pongo"</span><span class="token">)</span>
pingwin<span class="token">.</span>jedz<span class="token">(</span><span class="token">)</span>              <span class="token"># Pongo je</span>
pingwin<span class="token">.</span>wykonaj_plywanie<span class="token">(</span><span class="token">)</span>  <span class="token"># Pływam w wodzie</span>

kaczka <span class="token">=</span> Kaczka<span class="token">(</span><span class="token">"Donald"</span><span class="token">)</span>
kaczka<span class="token">.</span>jedz<span class="token">(</span><span class="token">)</span>              <span class="token"># Donald je</span>
kaczka<span class="token">.</span>wykonaj_lot<span class="token">(</span><span class="token">)</span>       <span class="token"># Lecę w powietrzu</span>
kaczka<span class="token">.</span>wykonaj_plywanie<span class="token">(</span><span class="token">)</span>  <span class="token"># Pływam w wodzie</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Przykład 3: Samochód &#8211; praktyczny przykład kompozycji</h3>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token">class</span> <span class="token">Silnik</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> moc<span class="token">,</span> pojemnosc<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>moc <span class="token">=</span> moc
        self<span class="token">.</span>pojemnosc <span class="token">=</span> pojemnosc
        self<span class="token">.</span>uruchomiony <span class="token">=</span> <span class="token">False</span>
    
    <span class="token">def</span> <span class="token">uruchom</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">if</span> <span class="token">not</span> self<span class="token">.</span>uruchomiony<span class="token">:</span>
            self<span class="token">.</span>uruchomiony <span class="token">=</span> <span class="token">True</span>
            <span class="token">print</span><span class="token">(</span><span class="token string-interpolation">f"Silnik </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">pojemnosc</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">L uruchomiony"</span><span class="token">)</span>
        <span class="token">else</span><span class="token">:</span>
            <span class="token">print</span><span class="token">(</span><span class="token">"Silnik już pracuje"</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">zatrzymaj</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">if</span> self<span class="token">.</span>uruchomiony<span class="token">:</span>
            self<span class="token">.</span>uruchomiony <span class="token">=</span> <span class="token">False</span>
            <span class="token">print</span><span class="token">(</span><span class="token">"Silnik zatrzymany"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Kola</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> rozmiar<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>rozmiar <span class="token">=</span> rozmiar
    
    <span class="token">def</span> <span class="token">informacja</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">return</span> <span class="token string-interpolation">f"Koła </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">rozmiar</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> cali"</span>

<span class="token">class</span> <span class="token">Nawigacja</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>aktywna <span class="token">=</span> <span class="token">False</span>
    
    <span class="token">def</span> <span class="token">wlacz</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>aktywna <span class="token">=</span> <span class="token">True</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Nawigacja włączona"</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">wyznacz_trase</span><span class="token">(</span>self<span class="token">,</span> cel<span class="token">)</span><span class="token">:</span>
        <span class="token">if</span> self<span class="token">.</span>aktywna<span class="token">:</span>
            <span class="token">print</span><span class="token">(</span><span class="token string-interpolation">f"Wyznaczam trasę do: </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">cel</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">"</span><span class="token">)</span>
        <span class="token">else</span><span class="token">:</span>
            <span class="token">print</span><span class="token">(</span><span class="token">"Najpierw włącz nawigację"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">Samochod</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">__init__</span><span class="token">(</span>self<span class="token">,</span> marka<span class="token">,</span> model<span class="token">)</span><span class="token">:</span>
        self<span class="token">.</span>marka <span class="token">=</span> marka
        self<span class="token">.</span>model <span class="token">=</span> model
        <span class="token"># Kompozycja - samochód SKŁADA SIĘ z innych obiektów</span>
        self<span class="token">.</span>silnik <span class="token">=</span> Silnik<span class="token">(</span>moc<span class="token">=</span><span class="token">150</span><span class="token">,</span> pojemnosc<span class="token">=</span><span class="token">2.0</span><span class="token">)</span>
        self<span class="token">.</span>kola <span class="token">=</span> Kola<span class="token">(</span>rozmiar<span class="token">=</span><span class="token">17</span><span class="token">)</span>
        self<span class="token">.</span>nawigacja <span class="token">=</span> Nawigacja<span class="token">(</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">uruchom_samochod</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token string-interpolation">f"\n--- Uruchamianie </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">marka</span><span class="token string-interpolation interpolation">}</span> <span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">model</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> ---"</span><span class="token">)</span>
        self<span class="token">.</span>silnik<span class="token">.</span>uruchom<span class="token">(</span><span class="token">)</span>
        <span class="token">print</span><span class="token">(</span>self<span class="token">.</span>kola<span class="token">.</span>informacja<span class="token">(</span><span class="token">)</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">jedz_do</span><span class="token">(</span>self<span class="token">,</span> miejsce<span class="token">)</span><span class="token">:</span>
        <span class="token">if</span> self<span class="token">.</span>silnik<span class="token">.</span>uruchomiony<span class="token">:</span>
            self<span class="token">.</span>nawigacja<span class="token">.</span>wlacz<span class="token">(</span><span class="token">)</span>
            self<span class="token">.</span>nawigacja<span class="token">.</span>wyznacz_trase<span class="token">(</span>miejsce<span class="token">)</span>
            <span class="token">print</span><span class="token">(</span><span class="token string-interpolation">f"Jadę do: </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">miejsce</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation">"</span><span class="token">)</span>
        <span class="token">else</span><span class="token">:</span>
            <span class="token">print</span><span class="token">(</span><span class="token">"Najpierw uruchom samochód"</span><span class="token">)</span>
    
    <span class="token">def</span> <span class="token">zatrzymaj_samochod</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token string-interpolation">f"\n--- Zatrzymywanie </span><span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">marka</span><span class="token string-interpolation interpolation">}</span> <span class="token string-interpolation interpolation">{</span><span class="token string-interpolation interpolation">self</span><span class="token string-interpolation interpolation">.</span><span class="token string-interpolation interpolation">model</span><span class="token string-interpolation interpolation">}</span><span class="token string-interpolation"> ---"</span><span class="token">)</span>
        self<span class="token">.</span>silnik<span class="token">.</span>zatrzymaj<span class="token">(</span><span class="token">)</span>


<span class="token"># Użycie:</span>
moj_samochod <span class="token">=</span> Samochod<span class="token">(</span><span class="token">"Toyota"</span><span class="token">,</span> <span class="token">"Corolla"</span><span class="token">)</span>
moj_samochod<span class="token">.</span>uruchom_samochod<span class="token">(</span><span class="token">)</span>
<span class="token"># --- Uruchamianie Toyota Corolla ---</span>
<span class="token"># Silnik 2.0L uruchomiony</span>
<span class="token"># Koła 17 cali</span>

moj_samochod<span class="token">.</span>jedz_do<span class="token">(</span><span class="token">"Warszawa"</span><span class="token">)</span>
<span class="token"># Nawigacja włączona</span>
<span class="token"># Wyznaczam trasę do: Warszawa</span>
<span class="token"># Jadę do: Warszawa</span>

moj_samochod<span class="token">.</span>zatrzymaj_samochod<span class="token">(</span><span class="token">)</span>
<span class="token"># --- Zatrzymywanie Toyota Corolla ---</span>
<span class="token"># Silnik zatrzymany</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Zalety kompozycji:</h3>



<ol class="wp-block-list [&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-decimal space-y-2.5 pl-7">
<li><strong>Większa elastyczność</strong> &#8211; możesz łatwo zmieniać komponenty</li>



<li><strong>Łatwiejsze testowanie</strong> &#8211; każdy komponent można testować osobno</li>



<li><strong>Unikanie problemów z wielodziedziczeniem</strong></li>



<li><strong>Luźniejsze powiązania</strong> &#8211; komponenty są niezależne</li>



<li><strong>Łatwiejsze ponowne użycie</strong> &#8211; komponenty działają w różnych kontekstach</li>
</ol>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Wady kompozycji:</h3>



<ol class="wp-block-list [&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-decimal space-y-2.5 pl-7">
<li>Więcej kodu do napisania (więcej klas)</li>



<li>Może być mniej intuicyjna niż dziedziczenie dla prostych relacji</li>



<li>Wymaga świadomego projektowania struktury</li>
</ol>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Złota zasada:</h3>



<blockquote class="wp-block-quote border-border-200 border-l-4 pl-4 is-layout-flow wp-block-quote-is-layout-flow">
<p class="whitespace-normal break-words"><strong>&#8222;Prefer composition over inheritance&#8221;</strong><br /><em>(Preferuj kompozycję nad dziedziczeniem)</em></p>
</blockquote>



<p class="whitespace-normal break-words">Nie oznacza to, że dziedziczenie jest złe! Po prostu w wielu przypadkach kompozycja daje lepsze rezultaty. Używaj dziedziczenia, gdy relacja &#8222;jest&#8221; (<em>is-a</em>) ma sens, a kompozycji, gdy relacja &#8222;ma&#8221; (<em>has-a</em>) lepiej opisuje sytuację.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading text-xl font-bold text-text-100 mt-1 -mb-0.5">Praktyczne ćwiczenie</h2>



<p class="whitespace-normal break-words">Spróbuj przeprojektować poniższy przykład używając kompozycji:</p>



<div class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg">
<div>
<pre class="prettyprint code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="token"># Aktualny kod z dziedziczeniem:</span>
<span class="token">class</span> <span class="token">Pracownik</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">pracuj</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Pracuję"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">PracownikZSamochodem</span><span class="token">(</span>Pracownik<span class="token">)</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">jedz_do_pracy</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Jadę samochodem"</span><span class="token">)</span>

<span class="token">class</span> <span class="token">PracownikZRowerem</span><span class="token">(</span>Pracownik<span class="token">)</span><span class="token">:</span>
    <span class="token">def</span> <span class="token">jedz_do_pracy</span><span class="token">(</span>self<span class="token">)</span><span class="token">:</span>
        <span class="token">print</span><span class="token">(</span><span class="token">"Jadę rowerem"</span><span class="token">)</span>

<span class="token"># Jak to przerobić na kompozycję?</span>
<span class="token"># Zastanów się: czy pracownik JEST samochodem, czy MA samochód?</span></code></pre>
</div>
</div>



<h3 class="wp-block-heading text-lg font-bold text-text-100 mt-1 -mb-1.5">Rozwiązanie:</h3>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;">class Samochod: 
    def jedz(self): 
        print("Jadę samochodem") 

class Rower: 
    def jedz(self): 
        print("Jadę rowerem") 

class Pracownik: 
    def __init__(self, imie, srodek_transportu=None): 
        self.imie = imie 
        self.srodek_transportu = srodek_transportu 
        
        def pracuj(self): 
            print(f"{self.imie} pracuje") 
        
        def jedz_do_pracy(self): 
            if self.srodek_transportu: 
                self.srodek_transportu.jedz() 
            else: 
                print(f"{self.imie} idzie pieszo") 
    
# Użycie - teraz możemy łatwo zmieniać środek transportu! jan = Pracownik("Jan", Samochod()) anna = Pracownik("Anna", Rower()) piotr = Pracownik("Piotr") # Bez środka transportu jan.jedz_do_pracy() # Jadę samochodem anna.jedz_do_pracy() # Jadę rowerem piotr.jedz_do_pracy() # Piotr idzie pieszo</code></pre>



<h2 class="wp-block-heading">Klasy i metody abstrakcyjne</h2>



<p>Klasa abstrakcyjna definiuje pewien model i zachowanie obiektu.</p>



<p>Taka klasa nie posiada definicji tych metod, jedynie ich deklaracje, że gdzieś dalej w kodzie muszą się pojawić. Czyli do czasu rozszerzenia ich o funkcjonalności w klasach dziedziczących, te metody nie istnieją (są abstrakcją). Klasa abstrakcyjna to taka klasa która służy do tego by z niej dziedziczyć i implementować te metody które oznaczone zostały jako abstrakcyjne.</p>



<p><strong>Nie można utworzyć obiektu klasy abstrakcyjnej.</strong> Klasa ta jest jedynie „bazą” dla klas potomnych.</p>



<p>Wyobraźmy sobie, że mamy klasę Zwierze, na jej podstawi tworzymy konkretne gatunki. W tym kontekście klasa Zwierze jest abstrakcyjna, bo nie można utworzyć istoty, która jest ogólnie zwierzęciem. Zawsze będziemy mieli na myśli konkretny gatunek kot, pies itp., które będą posiadały ogólne cechy, ale również indywidualne dla każdego z nich, które zostaną zakodowane w klasach potomnych.</p>



<p>Mechanizm klas i metod abstrakcyjnych (klasa jest abstrakcyjna gdy ma co najmniej jedną metodę abstrakcyjną) w języku Python jest wprowadzony trochę sztucznie, bo klasa bazowa (abstrakcyjna) musi dziedziczyć po sztucznej klasie <code class="prettyprint lang-sql" style="font-size: 0.85em;">ABC</code>, a metoda abstrakcyjna jest opatrzona dekoratorem <code class="prettyprint lang-sql" style="font-size: 0.85em;">@abstractmethod</code>.</p>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="kwd">from abc import ABC, abstractmethod</span><br />class AbstractClass(ABC):<br />    @abstractmethod<br />    def method1(self):<br />        pass<br /><br />    def method2(self):<br />        return "Hello!"<br /><br />    def __str__(self):<br />&nbsp; &nbsp; &nbsp; &nbsp; return f'Jestem {self.__class__.__name__}'<br /><br />obj = AbstractClass() #TypeError: Can't instantiate abstract class AbstractObject with abstract method method1<br /><br />class ConcreteClass(AbstractClass):<br />&nbsp; &nbsp; def method1(self):<br />&nbsp; &nbsp; &nbsp; &nbsp; print("Heeelo!")<br /><br /><br />print(ConcreteClass()) #to już się wykona</code></pre>



<h2 class="wp-block-heading">Interfejsy</h2>



<p>W Pythonie nie ma dedykowanego słowa kluczowego &#8222;interface&#8221; jak w niektórych innych językach programowania (np. Java). W praktyce, interfejsy są często reprezentowane za pomocą klas abstrakcyjnych w Pythonie, a moduł <code class="prettyprint lang-sql" style="font-size: 0.85em;">abc</code> (Abstract Base Classes) dostarcza mechanizmy do ich tworzenia.</p>



<h2 class="wp-block-heading">Paradygmat</h2>



<p>Z pojęciem programowania wiąże się <strong>paradygmat</strong> &#8211; jest to zbiór mechanizmów, używanych przez programistę podczas tworzenia kodu, a następnie wykonywany przez komputer. Paradygmat programowania obiektowego jest jak konstrukcja silnika z części składowych. Części to obiekty, które posiadają atrybuty i własności oraz współdziałają z innymi częściami.</p>



<p>Główne założenia programowania obiektowego to:</p>



<h3 class="wp-block-heading">Abstrakcja</h3>



<p>Pozwala programistom tworzyć obiekty, które ukrywają skomplikowane szczegóły i dostarczają prosty interfejs do korzystania z&nbsp; tych obiektów. Dzięki temu programiści mogą skupić się na używaniu tych obiektów bez konieczności zrozumienia każdego detalu ich działania.</p>



<p>W praktyce używając smartfona, nie musisz znać dokładnych technicznych szczegółów dotyczących działania systemu operacyjnego czy aplikacji. Możesz korzystać z funkcji telefonu, przeglądać internet, rozmawiać z ludźmi i wiele innych rzeczy, nie zastanawiając się nad tym, jak to wszystko działa &#8222;pod maską&#8221;.</p>



<div class="su-divider su-divider-style-default">&nbsp;</div>



<h3 class="wp-block-heading">Dziedziczenie</h3>



<p>Dziedziczenie to mechanizm w OOP, który umożliwia tworzenie nowych klas (klasy podrzędne lub potomne) na podstawie istniejących klas (klasy nadrzędne lub bazowe). Klasa potomna dziedziczy cechy (pola i metody) klasy nadrzędnej, co oznacza, że może korzystać z jej funkcjonalności. Dziedziczenie pozwala na tworzenie hierarchii klas, gdzie klasy potomne mogą rozszerzać lub modyfikować zachowanie klas nadrzędnych.</p>



<p>Przykład: Klasa &#8222;Samochód&#8221; może być klasą nadrzędną, a klasy &#8222;Sedan&#8221; i &#8222;SUV&#8221; mogą dziedziczyć od niej, dodając własne cechy specyficzne dla tych typów samochodów.</p>



<p>&nbsp;</p>



<h3 class="wp-block-heading">Enkapsulacja</h3>



<p>Enkapsulacja to zasada OOP, która polega na ukrywaniu wewnętrznych danych obiektu oraz dostępu do nich i udostępnianiu tylko niezbędnych informacji. Klasa może ukrywać swoje pola (zmienne) przed innymi klasami i udostępniać dostęp do nich tylko za pomocą publicznych metod, co pozwala na kontrolowanie i zabezpieczanie danych. Enkapsulacja pomaga utrzymać spójność i integralność danych w programie.</p>



<p>Przykład: Możemy ukryć pole &#8222;saldo&#8221; w klasie &#8222;KontoBankowe&#8221; i dostarczyć publiczne metody do wpłacania i wypłacania pieniędzy.</p>



<p>&nbsp;</p>



<h3 class="wp-block-heading">Polimorfizm</h3>



<p>Polimorfizm to zasada OOP, która pozwala na tworzenie wielu różnych klas, które posiadają wspólny interfejs, a jednocześnie mogą działać w różny sposób. Oznacza to, że różne obiekty mogą reagować na te same metody w zróżnicowany sposób, co jest użyteczne w dziedzinach, gdzie różne obiekty zachowują się inaczej. Istnieją dwa rodzaje polimorfizmu: polimorfizm klas (dziedziczenie i przesłanianie metod) oraz polimorfizm interfejsów (klasy implementujące wspólny interfejs).</p>



<p>Przykład: Mamy interfejs &#8222;Pojazd&#8221; i różne klasy, takie jak &#8222;Samochód&#8221; i &#8222;Rower&#8221;, które go implementują. Mogą być używane w ten sam sposób, choć działają inaczej.</p>



<h2 class="wp-block-heading">Zadanie 1</h2>



<p>Jesteś praktykantem w firmie zajmującej się tworzeniem witryn i aplikacji internetowych. Otrzymałeś zadanie polegające na stworzeniu skryptu w języku Python.</p>



<p>W skrypcie ma być utworzona klasa trójkąt, która zawiera dwa publiczne pola, takie jak: wysokość i podstawa, oraz konstruktor, który przypisze im losowo wygenerowane wartości.</p>



<p>Ponadto w klasie powinna być zadeklarowana metoda obliczająca pole trójkąta. <br />W aplikacji należy utworzyć dwa obiekty klasy trójkąt.</p>



<p>Wynikiem działania aplikacji ma być wyświetlona wartość wysokości, podstawy i pola powierzchni obu trójkątów oraz informacja, który z trójkątów ma większą powierzchnię.</p>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="kwd">print("=" * 60)
print("ZADANIE 1 - TRÓJKĄTY")
print("=" * 60)

import random

class Trojkat:
    def __init__(self):
        """Konstruktor generuje losowe wartości wysokości i podstawy"""
        self.wysokosc = random.randint(1, 20)
        self.podstawa = random.randint(1, 20)
    
    def oblicz_pole(self):
        """Metoda obliczająca pole trójkąta"""
        return (self.podstawa * self.wysokosc) / 2
    
    def __str__(self):
        """Reprezentacja tekstowa trójkąta"""
        return f"Trójkąt(podstawa={self.podstawa}, wysokość={self.wysokosc})"


# Tworzenie dwóch obiektów
trojkat1 = Trojkat()
trojkat2 = Trojkat()

# Obliczanie pól
pole1 = trojkat1.oblicz_pole()
pole2 = trojkat2.oblicz_pole()

# Wyświetlanie wyników
print(f"\n{trojkat1}")
print(f"Pole: {pole1} cm²")

print(f"\n{trojkat2}")
print(f"Pole: {pole2} cm²")

# Porównanie
if pole1 &gt; pole2:
    print(f"\n✓ Trójkąt 1 ma większą powierzchnię ({pole1} cm² &gt; {pole2} cm²)")
elif pole2 &gt; pole1:
    print(f"\n✓ Trójkąt 2 ma większą powierzchnię ({pole2} cm² &gt; {pole1} cm²)")
else:
    print(f"\n✓ Oba trójkąty mają taką samą powierzchnię ({pole1} cm²)")</span></code></pre>



<h2 class="wp-block-heading">Zadanie 2</h2>



<p>Jesteś praktykantem w firmie zajmującej się tworzeniem witryn i aplikacji internetowych. Otrzymałeś zadanie polegające na stworzeniu skryptu w języku Python.</p>



<p>W skrypcie ma być utworzona klasa odcinek zawierająca cztery publiczne pola, określające współrzędne początku i końca odcinka we współrzędnych x, y. W klasie odcinek należy utworzyć konstruktor, który współrzędnym przypisze <span class="underline">podane przez użytkownika (za pomocą formularza)</span> wartości.</p>



<p>Ponadto w klasie powinna być zadeklarowana metoda obliczająca długość odcinka.</p>



<p>W aplikacji należy utworzyć dwa obiekty klasy odcinek.</p>



<p>Wynikiem działania aplikacji ma być wyświetlona wartość długości obu odcinków oraz informacja, który z nich jest dłuższy.</p>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="kwd">print("\n" + "=" * 60)
print("ZADANIE 2 - ODCINKI")
print("=" * 60)

import math

class Odcinek:
    def __init__(self, x1, y1, x2, y2):
        """
        Konstruktor przyjmuje współrzędne początku i końca odcinka
        x1, y1 - początek odcinka
        x2, y2 - koniec odcinka
        """
        self.x1 = x1
        self.y1 = y1
        self.x2 = x2
        self.y2 = y2
    
    def oblicz_dlugosc(self):
        """
        Metoda obliczająca długość odcinka ze wzoru:
        d = √&#91;(x2-x1)² + (y2-y1)²]
        """
        return math.sqrt((self.x2 - self.x1)**2 + (self.y2 - self.y1)**2)
    
    def __str__(self):
        """Reprezentacja tekstowa odcinka"""
        return f"Odcinek&#91;({self.x1}, {self.y1}) → ({self.x2}, {self.y2})]"


# Symulacja danych z formularza (w rzeczywistej aplikacji byłyby z input())
print("\nPodaj współrzędne pierwszego odcinka:")
odcinek1 = Odcinek(0, 0, 3, 4)
print(f"Utworzono: {odcinek1}")

print("\nPodaj współrzędne drugiego odcinka:")
odcinek2 = Odcinek(1, 1, 4, 5)
print(f"Utworzono: {odcinek2}")

# Obliczanie długości
dlugosc1 = odcinek1.oblicz_dlugosc()
dlugosc2 = odcinek2.oblicz_dlugosc()

# Wyświetlanie wyników
print(f"\nDługość odcinka 1: {dlugosc1:.2f} jednostek")
print(f"Długość odcinka 2: {dlugosc2:.2f} jednostek")

# Porównanie
if dlugosc1 &gt; dlugosc2:
    print(f"\n✓ Odcinek 1 jest dłuższy ({dlugosc1:.2f} &gt; {dlugosc2:.2f})")
elif dlugosc2 &gt; dlugosc1:
    print(f"\n✓ Odcinek 2 jest dłuższy ({dlugosc2:.2f} &gt; {dlugosc1:.2f})")
else:
    print(f"\n✓ Oba odcinki mają taką samą długość ({dlugosc1:.2f})")</span></code></pre>



<h2 class="wp-block-heading">Zadanie 3</h2>



<p>Stwórz klasę Okrag, w trakcie tworzenia instancji tej klasy jako argument podawany jest promień. Klasa ma dodatkową metodę obwod, która zwraca obwód okręgu. Następnie stwórz klasę Kolo, która dziedziczy klasę Okrag. Poza metodą obwod, klasa ta posiada metodę pole zwracającą pole powierzchni danego koła. Wartość pi należy pobrać z modułu math.<br />Stwórz instancję klasy Kolo o promieniu 10 i wydrukuj poleceniem print() jego obwód i powierzchnię.<br /><strong>Opis</strong><br />Wartości liczby π należy zaimportować z modułu math.<br />Klasa Okrag musi mieć dwie metody:</p>



<ul class="wp-block-list">
<li>__init__(self, promien) &#8211; metoda wywoływana w momencie tworzenia instancji klasy, musi przyjmować jeden dodatkowy argument określający promień okręgu, ktorego wartość należy zapamiętać,</li>



<li>obwod(self) &#8211; metoda zwracająca obwód okręgu. Obwód jest liczony z wzoru 2πr, promień jest pobierany z atrybutu klasy, wartość π jest określona zmienną pi z modułu math.</li>
</ul>



<p>Definiując klasę Kolo należy podać klasę Okrag w definicji, aby wykonać dziedziczenie.<br />Wszystkie atrybuty i metody zdefiniowane w klasie Okrag będą dostępne również w klasie Kolo. Dodatkowo należy dopisać metodę pole, w które z wzoru πr<sup>2</sup> zostanie obliczone i zwrócone pole koła.<br />Po zdefiniowaniu obu klas należy utworzyć nową instancję klasy Kolo o promieniu 10 i wywołać obie metody: obwod i pole.</p>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;"><span class="kwd">print("\n" + "=" * 60)
print("ZADANIE 3 - OKRĄG I KOŁO")
print("=" * 60)

from math import pi

class Okrag:
    def __init__(self, promien):
        """Konstruktor przyjmuje promień okręgu"""
        self.promien = promien
    
    def obwod(self):
        """Metoda zwracająca obwód okręgu: 2πr"""
        return 2 * pi * self.promien


class Kolo(Okrag):
    """Klasa Kolo dziedziczy po klasie Okrag"""
    
    def pole(self):
        """Metoda zwracająca pole koła: πr²"""
        return pi * self.promien ** 2


# Tworzenie instancji klasy Kolo o promieniu 10
kolo = Kolo(10)

# Wyświetlanie obwodu i powierzchni
print(f"\nKoło o promieniu {kolo.promien}:")
print(f"Obwód: {kolo.obwod():.2f} jednostek")
print(f"Pole: {kolo.pole():.2f} jednostek²")</span></code></pre>



<h2 class="wp-block-heading">Zadanie 4</h2>



<div>
<div>Stwórz klasę Gracz dla gry RPG, która będzie miała:</div>
<div>&#8211; Atrybuty: nick, poziom, hp (punkty życia), exp (doświadczenie)</div>
<div>&#8211; Metody:</div>
<div>&nbsp; * atak() &#8211; wyświetla &#8222;Gracz {nick} atakuje!&#8221;</div>
<div>&nbsp; * otrzymaj_obrazenia(ilosc) &#8211; zmniejsza hp</div>
<div>&nbsp; * zdobadz_exp(ilosc) &#8211; dodaje exp, jeśli exp &gt;= 100, zwiększa poziom</div>
<div>&nbsp; * __str__() &#8211; wyświetla statystyki gracza</div>
<br />
<div>Stwórz dwóch graczy i przeprowadź między nimi walkę.</div>
</div>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;">print("\n\n" + "=" * 60)
print("ZADANIE 4 - GRACZ W GRZE RPG")
print("=" * 60)
print("""
Stwórz klasę Gracz dla gry RPG, która będzie miała:
- Atrybuty: nick, poziom, hp (punkty życia), exp (doświadczenie)
- Metody:
  * atak() - wyświetla "Gracz {nick} atakuje!"
  * otrzymaj_obrazenia(ilosc) - zmniejsza hp
  * zdobadz_exp(ilosc) - dodaje exp, jeśli exp &gt;= 100, zwiększa poziom
  * __str__() - wyświetla statystyki gracza

Stwórz dwóch graczy i przeprowadź między nimi walkę.
""")

class Gracz:
    def __init__(self, nick):
        self.nick = nick
        self.poziom = 1
        self.hp = 100
        self.exp = 0
        self.max_hp = 100
    
    def atak(self, cel):
        """Metoda ataku na przeciwnika"""
        obrazenia = random.randint(10, 25) + (self.poziom * 5)
        print(f"{self.nick} atakuje {cel.nick} zadając {obrazenia} obrażeń!")
        cel.otrzymaj_obrazenia(obrazenia)
        self.zdobadz_exp(20)
        return obrazenia
    
    def otrzymaj_obrazenia(self, ilosc):
        """Otrzymywanie obrażeń"""
        self.hp -= ilosc
        if self.hp &lt; 0:
            self.hp = 0
        print(f"{self.nick} ma teraz {self.hp}/{self.max_hp} HP")
    
    def zdobadz_exp(self, ilosc):
        """Zdobywanie doświadczenia i awans na poziom"""
        self.exp += ilosc
        if self.exp &gt;= 100:
            self.poziom_w_gore()
    
    def poziom_w_gore(self):
        """Awans na wyższy poziom"""
        self.exp = 0
        self.poziom += 1
        self.max_hp += 20
        self.hp = self.max_hp
        print(f"{self.nick} awansował na poziom {self.poziom}!")
    
    def czy_zyje(self):
        """Sprawdzenie czy gracz żyje"""
        return self.hp &gt; 0
    
    def __str__(self):
        return f"{self.nick} | Poziom: {self.poziom} | HP: {self.hp}/{self.max_hp} | EXP: {self.exp}/100"


# Rozwiązanie - walka graczy
print("\n--- POCZĄTEK WALKI ---\n")
gracz1 = Gracz("DragonSlayer")
gracz2 = Gracz("NinjaWarrior")

print(gracz1)
print(gracz2)
print()

runda = 1
while gracz1.czy_zyje() and gracz2.czy_zyje():
    print(f"\n--- RUNDA {runda} ---")
    gracz1.atak(gracz2)
    
    if gracz2.czy_zyje():
        gracz2.atak(gracz1)
    
    runda += 1
    
    if runda &gt; 10:  # Zabezpieczenie przed nieskończoną pętlą
        print("\nWalka trwa zbyt długo - remis!")
        break

if not gracz1.czy_zyje():
    print(f"\n{gracz2.nick} WYGRYWA!")
elif not gracz2.czy_zyje():
    print(f"\n{gracz1.nick} WYGRYWA!")

print("\n--- KOŃCOWE STATYSTYKI ---")
print(gracz1)
print(gracz2)</code></pre>



<h2 class="wp-block-heading">Zadanie 5</h2>



<div>
<div>Stwórz system zarządzania playlistami:</div>
<div>&#8211; Klasa Utwor: tytuł, wykonawca, czas_trwania (w sekundach)</div>
<div>&#8211; Klasa Playlista: nazwa, lista utworów</div>
<div>  * dodaj_utwor(utwor)</div>
<div>  * usun_utwor(tytul)</div>
<div>  * calkowity_czas() &#8211; suma czasu wszystkich utworów</div>
<div>  * najdluzszy_utwor() &#8211; zwraca najdłuższy utwór</div>
<div>  * __str__() &#8211; ładne wyświetlenie playlisty</div>
<br />
<div>Stwórz playlistę z kilkoma utworami i przetestuj wszystkie metody.</div>
</div>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;">print("\n\n" + "=" * 60)
print("ZADANIE 5 - SPOTIFY - PLAYLISTA MUZYCZNA")
print("=" * 60)
print("""
Stwórz system zarządzania playlistami:
- Klasa Utwor: tytuł, wykonawca, czas_trwania (w sekundach)
- Klasa Playlista: nazwa, lista utworów
  * dodaj_utwor(utwor)
  * usun_utwor(tytul)
  * calkowity_czas() - suma czasu wszystkich utworów
  * najdluzszy_utwor() - zwraca najdłuższy utwór
  * __str__() - ładne wyświetlenie playlisty

Stwórz playlistę z kilkoma utworami i przetestuj wszystkie metody.
""")

class Utwor:
    def __init__(self, tytul, wykonawca, czas_trwania):
        self.tytul = tytul
        self.wykonawca = wykonawca
        self.czas_trwania = czas_trwania  # w sekundach
    
    def formatuj_czas(self):
        """Formatuje czas z sekund na MM:SS"""
        minuty = self.czas_trwania // 60
        sekundy = self.czas_trwania % 60
        return f"{minuty}:{sekundy:02d}"
    
    def __str__(self):
        return f"{self.tytul} - {self.wykonawca} &#91;{self.formatuj_czas()}]"
    
    def __eq__(self, other):
        """Porównywanie utworów po tytule"""
        if isinstance(other, Utwor):
            return self.tytul == other.tytul
        return False


class Playlista:
    def __init__(self, nazwa):
        self.nazwa = nazwa
        self.utwory = &#91;]
    
    def dodaj_utwor(self, utwor):
        """Dodaje utwór do playlisty"""
        self.utwory.append(utwor)
        print(f"✓ Dodano: {utwor.tytul}")
    
    def usun_utwor(self, tytul):
        """Usuwa utwór o podanym tytule"""
        for utwor in self.utwory:
            if utwor.tytul == tytul:
                self.utwory.remove(utwor)
                print(f"✓ Usunięto: {tytul}")
                return True
        print(f"✗ Nie znaleziono utworu: {tytul}")
        return False
    
    def calkowity_czas(self):
        """Zwraca całkowity czas trwania playlisty"""
        return sum(utwor.czas_trwania for utwor in self.utwory)
    
    def formatuj_calkowity_czas(self):
        """Formatuje całkowity czas na HH:MM:SS"""
        total = self.calkowity_czas()
        godziny = total // 3600
        minuty = (total % 3600) // 60
        sekundy = total % 60
        return f"{godziny}:{minuty:02d}:{sekundy:02d}"
    
    def najdluzszy_utwor(self):
        """Zwraca najdłuższy utwór z playlisty"""
        if not self.utwory:
            return None
        return max(self.utwory, key=lambda u: u.czas_trwania)
    
    def __len__(self):
        """Zwraca liczbę utworów"""
        return len(self.utwory)
    
    def __str__(self):
        naglowek = f"\nPLAYLISTA: {self.nazwa}"
        naglowek += f"\n{'=' * 50}"
        naglowek += f"\nLiczba utworów: {len(self)}"
        naglowek += f"\nCałkowity czas: {self.formatuj_calkowity_czas()}"
        naglowek += f"\n{'-' * 50}"
        
        utwory_str = "\n".join(f"{i+1}. {utwor}" for i, utwor in enumerate(self.utwory))
        
        return f"{naglowek}\n{utwory_str if utwory_str else 'Brak utworów'}\n{'=' * 50}"


# Rozwiązanie
print("\n--- TWORZENIE PLAYLISTY ---\n")
moja_playlista = Playlista("Moje Ulubione 2024")

# Dodawanie utworów
utwor1 = Utwor("Bohemian Rhapsody", "Queen", 354)
utwor2 = Utwor("Stairway to Heaven", "Led Zeppelin", 482)
utwor3 = Utwor("Hotel California", "Eagles", 391)
utwor4 = Utwor("Imagine", "John Lennon", 183)
utwor5 = Utwor("Smells Like Teen Spirit", "Nirvana", 301)

moja_playlista.dodaj_utwor(utwor1)
moja_playlista.dodaj_utwor(utwor2)
moja_playlista.dodaj_utwor(utwor3)
moja_playlista.dodaj_utwor(utwor4)
moja_playlista.dodaj_utwor(utwor5)

# Wyświetlanie playlisty
print(moja_playlista)

# Najdłuższy utwór
print(f"\nNajdłuższy utwór: {moja_playlista.najdluzszy_utwor()}")

# Usuwanie utworu
print("\n--- USUWANIE UTWORU ---\n")
moja_playlista.usun_utwor("Imagine")
print(moja_playlista)</code></pre>



<h2 class="wp-block-heading">Zadanie 6</h2>



<div>
<div>Stwórz system bankowy z klasami:</div>
<div>&#8211; Klasa KontoBankowe: właściciel, saldo, historia_transakcji</div>
<div>  * wplata(kwota)</div>
<div>  * wyplata(kwota) &#8211; sprawdza czy jest wystarczający balans</div>
<div>  * przelew(kwota, konto_docelowe)</div>
<div>  * pokaz_historie() &#8211; wyświetla ostatnie 5 transakcji</div>
<div>  * __str__() &#8211; informacje o koncie</div>
<br />
<div>Stwórz kilka kont i przeprowadź między nimi transakcje.</div>
</div>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;">print("\n\n" + "=" * 60)
print("ZADANIE 6 - KONTO BANKOWE")
print("=" * 60)
print("""
Stwórz system bankowy z klasami:
- Klasa KontoBankowe: właściciel, saldo, historia_transakcji
  * wplata(kwota)
  * wyplata(kwota) - sprawdza czy jest wystarczający balans
  * przelew(kwota, konto_docelowe)
  * pokaz_historie() - wyświetla ostatnie 5 transakcji
  * __str__() - informacje o koncie

Stwórz kilka kont i przeprowadź między nimi transakcje.
""")

from datetime import datetime

class KontoBankowe:
    def __init__(self, wlasciciel, saldo_poczatkowe=0):
        self.wlasciciel = wlasciciel
        self.saldo = saldo_poczatkowe
        self.historia_transakcji = &#91;]
        self.numer_konta = f"{random.randint(1000, 9999)}-{random.randint(1000, 9999)}"
        
        if saldo_poczatkowe > 0:
            self._dodaj_do_historii("Wpłata początkowa", saldo_poczatkowe, "wpłata")
    
    def _dodaj_do_historii(self, opis, kwota, typ):
        """Prywatna metoda dodająca transakcję do historii"""
        transakcja = {
            "data": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "opis": opis,
            "kwota": kwota,
            "typ": typ,
            "saldo_po": self.saldo
        }
        self.historia_transakcji.append(transakcja)
    
    def wplata(self, kwota):
        """Wpłata środków na konto"""
        if kwota &lt;= 0:
            print("Kwota wpłaty musi być dodatnia!")
            return False
        
        self.saldo += kwota
        self._dodaj_do_historii(f"Wpłata gotówki", kwota, "wpłata")
        print(f"✓ Wpłacono {kwota} zł. Nowe saldo: {self.saldo} zł")
        return True
    
    def wyplata(self, kwota):
        """Wypłata środków z konta"""
        if kwota &lt;= 0:
            print("Kwota wypłaty musi być dodatnia!")
            return False
        
        if self.saldo &lt; kwota:
            print(f"Brak wystarczających środków! (saldo: {self.saldo} zł)")
            return False
        
        self.saldo -= kwota
        self._dodaj_do_historii(f"Wypłata gotówki", -kwota, "wypłata")
        print(f"✓ Wypłacono {kwota} zł. Nowe saldo: {self.saldo} zł")
        return True
    
    def przelew(self, kwota, konto_docelowe):
        """Przelew środków na inne konto"""
        if kwota &lt;= 0:
            print("Kwota przelewu musi być dodatnia!")
            return False
        
        if self.saldo &lt; kwota:
            print(f"Brak wystarczających środków! (saldo: {self.saldo} zł)")
            return False
        
        self.saldo -= kwota
        konto_docelowe.saldo += kwota
        
        self._dodaj_do_historii(
            f"Przelew do {konto_docelowe.wlasciciel}", 
            -kwota, 
            "przelew wychodzący"
        )
        konto_docelowe._dodaj_do_historii(
            f"Przelew od {self.wlasciciel}", 
            kwota, 
            "przelew przychodzący"
        )
        
        print(f"✓ Przelano {kwota} zł do {konto_docelowe.wlasciciel}")
        print(f"  Twoje nowe saldo: {self.saldo} zł")
        return True
    
    def pokaz_historie(self, ostatnie=5):
        """Wyświetla historię transakcji"""
        print(f"\nHistoria transakcji - {self.wlasciciel}")
        print("=" * 70)
        
        if not self.historia_transakcji:
            print("Brak transakcji")
            return
        
        transakcje = self.historia_transakcji&#91;-ostatnie:]
        
        for t in transakcje:
            symbol = "+" if t&#91;'kwota'] > 0 else "-"
            print(f"{t&#91;'data']} | {symbol} {abs(t&#91;'kwota']):>7.2f} zł | {t&#91;'opis']:&lt;30} | Saldo: {t&#91;'saldo_po']:.2f} zł")
        
        print("=" * 70)
    
    def __str__(self):
        return f"Konto: {self.numer_konta} | Właściciel: {self.wlasciciel} | Saldo: {self.saldo:.2f} zł"


# Rozwiązanie
print("\n--- TWORZENIE KONT BANKOWYCH ---\n")
konto1 = KontoBankowe("Jan Kowalski", 1000)
konto2 = KontoBankowe("Anna Nowak", 500)
konto3 = KontoBankowe("Piotr Wiśniewski", 2000)

print(konto1)
print(konto2)
print(konto3)

print("\n--- OPERACJE BANKOWE ---\n")
konto1.wplata(500)
konto1.wyplata(200)
konto1.przelew(300, konto2)
konto2.wyplata(100)
konto3.przelew(500, konto1)

print("\n--- HISTORIA TRANSAKCJI ---")
konto1.pokaz_historie()
konto2.pokaz_historie()</code></pre>



<h2 class="wp-block-heading">Zadanie 7</h2>



<div>
<div>Stwórz system biblioteki:</div>
<div>&#8211; Klasa Ksiazka: tytul, autor, rok_wydania, wypozyczona (bool)</div>
<div>&#8211; Klasa Biblioteka: nazwa, lista książek</div>
<div>  * dodaj_ksiazke(ksiazka)</div>
<div>  * wypozycz(tytul) &#8211; zmienia status książki</div>
<div>  * zwroc(tytul) &#8211; zmienia status z powrotem</div>
<div>  * dostepne_ksiazki() &#8211; zwraca listę dostępnych książek</div>
<div>  * wyszukaj_po_autorze(autor) &#8211; zwraca książki autora</div>
<div>  * __len__() &#8211; liczba książek w bibliotece</div>
<br />
<div>Stwórz bibliotekę, dodaj książki i przetestuj wypożyczenia.</div>
</div>



<pre class="wp-block-code prettyprint"><code class="prettyprint lang-sql" style="font-size: 0.85em;">print("\n\n" + "=" * 60)
print("ZADANIE 7 - BIBLIOTEKA KSIĄŻEK")
print("=" * 60)
print("""
Stwórz system biblioteki:
- Klasa Ksiazka: tytul, autor, rok_wydania, wypozyczona (bool)
- Klasa Biblioteka: nazwa, lista książek
  * dodaj_ksiazke(ksiazka)
  * wypozycz(tytul) - zmienia status książki
  * zwroc(tytul) - zmienia status z powrotem
  * dostepne_ksiazki() - zwraca listę dostępnych książek
  * wyszukaj_po_autorze(autor) - zwraca książki autora
  * __len__() - liczba książek w bibliotece

Stwórz bibliotekę, dodaj książki i przetestuj wypożyczenia.
""")

class Ksiazka:
    def __init__(self, tytul, autor, rok_wydania):
        self.tytul = tytul
        self.autor = autor
        self.rok_wydania = rok_wydania
        self.wypozyczona = False
    
    def wypozycz(self):
        """Wypożycza książkę"""
        if self.wypozyczona:
            return False
        self.wypozyczona = True
        return True
    
    def zwroc(self):
        """Zwraca książkę"""
        if not self.wypozyczona:
            return False
        self.wypozyczona = False
        return True
    
    def __str__(self):
        status = "WYPOŻYCZONA" if self.wypozyczona else "DOSTĘPNA"
        return f'"{self.tytul}" - {self.autor} ({self.rok_wydania}) &#91;{status}]'
    
    def __eq__(self, other):
        if isinstance(other, Ksiazka):
            return self.tytul == other.tytul and self.autor == other.autor
        return False


class Biblioteka:
    def __init__(self, nazwa):
        self.nazwa = nazwa
        self.ksiazki = &#91;]
    
    def dodaj_ksiazke(self, ksiazka):
        """Dodaje książkę do biblioteki"""
        self.ksiazki.append(ksiazka)
        print(f"Dodano książkę: {ksiazka.tytul}")
    
    def wypozycz(self, tytul):
        """Wypożycza książkę o podanym tytule"""
        for ksiazka in self.ksiazki:
            if ksiazka.tytul.lower() == tytul.lower():
                if ksiazka.wypozycz():
                    print(f"Wypożyczono: {ksiazka.tytul}")
                    return True
                else:
                    print(f"Książka '{ksiazka.tytul}' jest już wypożyczona")
                    return False
        print(f"Nie znaleziono książki: {tytul}")
        return False
    
    def zwroc(self, tytul):
        """Zwraca książkę o podanym tytule"""
        for ksiazka in self.ksiazki:
            if ksiazka.tytul.lower() == tytul.lower():
                if ksiazka.zwroc():
                    print(f"Zwrócono: {ksiazka.tytul}")
                    return True
                else:
                    print(f"Książka '{ksiazka.tytul}' nie była wypożyczona")
                    return False
        print(f"Nie znaleziono książki: {tytul}")
        return False
    
    def dostepne_ksiazki(self):
        """Zwraca listę dostępnych książek"""
        return &#91;k for k in self.ksiazki if not k.wypozyczona]
    
    def wypozyczone_ksiazki(self):
        """Zwraca listę wypożyczonych książek"""
        return &#91;k for k in self.ksiazki if k.wypozyczona]
    
    def wyszukaj_po_autorze(self, autor):
        """Zwraca książki danego autora"""
        return &#91;k for k in self.ksiazki if autor.lower() in k.autor.lower()]
    
    def __len__(self):
        """Zwraca liczbę książek w bibliotece"""
        return len(self.ksiazki)
    
    def __str__(self):
        naglowek = f"\nBIBLIOTEKA: {self.nazwa}"
        naglowek += f"\n{'=' * 70}"
        naglowek += f"\nLiczba książek: {len(self)}"
        naglowek += f"\nDostępne: {len(self.dostepne_ksiazki())} | Wypożyczone: {len(self.wypozyczone_ksiazki())}"
        naglowek += f"\n{'-' * 70}"
        
        ksiazki_str = "\n".join(str(k) for k in self.ksiazki)
        
        return f"{naglowek}\n{ksiazki_str}\n{'=' * 70}"


# Rozwiązanie
print("\n--- TWORZENIE BIBLIOTEKI ---\n")
biblioteka = Biblioteka("Miejska Biblioteka Publiczna")

# Dodawanie książek
ksiazka1 = Ksiazka("Wiedźmin", "Andrzej Sapkowski", 1990)
ksiazka2 = Ksiazka("Pan Tadeusz", "Adam Mickiewicz", 1834)
ksiazka3 = Ksiazka("Solaris", "Stanisław Lem", 1961)
ksiazka4 = Ksiazka("Lalka", "Bolesław Prus", 1890)
ksiazka5 = Ksiazka("Miecz przeznaczenia", "Andrzej Sapkowski", 1992)

biblioteka.dodaj_ksiazke(ksiazka1)
biblioteka.dodaj_ksiazke(ksiazka2)
biblioteka.dodaj_ksiazke(ksiazka3)
biblioteka.dodaj_ksiazke(ksiazka4)
biblioteka.dodaj_ksiazke(ksiazka5)

print(biblioteka)

print("\n--- WYPOŻYCZENIA ---\n")
biblioteka.wypozycz("Wiedźmin")
biblioteka.wypozycz("Solaris")
biblioteka.wypozycz("Solaris")  # Próba wypożyczenia ponownie

print(biblioteka)

print("\n--- WYSZUKIWANIE PO AUTORZE ---\n")
sapkowski_ksiazki = biblioteka.wyszukaj_po_autorze("Sapkowski")
print(f"Znaleziono {len(sapkowski_ksiazki)} książek Sapkowskiego:")
for ksiazka in sapkowski_ksiazki:
    print(f"  {ksiazka}")

print("\n--- ZWROT KSIĄŻEK ---\n")
biblioteka.zwroc("Wiedźmin")

print(biblioteka)</code></pre>



<h2 class="wp-block-heading">Zadanie 8</h2>



<div>
<div>Stwórz prosty sklep internetowy:</div>
<div>&#8211; Klasa Produkt: nazwa, cena, ilosc_w_magazynie</div>
<div>&#8211; Klasa KoszykZakupowy:</div>
<div>  * dodaj_produkt(produkt, ilosc)</div>
<div>  * usun_produkt(nazwa_produktu)</div>
<div>  * oblicz_wartosc() &#8211; suma wartości wszystkich produktów</div>
<div>  * wyswietl_koszyk()</div>
<div>  * zrealizuj_zamowienie() &#8211; zmniejsza stan magazynowy</div>
<br />
<div>Stwórz kilka produktów, dodaj je do koszyka i zrealizuj zamówienie.</div>
</div>


<p>Artykuł <a href="https://kamakaczmarek.net/13-python-obiektowo/">13. Python &#8211; obiektowo</a> pochodzi z serwisu <a href="https://kamakaczmarek.net">Kama Kaczmarek</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>14. JAVA &#8211; obiektowo</title>
		<link>https://kamakaczmarek.net/14-java-obiektowo/</link>
		
		<dc:creator><![CDATA[Kama]]></dc:creator>
		<pubDate>Mon, 11 Oct 2021 08:27:34 +0000</pubDate>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[obiekty]]></category>
		<guid isPermaLink="false">https://kamakaczmarek.net/?p=3262</guid>

					<description><![CDATA[<p>Programowanie obiektowe – OOP (object-oriented programming) – pozwala na przedstawienie rzeczywistości i relacji w niej zachodzących za pomocą obiektów.   Klasa i obiekt Kiedy mówimy o klasie musimy wyobrazić ją sobie jak ogólny zarys/opis jakiegoś obiektu, zbiór cech wspólnych dla np. człowieka. Gdybyśmy mieli klasę człowiek moglibyśmy określić ogólne cechy jakie definiują ludzi, czyli np. [&#8230;]</p>
<p>Artykuł <a href="https://kamakaczmarek.net/14-java-obiektowo/">14. JAVA &#8211; obiektowo</a> pochodzi z serwisu <a href="https://kamakaczmarek.net">Kama Kaczmarek</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Programowanie obiektowe – OOP (object-oriented programming) – pozwala na przedstawienie rzeczywistości i relacji w niej zachodzących za pomocą obiektów.</p>
<p> </p>
<h2>Klasa i obiekt</h2>
<p>Kiedy mówimy o klasie musimy wyobrazić ją sobie jak ogólny zarys/opis jakiegoś obiektu, zbiór cech wspólnych dla np. człowieka. Gdybyśmy mieli klasę człowiek moglibyśmy określić ogólne cechy jakie definiują ludzi, czyli np. to że śpi, że ma głos, oczy, włosy, ręce, nogi itd.<br /><br />Obiekt jest instancją danej klasy, czyli konkretnym człowiekiem np. Janem Kowalskim, który ma brązowe włosy, jest typem „skowronka” i ma niebieskie oczy. Te cechy nie są bezpośrednio związane z klasą, a z obiektem (instancją/wystąpieniem klasy). <br />Można powiedzieć, że Jan Kowalski jest zmienną typu klasy, czyli obiektem typu człowiek.<br /><br />W Javie istnieje wiele &#8222;gotowych&#8221; klas, z których możemy korzystać. Zawierają one konkretne własności oraz metody. Poznaliście już klasę String, Integer i inne.</p>
<p>Już wiecie mniej więcej co to jest obiekt i klasa. Rozszerzając te zagadnienia możemy powiedzieć, że klasa jest schematem na bazie którego będziemy tworzyli obiekty np. mając projekt domu, możemy na jego podstawie stworzyć wiele podobnych do siebie domów.<br />Klasy możecie Tworzyć samodzielnie, mogą one zawierać zdefiniowane wartości i metody lub wykorzystywać wartości przekazane przez użytkownika.<br />Podsumowując &#8211; za pomocą jednej klasy możemy utworzyć wiele obiektów, czyli instancji naszej klasy, które będą niezależne od siebie.<br /><br />Należy zapamiętać, że dobrą praktyką jest tworzenie nowej klasy w oddzielnym pliku.</p>
<h3>Przykład:</h3>
<p>Stwórzmy nowy plik/klasę o nazwie Person ustawimy w niej, że nasze obiekty będą miały imię i wiek:</p>
<p><strong>plik Person.java</strong></p>
<pre>public class Person1 {<br />    String name;<br />    int age;<br />}</pre>
<p><strong>plik ObjectsAndClasses .java</strong></p>
<pre>public class ObjectsAndClasses {<br />    public static void main(String[] args) {<br /><br />        //tworzymy nową osobę<br />        Person osoba1 = new Person();<br />        osoba1.name = "Jan"; //ustawiamy imię<br />        osoba1.age = 18; //ustawiamy wiek<br /><br />        //tworzymy jeszcze jedną osobę<br />        Person osoba2 = new Person();<br />        osoba2.name = "Anna"; //ustawiamy imię<br />        osoba2.age = 22; //ustawiamy wiek<br /><br />        System.out.println(osoba1.name + " ma " + osoba1.age + " lat.");<br />        System.out.println(osoba2.name + " ma " + osoba2.age + " lat.");<br />    }<br />}</pre>
<p> </p>
<h3>Przykład:</h3>
<p>Stworzymy nowy obiekt wykorzystując klasę JFrame (należy zaimportować javax.swing.* na samej górze skryptu), dzięki której wywołamy okienko systemowe, czyli utworzymy instancję klasy.</p>
<pre>public class UsingObjects {<br />    public static void main(String[] args) {<br /><br />        JFrame window = new JFrame();<br />        //podajemy nazwę typu/klasy + wymyślona nazwa = słówko "new" i nazwa klasy + ()<br /><br />        //teraz nadamy rozmiar okienka<br />        //po wpisaniu nazwy zmiennej i postawieniu "." pokaże nam się lista dostępnych opcji<br />        window.setSize(600,600);<br /><br />        //ustawimy tytuł<br />        window.setTitle("Moje pierwsze okienko");<br /><br />        window.setVisible(true); // ustawiamy widoczność okienka na true<br />        //po uruchomieniu programu pokaże się małe okienko systemowe</pre>
<p> </p>
<h2>Metody</h2>
<p>Klasa może definiować metody, czyli nic innego jak funkcje z podejścia proceduralnego. Kiedy tworzymy obiekt nadajemy mu dostęp do metod danej klasy.</p>
<p>Możemy rozszerzyć powyższy przykład z osobą lub utworzyć nową klasę:</p>
<p>plik Person2.java:</p>
<pre>import java.util.*; //import do metody określającej rok urodzenia<br /><br />public class Person2 {<br />    String name;<br />    int age;<br /><br />    //w Java istnieją tzw. gettery i settery, czyli metody pobierające lub ustawiające wartość, co do ich stosowania zdania są podzielone;<br />    //możemy zaimplementować je w Intellij automatycznie lub napisać samodzielnie<br />    //automatycznie: PPM -&gt; Generate... (u mnie skrót Alt+G) -&gt; Getter and Setter...<br /><br />    public String getName() {<br />        return name;<br />    }<br /><br />    public void setName(String name) {<br />        this.name = name; //słówko this pozwala dostać się do pola w obiekcie, nie musimy go używać jeżeli nazwy argumentów i zmiennych się różnią<br />    }<br /><br />    public int getAge() {<br />        return age;<br />    }<br /><br />    public void setAge(int age) {<br />        this.age = age;<br />    }<br /><br /><br /><br />    //METODY<br />    //ustawimy metodę, która wygeneruje powitanie<br />    public void sayHello(){<br />        System.out.println("Hello new Person! " + name);<br />    }<br /><br />    //stworzymy metodę określającą rok urodzenia<br />    public void birthYear(){<br />        Calendar data = Calendar.getInstance();<br />        int by = data.get(Calendar.YEAR) - age;<br />        System.out.println("Rok urodzenia to:" + by);<br />        /*<br />        musimy zwrócić uwagę na to, że tak skonstruowana metoda nic nam nie zwraca.<br />        To oznacza, że nie otrzymamy fizycznie wartości, którą możemy wykorzystać gdzieś indziej, otrzymamy jedynie wyświetlony napis. Jeżeli chcemy uzyskać wartość musimy ją zwrócić używając słówka return.<br />         */<br />    }<br /><br />    public int yearsToRetirement(){<br />        return 65 - age;<br />    }<br /><br />    /*<br />    Pamiętamy z tematu JAVA – instrukcje sterujące, pętle i funkcje(metody), że metody mogą przyjmować argumenty. Czyli możemy przekazać bezpośrednio wartość przy wywołaniu metody<br />     */<br />    public void speak(String text){<br />        System.out.println(text);<br />    }<br /><br />    public void move(String direction, double distance){<br />        System.out.println("Hurra, poszedłem " + direction + ", " + distance + " metrów");<br />    }<br /><br />    //przeładujemy metodę<br />    public void speak(String text, int words){<br />        System.out.println(text + words + " wyrazy");<br />    }<br />}<br /><br /></pre>
<p><strong>plik Methods.java</strong></p>
<pre>package tutaj.nazwa.waszego.pakietu;<br /><br />public class Methods {<br />    public static void main(String[] args) {<br />        /*<br />        Klasa może definiować metody, czyli nic innego jak funkcje z podejścia proceduralnego. Kiedy tworzymy obiekt nadajemy mu dostęp do metod danej klasy.<br />         */<br />        Person2 osoba2_1 = new Person2();<br /><br />        /* tak ustawiamy dane bez getterów i setterów*/<br />        osoba2_1.name = "Ania"; //ustawiamy imię<br />        osoba2_1.age = 10; //ustawiamy wiek<br />        osoba2_1.sayHello(); //wyświetli: Hello new Person! Ania<br />        System.out.println(osoba2_1.name + " ma " + osoba2_1.age + " lat."); //wyświetli: Ania ma 10 lat.<br /><br />        //wykorzystanie getterów i setterów do ustawiania wartości danych<br />        Person2 osoba2_2 = new Person2();<br /><br />        osoba2_2.setName("Jan");<br />        osoba2_2.setAge(18);<br />        osoba2_2.sayHello(); //wyświetli: Hello new Person! Jan<br />        System.out.println(osoba2_2.getName() + " ma " + osoba2_2.getAge() + " lat."); //wyświetli: Jan ma 18 lat.<br /><br /><br />        //wywołujemy metodę sprawdzającą rok urodzenia<br />        //ona tylko wyświetla napis<br />        if (osoba2_1.age &gt; 0) osoba2_1.birthYear();<br /><br />        //wywołujemy metodę zwracającą lata do emerytury<br />        int yl = osoba2_1.yearsToRetirement();<br />        System.out.println("Do emerytury pozostało: " + yl + " lat");<br /><br />        //wywołujemy metodę z 1 argumentem<br />        osoba2_1.speak("Cześć, nauczyłem się mówić :)");<br /><br />        //wywołujemy metodę z 2 argumentami<br />        osoba2_1.move("prosto", 5);<br /><br />        //wywołujemy przeładowaną metodę<br />        osoba2_1.speak("Wypowiedziałam dzisiaj ", 2);<br /><br />        //argumenty do metody mogą być przekazywane przez zmienne<br />        String hello = "Hello everybody";<br />        osoba2_1.speak(hello);<br /><br />    }<br />}</pre>
<p> </p>
<h2>Konstruktory</h2>
<p>Konstruktory, to metody wywoływane automatycznie w momencie tworzenia obiektu i nie wymagają dodatkowych akcji. Metody te występują tylko w kontekście klas, a ich nazwy są takie same jak nazwa klasy głównej.<br /><br />Dzięki konstruktorowi możemy przesłać określone wartości do obiektu w momencie jego tworzenia.</p>
<p> </p>
<p><strong>plik Person3.java</strong></p>
<pre>public class Person3 {<br />    String name;<br />    int age;<br /><br />    //tworzymy konstruktor bezargumentowy<br />    public Person3() {<br />        System.out.println("Obiekt klasy Person3 storzony - to ja, konstruktor bezargumentowy");<br />    }<br /><br />    //konstruktor przyjmujący 1 argumant: imię lub wiek<br />    public Person3(String name) {<br />        this.name = name; //aby zmodyfikować konkretną zmienną w obiekcie możemy użyć słówka "this", ale tylko w sytuacji kiedy argument i zmienna mają takie same nazwy<br />    }<br /><br />    //konstruktor przyjmujący 2 argumenty<br />    public Person3(String name, int age) {<br />        this.name = name;<br />        this.age = age;<br />    }<br />    /*<br />    możemy wewnątrz konstruktora wywołać inny konstruktor<br />    nie używamy wywołania np: Person("Ania",13), tylko zamiast nazwy konstruktora używamy "this"<br />    np: this("Ania",13)<br />     */<br />}</pre>
<p><strong>plik Constructors.java</strong></p>
<pre>public class Constructors {<br />    public static void main(String[] args) {<br /><br />        //tworzymy obiekt klasy Person3<br />        Person3 osoba3_1 = new Person3();<br />        /*<br />        wywoła się konstruktor bezargumentowy, bo w nawiasie nie podaliśmy danych<br />        po uruchomieniu skryptu otrzymamy napis:<br />        Obiekt klasy Person3 stworzony - to ja, konstruktor bezargumentowy<br />        został wywołany konstruktor w momencie tworzenia obiektu<br />        */<br /><br />        /*<br />        możemy tworzyć wiele konstruktorów, rozróżniając je ilością przekazywanych argumentów<br />        */<br /><br />        //tworzymy obiekt przekazując 1 argument - uruchomi się konstruktor z 1 argumentem<br />        Person3 osoba3_2 = new Person3("Kama");<br />        System.out.println("Przypisano imię " + osoba3_2.name);<br /><br />        //tworzymy obiekt przekazując 2 argumenty - uruchomi się konstruktor z 2 argumentami<br />        Person3 osoba3_3 = new Person3("Anna", 22);<br />        System.out.println("Przypisano imię " + osoba3_3.name + " oraz wiek = " + osoba3_3.age);<br />    }<br />}</pre>
<p> </p>
<h2>Modyfikatory dostępu</h2>
<p>Do tej pory wykonywaliśmy przykłady w oparciu o publiczną dostępność danego elementu, czyli public.<br />Taka metoda lub właściwość jest publiczna, więc widoczna wszędzie wewnątrz obiektu i poza nim.<br />Dostęp do pola jest nieograniczony i można je odczytywać i zmieniać dowolnie.<br /><br />Właściwość lub metoda może być prywatna, czyli private, wówczas może zostać użyta tylko wewnątrz obiektu.<br /><br />Właściwość lub metoda protected może być użyta tylko wewnątrz obiektu, package, ale może być również dziedziczona.<br /><br />Metoda domyślna &#8211; może być dostępna tylko wewnątrz tego package<br /><br />Zaleca się w programowaniu i w życiu, nie udostępniać zbyt wiele informacji na zewnątrz, więc tego się trzymajmy – korzystamy z modyfikatorów private.<br /><br />Kolejność restrykcji:<br />&#8211; private<br />&#8211; default<br />&#8211; protected<br />&#8211; public<br /><br />np.<br />public void doSomethingPublic(){}<br />private void doSomethingPrivate(){}<br />protected void doSomethingProtected(){}<br />void doSomething(){}<br /><br />I tutaj pojawia się pojęcie <span style="text-decoration: underline;"><strong>enkapsulacji</strong></span>, czyli hermetyzacji, która polega na zgrupowaniu danych i metod w obrębie jednej jednostki np. klasy.<br />Enkapsulacja pozwala również na ograniczenie dostepu do danych.</p>
<p><strong>plik AccessModifiers.java</strong></p>
<pre>public class AccessModifiers {<br />    public static void main(String[] args) {<br />        //ustawiamy prywatne zmienne za pomocą setterów<br />        Frog frog1 = new Frog();<br />        frog1.setName("Bella");<br />        frog1.setAge(2);<br />        System.out.println("Żabcia " + frog1.getName() + " ma lat " + frog1.getAge());<br />    }<br />}</pre>
<p><strong>plik Frog.java</strong></p>
<pre>public class Frog {<br />    private String name;<br />    private int age;<br /><br />    //jeżeli modyfikatory zmiennych będą private, nie będziemy mogli ich zmienić poza klasą,<br />    //jedyne co możemy zrobić to skorzystać z setterów<br />    public void setName(String name) {<br />        this.name = name;<br />    }<br /><br />    public void setAge(int age) {<br />        this.age = age;<br />    }<br /><br />    public String getName() {<br />        return name;<br />    }<br /><br />    public int getAge() {<br />        return age;<br />    }<br />}</pre>
<p> </p>
<h2>Static i Final</h2>
<p>Czasami istnieje potrzeba stworzenia zmiennej lub metody statycznej, czyli takiej, która nie jest przypisana do obiektu, a jedynie do klasy i może być wykorzystywana poza klasą.</p>
<p>Metody i właściwości statyczne to takie, które nie wymagają utworzenia obiektu, aby móc się do nich odwołać. Nadawane są dla całej klasy. Tworzymy je przy pomocy modyfikatora static.</p>
<p><strong>plik Static_Final.java</strong></p>
<pre>public class Static_Final {<br />    public static void main(String[] args) {<br /><br />        Thing something = new Thing();<br />        something.name = "Itit";<br />        something.showName();<br /><br />        //teraz wykorzystamy static<br />        Thing.saluton = "Jestem statycznym powitaniem niezależnym od obiektów";<br />        Thing.showInfo();<br />        /*<br />        zwróćmy uwagę, że nie tworzymy nowego obiektu, ani nie odwołujemy się do metody, czy zmiennej przez obiekt.<br />        Podajemy nazwę klasy i po krropce wywołujemy wartości statyczne.<br />         */<br /><br />        something.showNameSaluton();<br /><br />        //STAŁE<br />        System.out.println(Thing.LUCK_NR); //ta wartość jest niezmienna<br /><br />        //działanie statycznego licznika przedstawiam tutaj na dole, jednak należy pamiętać, że już 1 obiekt został stworzony wcześniej<br />        System.out.println("Stan licznika przed utworzeniem dodatkowych obiektów " + Thing.count);<br /><br />        Thing something1 = new Thing();<br />        Thing something2 = new Thing();<br />        Thing something3 = new Thing();<br />        System.out.println("Stan licznika po utworzeniu dodatkowych obiektów " + Thing.count);<br /><br /><br />    }<br />}</pre>
<p><strong>plik Thing.java</strong></p>
<pre>public class Thing {<br />    public String name; //publiczna zmienna<br />    public static String saluton; //statyczna zmienna<br /><br />    public void showName(){<br />        System.out.println(name);<br />    }<br /><br />    public void showNameSaluton(){<br />        System.out.println(saluton + " - " + name);<br />    }<br /><br />    public static void showInfo() {<br />        System.out.println(saluton);<br />        //System.out.println(name); takie odwołanie wygenerujee błąd, pamiętajmy, że to jest stałe w klasie, a obiekty przyjmują inne wartości<br />    }<br />    /*<br />     we wcześniejszych lekcjach korzystaliśmy ze stałych wbudowanych, np. liczby Pi z biblioteki Math<br />    stałą możemy stworzyć sami, wystarczy użyć słówka "final"<br />    Stała to właściwość klasy tylko do odczytu. Jak wiemy, stałe deklarujemy drukowanymi literami, są dostępne public i nie można ich modyfikować w kodzie.<br />    */<br />    public final static int LUCK_NR = 7;<br /><br /><br />    /*<br />    o ile idea istnienia stałych nikogo nie dziwi o tyle właściwości i metody statyczne już tak. Bo po co? A na przykład dla licznika utworzonych obiektów<br />     */<br />    //tworzę konstruktor, który za każdym razem, gdy zostanie utworzony nowy obiekt tej klasy doda 1 do licznika<br />    public static int count = 0;<br />    //teraz konstruktor,<br />    public Thing(){<br />        /*<br />        możemy stan licznika przy każdym obiekcie dodać do zmiennej i będziemy mieli np. id konkretnego obiektu<br />         */<br />        count++;<br />    }<br />}</pre>
<p> </p>
<h2>Dziedziczenie</h2>
<p>Inheritance, czyli dziedziczenie. Tak jak w życiu – jako potomkowie dziedziczymy po naszych przodkach pewne cechy (tak naprawdę to 50% od matki i 50% od ojca), tak samo klasy dziedziczą pola i metody, ale mogą zostać uzupełnione o inne elementy, których przodek nie posiada.<br /><br />Jeżeli klasa przodka posiada pola i metody, które nie są prywatne lub są chronione, to klasa potomna również będzie je posiadać. Aby klasa dziedziczyła po innej należy użyć słówka extends i podać nazwę klasy przodka:</p>
<pre>public class Car extends Machine{}</pre>
<p><br />Klasa może dziedziczyć tylko po jednej klasie (rozszerzać tylko jedną klasę bazową ).</p>
<p><strong>plik Machine.java</strong></p>
<pre>public class Machine {<br />    protected String type;<br /><br />    Machine(){<br />        System.out.println("Wywołanie konstruktora z klasy nadrzędnej");<br />    }<br /><br />    public void start(){<br />        System.out.println("Maschine started.");<br />    }<br />    public void stop(){<br />        System.out.println("Maschine stopped.");<br />    }<br />}</pre>
<p><strong>plik Car.java</strong></p>
<pre>/*<br />chcemy aby nasza klasa dziedziczyła wszystko po klasie Maschine<br />należy użyc słówka "extends"<br /> */<br />public class Car extends Machine{<br />    public void turn(){<br />        System.out.println("Car turned.");<br />    }<br />    //możemy nadpisać klasę dziedziczoną w klasie potomnej<br />    public void stop(){<br />        System.out.println("Car stopped.");<br />    }<br />    /*<br />    metody możemy nadpisywać automatycznie klikając (u mnie) Ctrl+o lub ALT+g lub wybierając z menu Code i "override methods"<br /><br />    @Override<br />    public void start() {<br />        super.start(); //tą część możemy wykasować i podmienić na swoją wersję<br />    }<br />    */<br /><br />    //możemy wywołać konstruktor z klasy nadrzędnej<br />    Car(){<br />        super();<br />    }<br />}</pre>
<p><strong>plik Inheritance.java</strong></p>
<pre>public class Inheritance {<br />    public static void main(String[] args) {<br /><br />        Machine machine1 = new Machine();<br />        machine1.start();<br />        machine1.stop();<br /><br />        Car car1 = new Car(); //tutaj zostanie wywołany konstruktor z klasy nadrzędnej<br />        car1.start(); //dostęp do odziedziczonej metody<br />        car1.turn(); //nowa metoda, tylko dla klasy Car, Maschine nie ma tej funkcjonalności<br />        car1.stop();//dostęp do odziedziczonej metody<br /><br />        /*<br />        jeżeli nie chcemy, aby stworzona klasa była dziedziczona na początku wpisujemy "final", np. final class Example<br />         */<br /><br />        //jeżeli zajdzie potrzeba sprawdzenia jakiej klasy instancją jest dany obiekt - oto rozwiązanie<br />        System.out.println(car1 instanceof Car); //true<br />        System.out.println(machine1 instanceof Car); //false<br />    }<br />}</pre>
<p> </p>
<h3>Przykład:</h3>
<p><strong>plik App.java</strong></p>
<pre>public class App {<br />    public static void main(String[] args) {<br />        Car auto = new Car(270.0f);<br />        auto.Info();<br />    }<br />}</pre>
<p><strong>plik Car.java</strong></p>
<pre>public class Car extends Vehicle{<br />    public Car(float topSpeed) {<br />        //wywołujemy konstruktor klasy nadrzędnej<br />        super("Auto", topSpeed);<br />    }<br />}</pre>
<p><strong>plik Vehicle.java</strong></p>
<pre>public class Vehicle {<br />    protected String type;<br />    protected float topSpeed;<br /><br />    public Vehicle(){<br />        type = "basic";<br />    }<br /><br />    public Vehicle(String type, float topSpeed) {<br />        this.type = type;<br />        this.topSpeed = topSpeed;<br />    }<br /><br />    protected void Info(){<br />        System.out.println("Typ pojazdu " + this.type + ", max szybkość " + this.topSpeed);<br />    }<br />}</pre>
<h3>Przykład:</h3>
<p><strong>plik App.java</strong></p>
<pre>public class App {<br />    public static void main(String[] args) {<br />        School t = new School(3, 316, "Technikum");<br />    }<br />}</pre>
<p><strong>plik Building.java</strong></p>
<pre>public class Building {<br />    public int numFloors;<br />    public int numClass;<br /><br />    public Building(){<br />        numFloors = 3;<br />    }<br /><br />    public Building(int numFloors, int numClass) {<br />        this.numFloors = numFloors;<br />        this.numClass = numClass;<br />        System.out.println("Budynek ma " + numFloors + " pięter oraz " + numClass + " sal lekcyjnych.");<br />    }<br />}</pre>
<p><strong>plik School.java</strong></p>
<pre>public class School extends Building{<br />    public String type = "Technikum";<br /><br />    public School(int numFloors, int numClass, String type) {<br />        super(numFloors, numClass);<br />        System.out.println("Szkoła ma " + numFloors + " pięter " + numClass + " klas i jest to " + type);<br />    }<br />}</pre>
<p> </p>
<h2>Polimorfizm</h2>
<p>Polimorfizm to możliwość przybierania różnych form w zależności od wyboru podklasy.<br />Każdy obiekt klasy dziedziczącej jest tez obiektem klasy nadrzędnej.</p>
<p><strong>plik Polymorphism.java</strong></p>
<pre>public class Polymorphism {<br />    public static void main(String[] args) {<br />        /*<br />        Polimorfizm to możliwość przybierania różnych form w zależności od wyboru podklasy<br />        Każdy obiekt klasy dziedziczącej jest tez obiektem klasy nadrzędnej.<br />         */<br /><br />        Vehicle newCar = new Car("Auto");//nie ma dostępu do maxSpeed<br />        System.out.println(newCar.name);<br /><br />        Vehicle newBicycle = new Bicycle("Rower"); //ma dostęp tylko do name<br />        System.out.println(newBicycle.name);<br /><br />        //poniższy zapis jest nieprawidłowy<br />        //Car test = new Vehicle("test");<br /><br />        //tłumacząc prościej - każde auto jest pojazdem, ale nie każdy pojaz jest autem<br />    }<br />}</pre>
<p><strong>plik Vehicle.java</strong></p>
<pre>public class Vehicle {<br />    public String name;<br /><br />    public Vehicle(String name) {<br />        this.name = name;<br />    }<br />}</pre>
<p><strong>plik Car.java</strong></p>
<pre>public class Car extends Vehicle{<br />    public int maxSpeed;<br /><br />    public Car(String name) {<br />        super(name);<br />    }<br />}</pre>
<p><strong>plik Bicycle.java</strong></p>
<pre>public class Bicycle extends Car{<br />    int numWheels;<br />    public Bicycle(String name){<br />        super(name);<br />    }<br />}</pre>
<p> </p>
<h3>Przykład:</h3>
<p><strong>plik Company.java</strong></p>
<pre>public class Company {<br />    public static void main(String[] args) {<br />        Employee employee = new Employee("Kama", "Programmer", 10000);<br />        Manager manager = new Manager("Jan", "Team Leader", 11000, "R&amp;D");<br />        Ceo ceo = new Ceo("Rafał", "Prezes", 20000, "Board", 100);<br /><br />        Employee worker = ceo; //każdy ceo jest employee i ma dostęp do metod i własności tej klasy<br />        worker.doWork();<br />        Manager person = ceo;<br />        //wpisując nazwę obiektu po kropce możemy zobaczyć dostęp do metod i właściwości<br />    }<br />}</pre>
<p><strong>plik Employee.java</strong></p>
<pre>public class Employee {<br />    private String name;<br />    private String jobTitle;<br />    private int salary;<br /><br />    public Employee(){<br />        name = "unknown";<br />        jobTitle = "unknown";<br />        salary = 2500;<br />    }<br /><br />    public Employee(String name, String jobTitle, int salary) {<br />        this.name = name;<br />        this.jobTitle = jobTitle;<br />        this.salary = salary;<br />    }<br /><br />    public void doWork(){<br />        System.out.println("Working!");<br />    }<br /><br />    public String getName() {<br />        return name;<br />    }<br /><br />    public void setName(String name) {<br />        this.name = name;<br />    }<br /><br />    public String getJobTitle() {<br />        return jobTitle;<br />    }<br /><br />    public void setJobTitle(String jobTitle) {<br />        this.jobTitle = jobTitle;<br />    }<br /><br />    public int getSalary() {<br />        return salary;<br />    }<br /><br />    public void setSalary(int salary) {<br />        this.salary = salary;<br />    }<br />}</pre>
<p><strong>plik Manager.java</strong></p>
<pre>public class Manager extends Employee{<br />    private String departmentName;<br /><br />    public Manager() {<br />        super();<br />        departmentName = "unknown";<br />    }<br /><br />    public Manager(String name, String jobTitle, int salary, String departmentName) {<br />        super(name, jobTitle, salary);<br />        this.departmentName = departmentName;<br />    }<br /><br />    public void hireEmployee(){<br />        System.out.println("Employee hired!");<br />    }<br />    public void giveRise(Employee employee){<br />        System.out.println("Employee got rise!");<br />    }<br /><br />    public String getDepartmentName() {<br />        return departmentName;<br />    }<br /><br />    public void setDepartmentName(String departmentName) {<br />        this.departmentName = departmentName;<br />    }<br />}</pre>
<p><strong>plik Ceo.java</strong></p>
<pre>public class Ceo extends Manager{<br />    private int sharesNumber;<br /><br />    public Ceo() {<br />        sharesNumber = 100;<br />    }<br /><br />    public Ceo(String name, String jobTitle, int salary, String departmentName, int sharesNumber) {<br />        super(name, jobTitle, salary, departmentName);<br />        this.sharesNumber = sharesNumber;<br />    }<br /><br />    public void signContract(){<br />        System.out.println("Contract signed!");<br />    }<br /><br />    public int getSharesNumber() {<br />        return sharesNumber;<br />    }<br /><br />    public void setSharesNumber(int sharesNumber) {<br />        this.sharesNumber = sharesNumber;<br />    }<br />}</pre>
<p> </p>
<h3>Przykład:</h3>
<p><strong>plik PolymorphismCasting.java</strong></p>
<pre>public class PolymorphismCasting {<br />    public static void main(String[] args) {<br />        Employee employee[] = new Employee[10];<br />        employee[0] = new Manager("Dyrektor", 10000); //typ Manager<br />        employee[0].printName();<br />        employee[1] = new Employee("Programista", 12000);<br />        employee[1].printName();<br /><br />        /*<br />        w takiej sytuacji jeżeli chcemy, aby dyrektor mógł dać podwyżkę to musimy<br />        rzutowac jego typ na Managera, bo typ employee nie posiada takiej metody<br />         */<br /><br />        Manager manager = (Manager) employee[0];<br />        manager.giveRise(employee[1], 0.15f);<br />        employee[1].printName();<br />    }<br />}</pre>
<p><strong>plik Employee.java</strong></p>
<pre>public class Employee {<br />    protected int salary;<br />    protected String name;<br />    public Employee(String name, int salary){<br />        this.name = name;<br />        this.salary = salary;<br />    }<br />    public void printName(){<br />        System.out.println("Employee: " + name + ", salary: " + salary);<br />    }<br />}</pre>
<p><strong>plik Manager.java</strong></p>
<pre>public class Manager extends Employee{<br />    public Manager(String name, int salary) {<br />        super(name, salary);<br />    }<br />    public void printName(){<br />        System.out.println("Manager: " + name + ", salary: " + salary);<br />    }<br />    public void giveRise(Employee e, float percent){<br />        e.salary+=(int)(e.salary*percent);<br />    }<br />}</pre>
<p> </p>
<h2>Klasy i metody abstrakcyjne oraz interfejsy</h2>
<p>Klasa abstrakcyjna definiuje pewien model i zachowanie obiektu.<br />Taka klasa nie posiada definicji tych metod, jedynie ich deklaracje, że gdzieś dalej w kodzie muszą się pojawić. Czyli do czasu rozszerzenia ich o funkcjonalności w klasach dziedziczących, te metody nie istnieją (są abstrakcją).<br />Metody abstrakcyjne definiujemy w klasie bazowej klauzulą abstract. Wszystkie tego typu zadeklarowane metody będą musiały pojawić się w klasach dziedziczących.<br />Nie można utworzyć obiektu klasy abstrakcyjnej. Klasa ta jest jedynie „bazą” dla klas potomnych.<br />Można przypisać podklasę do zmiennej typu abstrakcyjnego.<br />Pamiętamy, że klasę dziedziczymy i możemy zrobić to tylko raz.</p>
<p> </p>
<p>Interfejs jest zbiorem metod jakie wymagamy by posiadała klasa, która go implementuje.<br />Możemy implementować wiele interfejsów dla jednej klasy.<br />Wszystkie metody określane w interfejsie są abstrakcyjne.</p>
<h3>Przykład:</h3>
<p><strong>plik AbstractClassesAndInterfaces.java</strong></p>
<pre>public class AbstractClassesAndInterfaces {<br />    public static void main(String[] args) {<br /><br />        //CelestialBody earth = new CelestialBody();<br />        //powyższe wywołanie generuje błąd, bo nie ma czegoś fizycznego co się nazywa ciało niebieskie. To tylko pojęcie określające różne elementy<br />        Planet earth = new Planet();<br />        earth.setName("Ziemia");<br />        System.out.println(earth.getName());<br />        earth.round();<br /><br />        Star sun = new Star();<br />        sun.round();<br /><br />        earth.showInfo();<br />    }<br />}</pre>
<p><strong>plik CelestialBody.java</strong></p>
<pre>public abstract class CelestialBody {<br />    private String name;<br /><br />    public String getName() {<br />        return name;<br />    }<br /><br />    public void setName(String name) {<br />        this.name = name;<br />    }<br /><br />    //tworzymy nazwę metody, którą musi mieć każda klasa dziedzicząca metodę abstrakcyjną<br />    public abstract void round();<br /><br /><br />}</pre>
<p><strong>plik Info.java</strong></p>
<pre>public interface Info {<br />    public void showInfo();<br />}</pre>
<p><strong>plik Planet.java</strong></p>
<pre>public class Planet extends CelestialBody implements Info {<br />    @Override<br />    public void round() {<br />        System.out.println("jestem planetą - kręce się");<br />    }<br /><br />    @Override<br />    public void showInfo() {<br />        System.out.println("Implementuję metodę wspólną dla obu klas");<br />    }<br />}</pre>
<p><strong>plik Star.java</strong></p>
<pre>public class Star extends CelestialBody implements Info {<br /><br />    @Override<br />    public void round() {<br />        System.out.println("Jestem gwiazdą - nie kręcę się");<br />    }<br /><br />    @Override<br />    public void showInfo() {<br />        System.out.println("Implementuję metodę wspólną dla obu klas");<br />    }<br />}</pre>
<p> </p>
<h3>Różnice między interfejsem, a klasą abstrakcyjną</h3>
<ul>
<li>klasa może implementować wiele interfejsów, ale rozszerzać tylko jednego rodzica</li>
<li>metody w interfejsie są publiczne, w klasie publiczne lub chronione</li>
<li>interfejs może zawierać tylko deklaracje metod, a klasa też metody zdefiniowane</li>
<li>klasy abstrakcyjne mogą zawierać atrybuty(pola), interfejsy nie</li>
<li>w interfejsach wszystkie metody są abstrakcyjne, natomiast w klasie abstrakcyjnej można stworzyć metody posiadające ciało, jak i abstrakcyjne</li>
<li>klasa abstrakcyjna zazwyczaj jest ściśle związana z klasami dziedziczącymi w sensie logicznym, czyli np. tworzymy klasę abstrakcyjną Planeta po której dziedziczą konkretne klasy planet (np. Ziemia, Mars).</li>
<li>Interfejs natomiast nie musi być już tak mocno związany z daną klasą, on określa jej cechy, np możesz stworzyć interfejs Zniszczalny, który mówi że dany obiekt może zostać zniszczony. Taki interfejs możesz nadać zarówno klasą Planeta, Gwiazda, Budynek itp.</li>
<li>interfejs może dziedziczyć jedynie po innych interfejsach, a klasa abstrakcyjna może dziedziczyć po klasach abstrakcyjnych, interfejsach a nawet zwykłych klasach</li>
<li>interfejs nie może mieć konstruktora, w klasie abstrakcyjnej możemy dostarczyć implementację konstruktora domyślnego</li>
</ul>
<p> </p>
<h3>Przykład:</h3>
<p><strong>plik Interface.java</strong></p>
<pre>public class Interface {<br />    public static void main(String[] args) {<br />        Car car = new Car();<br />        car.move();<br /><br />        // możemy zapimplementować obiekt tak:<br />        // Vehicle vehicle = new Car();<br />        //lub tak:<br />        Vehicle vehicle = car;<br />        System.out.println(vehicle.speed());<br /><br />        Vehicle car2 = new Car();<br />        car2.turn();<br /><br />        Car car3 = (Car) car2; //rzutowanie<br />        car3.stop();<br /><br />        Train train = new Train();<br />        Vehicle trainVehicle = train;<br />        System.out.println(trainVehicle.speed());<br /><br />        Plain plain = new Plain();<br />        plain.increaseHeight();<br /><br />        Vehicle vehicles[] = new Vehicle[4];<br />        vehicles[0] = car;<br />        vehicles[1] = car2;<br />        vehicles[2] = train;<br />        vehicles[3] = plain;<br /><br />        vehicles[2].move();<br /><br />        if (vehicles[2] instanceof Train){<br />            Train someTrain = (Train) vehicles[2];<br />            someTrain.turn();<br />        }<br /><br />        if (vehicles[3] instanceof Plain){<br />            Plain somePlain = (Plain) vehicles[3];<br />            somePlain.decreaseHeight();<br /><br />            Flying flyingVehicle = somePlain;<br />            flyingVehicle.increaseHeight();<br />        }<br />    }<br />}</pre>
<p><strong>plik Flying.java</strong></p>
<pre>public interface Flying {<br />    void increaseHeight();<br />    void decreaseHeight();<br />}</pre>
<p><strong>plik Vehicle.java</strong></p>
<pre>public interface Vehicle {<br />    void move(); // nie musimu podawać modyfikatora public<br />    void stop();<br />    void turn();<br />    float speed();<br />}</pre>
<p><strong>plik Car.java</strong></p>
<pre>public class Car implements Vehicle{<br />    @Override<br />    public void move() {<br />        System.out.println("Car is moving!");<br />    }<br /><br />    @Override<br />    public void stop() {<br />        System.out.println("Car stopped!");<br />    }<br /><br />    @Override<br />    public void turn() {<br />        System.out.println("Car is turning!");<br />    }<br /><br />    @Override<br />    public float speed() {<br />        return 220;<br />    }<br />}</pre>
<p><strong>plik Plain.java</strong></p>
<pre>//wiele interfejsów<br />public class Plain implements Vehicle, Flying{<br />    @Override<br />    public void move() {<br />        System.out.println("Plain is moving!");<br />    }<br /><br />    @Override<br />    public void stop() {<br />        System.out.println("Plain stopped!");<br />    }<br /><br />    @Override<br />    public void turn() {<br />        System.out.println("Plain turn!");<br />    }<br /><br />    @Override<br />    public float speed() {<br />        return 900;<br />    }<br /><br />    //implementujemy metody z obu interfejsów<br /><br />    @Override<br />    public void increaseHeight() {<br />        System.out.println("Plain up!");<br />    }<br /><br />    @Override<br />    public void decreaseHeight() {<br />        System.out.println("Plain down!");<br />    }<br />}</pre>
<p><strong>plik Train.java</strong></p>
<pre>public class Train implements Vehicle{<br />    @Override<br />    public void move() {<br />        System.out.println("Train is moving!");<br />    }<br /><br />    @Override<br />    public void stop() {<br />        System.out.println("Train stopped!");<br />    }<br /><br />    @Override<br />    public void turn() {<br />        System.out.println("Train turn!");<br />    }<br /><br />    @Override<br />    public float speed() {<br />        return 180;<br />    }<br />}</pre>
<p> </p>
<h3>Przykład:</h3>
<p><strong>plik interface_extends_default_static_final.java</strong></p>
<pre>public class Train implements Vehicle{<br />    @Override<br />    public void move() {<br />        System.out.println("Train is moving!");<br />    }<br /><br />    @Override<br />    public void stop() {<br />        System.out.println("Train stopped!");<br />    }<br /><br />    @Override<br />    public void turn() {<br />        System.out.println("Train turn!");<br />    }<br /><br />    @Override<br />    public float speed() {<br />        return 180;<br />    }<br />}</pre>
<p><strong>plik Animal.java</strong></p>
<pre>public interface Animal {<br />    int getNumLegs();<br />    String getName();<br />}</pre>
<p><strong>plik Bird.java</strong></p>
<pre>//rozszerzamy wiele interfejsów<br />public interface Bird extends Animal,Eating,Flying{<br /><br />}</pre>
<p><strong>plik Eating.java</strong></p>
<pre>public interface Eating {<br />    void eat();<br />    default void searchForFood(){<br />        System.out.println("Searching for food.");<br />    }<br />}</pre>
<p><strong>plik Flying.java</strong></p>
<pre>public interface Flying {<br />    //możemy dodać zmienną statyczną<br />    static final float DEFAULT_WINGSPAN = 0.7f;<br />    void fly();<br /><br />    default void flyHigher(){<br />        System.out.println("Flying higher.");<br />    }<br /><br />    default float getWingspan(){<br />        return Flying.DEFAULT_WINGSPAN;<br />    }<br /><br />    static int getDefaultNumWings(){<br />        return 2;<br />    }<br />}</pre>
<p><strong>plik Parrot.java</strong></p>
<pre>public class Parrot implements Bird{<br />    @Override<br />    public int getNumLegs() {<br />        return 2;<br />    }<br /><br />    @Override<br />    public String getName() {<br />        return "Parrot";<br />    }<br /><br />    @Override<br />    public void eat() {<br />        System.out.println("Eating.");<br />    }<br /><br />    @Override<br />    public void fly() {<br />        System.out.println("Parrot is flying.");<br />    }<br /><br />    //możemy nadpisac metodę domyslną, jeżeli np nam się nie podoba<br /><br />    @Override<br />    public void searchForFood() {<br />        System.out.println("Parrot is searching for food.");<br />    }<br />}</pre>
<p> </p>
<h3>Przykład:</h3>
<p><strong>plik MouseListenerExample.java</strong></p>
<pre>import javax.swing.*;<br /><br />public class MouseListenerExample {<br />    public static void main(String[] args) {<br />        Frame frame = new Frame();<br />        frame.setSize(300,300); //wielkość okienka<br />        frame.setTitle("Przykład"); //tytuł okienka<br />        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//co ma zrobić aplikacja jeżeli użytkownik będzie chciał ją zamknąć<br />        frame.setLayout(null);//wymuszamy położenie na taką pozycję jak my ustawiliśmy<br />        frame.setVisible(true);//pokazujemy okienko<br />        frame.addMouseListener(frame);<br />    }<br />}</pre>
<p><strong>plik Frame.java</strong></p>
<pre>//korzystamy z wbudowanej klasy JFrame oraz wbudowanego interfejsu MouseListener<br />import javax.swing.*;<br />import java.awt.event.MouseEvent;<br />import java.awt.event.MouseListener;<br /><br />public class Frame extends JFrame implements MouseListener {<br /><br />    //jeżeli nie chcemy uzyskiwać wyników kliknięć w konsoli, tylko w okienku musimy dodać JLable<br />    private JLabel label;<br />    public Frame(){<br />        label = new JLabel("---");<br />        label.setBounds(10,10,250,50);//określamy wielkość pola<br />        this.add(label);<br />    }<br /><br />    //alt+g i implementujemy wszystkie metody<br />    @Override<br />    public void mouseClicked(MouseEvent e) {<br />        //pobieramy współrzędne kliknięcia w okienku<br />        int x = e.getX();<br />        int y = e.getY();<br /><br />        String str = "Kliknięto x: "+x+" y: "+y;<br />        label.setText(str);<br /><br />        System.out.println(str);<br />    }<br /><br />    @Override<br />    public void mousePressed(MouseEvent e) {<br /><br />    }<br /><br />    @Override<br />    public void mouseReleased(MouseEvent e) {<br /><br />    }<br /><br />    @Override<br />    public void mouseEntered(MouseEvent e) {<br /><br />    }<br /><br />    @Override<br />    public void mouseExited(MouseEvent e) {<br /><br />    }<br />}</pre>
<p> </p>
<h2>Klasy wewnetrzne</h2>
<p>W java istnieje opcja zadeklarowania klasy wewnętrznej, czyli klasy w klasie. Istnieje kilka opcji:<br />&#8211; klasa prywatna wewnątrz klasy może być używana tylko w niej<br />&#8211; klasa publiczna może zostać zainicjowana po podaniu nazwy klasy głównej, a następnie po kropce klasy wewnętrznej</p>
<p> </p>
<h3>Przykład</h3>
<p><strong>plik ClassPrvPub.java</strong></p>
<pre>public class ClassPrvPub {<br />    //wewnętrzna prywatna klasa<br />    private class PrivCls{<br />        public void printInfo(){<br />            System.out.println("Jestem z prywatnej wewnętrznej klasy.");<br />        }<br />    }<br /><br />    //wewnętrzna prywatna klasa<br />    public class PubCls{<br />        public void printInfo(){<br />            System.out.println("Jestem z publicznej wewnętrznej klasy.");<br />        }<br />    }<br /><br />    //publiczna metoda wykorzystująca wewnętzną prywatną klasę<br />    public void run(){<br />        PrivCls prvCls = new PrivCls();<br />        prvCls.printInfo();<br /><br />        //możemy zadeklarować klasę wewnątrz metody<br />        class ClassInMethod{<br />            public void printInfo(){<br />                System.out.println("Klasa wewnątrz metody");<br />            }<br />        }<br />        ClassInMethod innerClass = new ClassInMethod();<br />        innerClass.printInfo();<br />    }<br />}</pre>
<p><strong>plik InnerClass.java</strong></p>
<pre>public class InnerClass {<br />    public static void main(String[] args) {<br />        //tworzymy obiekt klasy ClassPrvPub<br />        ClassPrvPub privExample = new ClassPrvPub();<br />        //wywołujemy metodę<br />        privExample.run();<br /><br />        //tworzymy obiekt publicznej klasy<br />        ClassPrvPub.PubCls pubClass = privExample.new PubCls();<br />        pubClass.printInfo();<br />    }<br />}</pre>
<p> </p>
<h2>Klasa Object</h2>
<p>Klasa Object jest bazową klasą Javy, każdy nowo tworzony obiekt rozszerza klasę Object.<br />Klasa ta posiada wiele przydatnych metod, część z nich juz poznaliście np. equals, to String itp.</p>
<h3>Przykład</h3>
<p><strong>plik CarObject.java</strong></p>
<pre>public class CarObject {<br />    private String manufacturer;<br />    private String model;<br />    private String color;<br /><br />    //dodajemy konstruktor Alt+g lub Alt+Insert lub...<br />    public CarObject(String manufacturer, String model, String color) {<br />        this.manufacturer = manufacturer;<br />        this.model = model;<br />        this.color = color;<br />    }<br /><br />    //przesłonimy teraz metodę toString, żeby wyświetlała więcej czytelnych informacji<br />    //Alt+g i wybieramy toString<br />/*<br />    @Override<br />    public String toString() {<br />        return "CarObject{" +<br />                "manufacturer='" + manufacturer + '\'' +<br />                ", model='" + model + '\'' +<br />                ", color='" + color + '\'' +<br />                '}';<br />    }*/<br />}</pre>
<p><strong>plik ObjectExample.java</strong></p>
<pre>//jak przesłonić metodę toString<br />public class ObjectExample {<br />    public static void main(String[] args) {<br />        CarObject car = new CarObject("Ford", "Focus","blue");<br />        CarObject car2 = new CarObject("Peugeot", "307SW", "blue");<br />        System.out.println(car); //zostanie wykorzystana automatycznie metoda toString i wyświetli: all.ObjectClass.CarObject@378bf509, po przesłonięciu metody otrzymamy bardziej czytelne informacje<br />        System.out.println(car.hashCode());//unikalna liczba na bazie CarObject<br /><br />        //sprawdzimy czy obiekty wskazują na to samo miejsce w pamięci<br />        if(car.equals(car2)){<br />            System.out.println("Obiekty wskazują na tą samą referencję, czyli miejsce w pamięci.");<br />        } else{<br />            System.out.println("Obiekty nie wskazują na tą samą referencję");<br />        }<br />    }<br />}</pre>
<h3> </h3>
<h3>Zadanie1:</h3>
<p>Napisz program sortujący tablicę metodą przez wybieranie zgodnie z poniższymi wytycznymi:</p>
<p><b>Sortowanie przez wybieranie</b> &#8211; jedna z prostszych metod sortowania o złożoności O(<i>n</i><sup>2</sup>). Polega na wyszukaniu elementu mającego się znaleźć na żądanej pozycji i zamianie miejscami z tym, który jest tam obecnie. Operacja jest wykonywana dla wszystkich indeksów sortowanej tablicy.</p>
<p>Algorytm przedstawia się następująco:</p>
<ol>
<li>wyszukaj minimalną wartość z tablicy spośród elementów od <tt>i</tt> do końca tablicy</li>
<li>zamień wartość minimalną, z elementem na pozycji <tt>i</tt></li>
</ol>
<p>Gdy zamiast wartości minimalnej wybierana będzie maksymalna, wówczas tablica będzie posortowana od największego do najmniejszego elementu.</p>
<p>Założenia do programu:</p>
<ul>
<li>program wykonywany w konsoli</li>
<li>sortowanie odbywa się malejąco, nie wykorzystuje gotowych funkcji do sortowania oraz do szukania maksimum</li>
<li>sortowana jest tablica 10 liczb całkowitych. Tablica jest polem klasy.</li>
<li>tablica jest wczytywana z klawiatury po uprzednim wypisaniu odpowiedniego komunikatu</li>
<li>wszystkie elementy posortowanej tablicy są wyświetlane na ekranie</li>
<li>klasa zawiera co najmniej dwie metody: sortującą i szukającą wartość najwyższą. Widzialność metody szukającej ogranicza się jedynie do klasy.</li>
<li>metoda szukająca zwraca wartość, w zależności od przyjętej taktyki może być to wartość maksymalna lub index wartości maksymalnej.</li>
<li>program powinien być zapisany czytelnie, z zasadami czystego formatowania kodu, należy stosować znaczące nazwy zmiennych i funkcji.</li>
</ul>
<p> </p>
<h3>Zadanie2:</h3>
<p><span id="page230R_mcid8" class="markedContent"><span dir="ltr" role="presentation">Napisz program, który szyfruje podany przez użytkownika tekst szyfrem podstawieniowym zwanym GADERYPOLUKI. Klucz </span><span dir="ltr" role="presentation">ten zawiera pary zamienników: GA</span><span dir="ltr" role="presentation">&#8211;</span><span dir="ltr" role="presentation">DE</span><span dir="ltr" role="presentation">&#8211;</span><span dir="ltr" role="presentation">RY</span><span dir="ltr" role="presentation">&#8211;</span><span dir="ltr" role="presentation">PO</span><span dir="ltr" role="presentation">&#8211;</span><span dir="ltr" role="presentation">LU</span><span dir="ltr" role="presentation">&#8211;</span><span dir="ltr" role="presentation">KI. Pierwsza litera w parze jest zastępowana na drugą, druga na pierwszą. </span><span dir="ltr" role="presentation">Dla przykładu litera G z</span><span dir="ltr" role="presentation">astępowana jest literą A, litera A literą G. Litery, których nie ma w kluczu (inne niż GADERYPOLUKI) </span><span dir="ltr" role="presentation">pozostają bez zmian. </span></span><span id="page230R_mcid9" class="markedContent"><span dir="ltr" role="presentation">Np. słowo PROGRAM po zaszyfrowaniu brzmi OYPAYGM, bo: </span></span><span id="page230R_mcid10" class="markedContent"> </span><span id="page230R_mcid11" class="markedContent"> </span><span id="page230R_mcid12" class="markedContent"><br role="presentation" /><span dir="ltr" role="presentation">P</span> </span><span id="page230R_mcid13" class="markedContent"><span dir="ltr" role="presentation">R</span> </span><span id="page230R_mcid14" class="markedContent"><span dir="ltr" role="presentation">O</span> </span><span id="page230R_mcid15" class="markedContent"><span dir="ltr" role="presentation">G</span> </span><span id="page230R_mcid16" class="markedContent"><span dir="ltr" role="presentation">R</span> </span><span id="page230R_mcid17" class="markedContent"><span dir="ltr" role="presentation">A</span> </span><span id="page230R_mcid18" class="markedContent"><span dir="ltr" role="presentation">M</span> </span><span id="page230R_mcid19" class="markedContent"></span><span id="page230R_mcid20" class="markedContent"><br role="presentation" /><span dir="ltr" role="presentation">O</span> </span><span id="page230R_mcid21" class="markedContent"><span dir="ltr" role="presentation">Y</span> </span><span id="page230R_mcid22" class="markedContent"><span dir="ltr" role="presentation">P</span> </span><span id="page230R_mcid23" class="markedContent"><span dir="ltr" role="presentation">A</span> </span><span id="page230R_mcid24" class="markedContent"><span dir="ltr" role="presentation">Y</span> </span><span id="page230R_mcid25" class="markedContent"><span dir="ltr" role="presentation">G</span> </span><span id="page230R_mcid26" class="markedContent"><span dir="ltr" role="presentation">M</span> </span><span id="page230R_mcid27" class="markedContent"></span><span id="page230R_mcid28" class="markedContent"> </span><span id="page230R_mcid29" class="markedContent"><br role="presentation" /><span dir="ltr" role="presentation">Założenia programu</span>:</span></p>
<ul>
<li><span id="page230R_mcid30" class="markedContent"><span dir="ltr" role="presentation">Program wykonywany w konsoli</span> </span><span id="page230R_mcid32" class="markedContent"></span></li>
<li><span id="page230R_mcid32" class="markedContent"><span dir="ltr" role="presentation">Jeżeli język programowania tego wymaga, można założyć dla uproszczenia, że tekst do zaszyfrowania ma </span><br role="presentation" /><span dir="ltr" role="presentation">maksymalnie 20 liter i zapisany jest małymi liter</span><span dir="ltr" role="presentation">ami oraz nie ma w nim innych znaków, cyfr, spacji</span> </span><span id="page230R_mcid33" class="markedContent"></span></li>
<li><span id="page230R_mcid33" class="markedContent"><span dir="ltr" role="presentation">Program zawiera funkcję szyfrującą, która przyjmuje jako argument wprowadzony tekst</span> </span><span id="page230R_mcid34" class="markedContent"></span></li>
<li><span id="page230R_mcid34" class="markedContent"><span dir="ltr" role="presentation">Funkcja zwraca zaszyfrowany tekst</span> </span><span id="page230R_mcid35" class="markedContent"></span></li>
<li><span id="page230R_mcid35" class="markedContent"><span dir="ltr" role="presentation">W programie głównym występuje wczytanie tekstu z klawiatury po uprzednim wyświetleniu st</span><span dir="ltr" role="presentation">osownego komunikatu </span><span dir="ltr" role="presentation">dla użytkownika, a po zaszyfrowaniu wyświetlenie zaszyfrowanej jego wersji</span>  </span><span id="page230R_mcid36" class="markedContent"></span></li>
<li><span id="page230R_mcid36" class="markedContent"><span dir="ltr" role="presentation">Program powinien być zapisany czytelnie, z zasadami czystego formatowania kodu, należy stosować znaczące nazwy </span><span dir="ltr" role="presentation">zmiennych i funkcji</span> </span></li>
</ul>
<p>Artykuł <a href="https://kamakaczmarek.net/14-java-obiektowo/">14. JAVA &#8211; obiektowo</a> pochodzi z serwisu <a href="https://kamakaczmarek.net">Kama Kaczmarek</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
