IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Výpočet obvodu a obsahu

Aktivity
Avatar
Nikol Srničková:4.12.2017 21:54

Prosím, mohl by mi někdo poradit, jak v hlavní třídě Aplikace vypíšu výsledek, tak aby se použily metody ze tříd Obvod a Obsah?
Děkuji

 
Odpovědět
4.12.2017 21:54
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Nikol Srničková
Jindřich Máca:5.12.2017 1:32

Ahoj, je to docela jednoduché. V těch jednotlivých case uděláš následující:

...
case 1:
    ...
    double stranaB = scanner.nextDouble();
    Obvod obvod = new Obvod(stranaA, stranaB);
    obvod.vypocitejObvod();
    strany.add(obvod);
...
case 2:
    ...
    double stranaB = scanner.nextDouble();
    Obsah obsah = new Obsah(stranaA, stranaB);
    obsah.vypocitejObsah();
    strany.add(obsah);
...

Jinak bych Tě chtěl ještě upozornit, že ten kód je koncepčně úplně špatně, hlavně z hlediska OOP... Měl jsem zrovna chvíli i náladu a tak jsem to zkusil v rychlosti napsat, jak bych to asi řešil já. Tady najdeš zdrojové kódy - https://www.itnetwork.cz/dev-lighter/992 Zkus si to projít a kdyby nebylo něco jasné, klidně se ještě ptej. ;)

 
Nahoru Odpovědět
5.12.2017 1:32
Avatar
Nikol Srničková:5.12.2017 13:43

Děkuji, pomohlo mi to a už to jde.
Vím, že kód asi nebude nic moc, ale mám Javu první semestr a tohle je vůbec první kód, který jsem psala.

 
Nahoru Odpovědět
5.12.2017 13:43
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:5.12.2017 17:25

Malinká poznámka k Jindrovému kódu (tam to nejde připsat, tak to píšu sem)
Čtverec je speciální případ obdelníka. Můžeš to tedy podědit.

// Soubor Ctverec.java
class Ctverec extends Obdelnik {

    public Ctverec(double size) {
        super(size, size);
    }

    @Override
    public TypGeometrickehoTvaru typObrazce() {
        return TypGeometrickehoTvaru.CTVEREC;
    }
}

Nicméně jinak bych nic neměnil (a tohle je stejně jen malá drobnost), hezký kód

Nahoru Odpovědět
5.12.2017 17:25
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Neználek
Člen
Avatar
Odpovídá na Lubor Pešek
Neználek:5.12.2017 21:28

Následující kód je špatně:

class Ctverec extends Obdelnik

Doporučuji poslechnout si Roberta Martina:
https://youtu.be/TMuno5RZNeE?…

Čtverec je sice speciální případ obdélníka. To ale neznamená, že by třída Ctverec měla být potomkem třídy Obdelnik.

 
Nahoru Odpovědět
5.12.2017 21:28
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Neználek
Lubor Pešek:6.12.2017 7:04

Přiznám se, že toho člověka neznám a co jsem viděl to video a trochu jsem si o něm přečetl, tak jsem zjistil, že ho ani znát nepotřebuju (už i ty komentáře o něčem trošku svědčí)
Takže abych si to shrnul - on tvrdí, že třída Obdelník není skutečný obdelník, ale kód, který představuje obdelník (a to samé u třídy Čtverec). A já blbec si pořád myslel, že hlavním důvodem, proč vůbec nějaké OOP vzniklo, je abychom se na všechny subjekty, které programujeme, dívali jako na objekty.
Očividně je to asi naopak.

Nahoru Odpovědět
6.12.2017 7:04
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Peter Sciranka
Tvůrce
Avatar
Odpovídá na Lubor Pešek
Peter Sciranka:6.12.2017 12:51

Ahoj, tak som si pozrel to video a myslím, že stojí za pozretie. On vysvetľuje "SOLID" design a jednotlivé princípy a čo sa týka toho štvorca a obdĺžnika, tak v jeho príklade je porušený princíp "L" (Liskov substitution principle).
V tvojom konkrétnom príklade ten princíp nie je porušený, ale myslím, že poukázal na zaujímavú vec:

  • štvorec by nemal byť "principiálne" potomkom obdĺžnika a to kvôli tomu, že na definovanie obdĺžnika nutne potrebuješ dve hodnoty, na štvorec len jednu.
  • dedičnosť je o tom, že potomok implementuje (z principiálneho pohľadu sú pre neho potrebné) všetky atribúty a metódy rodiča, ale v tomto prípade to tak nie je, pretože štvorec nepotrebuje 2, ale len 1 atribút (úspora 50%). Samozrejme v tomto príklade sa to môže zdať ako zbytočnosť, ale jedná sa skôr o pochopenie princípu a následné vytváranie dobrého designu.

Čo sa týka toho, že spomína, že obdĺžnik nie je skutočný obdĺžnik, tak to sa práve snaží vysvetliť to, že napr. class auto (a jeho inštancia) nie je skutočné reálne auto, ale len jeho reprezentácia v tvojom kóde a tým pádom by si mal prispôsobiť ten kód tomu, aby fungoval čo najlepšie v tvojej aplikácii (bude nasledovať určité princípy):

  • trochu to preženiem, ale do svojej triedy "auto" neimplementuješ napr. atribút "poťah sedadiel", ak ho nikdy nikde nevyužiješ (aj keď dané reálne auto má nejaké sedadlá).
  • tak isto asi nebudeš dediť triedu "auto" z triedy "lietadlo", aj keď všetko, čo môžeš robiť s autom, môžeš robiť aj s lietadlom a tým pádom je auto špeciálny druh lietadla a to také, ktoré nelieta. Tak toto je myslím zlý príklad dedičnosti ale dobrá paralela k štvorcu a obdĺžniku.

Takže obdĺžnik a štvorec sa môže dediť z triedy "geometrickýTvar", tak ako aj lietadlo a auto sa môže dediť z triedy "dopravnýPros­triedok", to myslím dáva väčší zmysel.

PS: Nerobím si žiadny nárok na pravdu a ak sa mýlim, alebo je moja úvaha nesprávna, tak budem vďačný, ak ma na to upozorníte :)

Nahoru Odpovědět
6.12.2017 12:51
Act as if it was Impossible to Fail
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Peter Sciranka
Lubor Pešek:6.12.2017 13:33

jo, krásně jsi tu popsal, kdy využít a nevyužít dědičnost:) Jasně, že je nebezpečné, pokud se dědičnost používá všude možně. Proto se musí (takto, jak jsi to popsal) takhle předem uvažovat, kdy je to vhodné a kdy ne. V tomto s tebou souhlasím. Nejznámější příklad je toho programátora, který řešil problém mezi cyklistou a žábou. Oba se mohli pohybovat. Ale když se dostal ke kamenům, po kterých cyklista nemohl přejet, ale žába mohla přeskákat, tak to programátor řešil tak, že cyklista dědil od žáby. Potom bylo úsměvné, že cyklista podědil i metodu kvákej.

Takže s tebou maximálně souhlasím - se vším, co jsi psal. A ano, na obdelník i čtverec se dá pohlížet jako na rozdílné útvary. Toto beru.

Nicméně jedno to ale si neodpustím:)
Ale vzpomeň si na základní školu - od základky se učíme, že právě ten nešťastný čtverec je speciálním případem obdélníka. Ano, z tohoto pohledu, co tu propagoval ten "profesor", tak on si to může touhle teorií vysvětlit i takto.
Nicméně ty když dědíš z nějaké třídy, tak využíváš bez výjimky všechny předkovi metody? To by dědičnost ztrácela tak trošku smysl - stačilo by vždycky jen a jen rozšiřovat předka.
A to, že čtverec místo dvou metod zavolá jednu (ve které může klidně zavolat obě předkovi metody), například takhle:

public void setSize(int size) {
        super.setWidth(size);
        super.setHeight(size);

        //nebo pokud by byla metoda setSize(int, int)
        super.setSize(size, size);
}

Jinak jaké má čtverec vlastnosti, které nemá obdélník? to že tomu lidé říkají jinak, že to nějak specializují, tak to je náš problém (třeba, že čtverec má úhlopříčky stejně velké).
Kdyby to byl jiný případ, určitě stejně jako ty, budu dlouze přemýšlet nad dědičností. Ale tady si nejsem vědom jakéhokoliv nebezpečí, proč bych neměl dědit. Toto je spíš krásný důkaz, že jeho teorie má chybu. Protože se nedá nic zkazit. Pokud ano, prosím aspoň o jeden případ, kdy dojde k nějakému nesmyslu a já to uznám.

Nahoru Odpovědět
6.12.2017 13:33
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Peter Sciranka
Tvůrce
Avatar
Odpovídá na Lubor Pešek
Peter Sciranka:6.12.2017 15:12

Ďakujem za komentár :)

Nemyslím si, že ty si urobil nejakú chybu, alebo porušil nejaký princíp. To ako píšeš, tak máš pravdu a nemyslím si, že je to v niečom nebezpečné, ale taktiež si nemyslím že on vraví nejaké hlúposti.

Ja viem že pôvodne si to napísal ako rekciu na zadaný príklad, poukázal si na dedičnosť a jej praktické využite a je dobre že si tak urobil, tak ďalší text ber prosím už len skôr ako také zamyslenie.
Čo sa týka všeobecne štvorca a obdĺžnika, ako aj sám píšeš, štvorec nemá žiadne iné metódy a atribúty ako trieda obdĺžnik, takže v podstate je zbytočné vytvárať dedičnú triedu štvorec, pretože stačí v konštruktore zadať obe hodnoty ako "size", "size" a tým pádom nemá zmysel dediť triedu, ak sa v ničom nelíši od rodiča.

  • Jedine, že by sme niekde v kóde zisťovali, či je daný objekt inštanciou štvorca alebo obdĺžnika, ale tam je už potom na zamyslenie, či štvorec mať ako geometrickýTvar alebo ako podedený obdĺžnik.

PS: Ja sa každopádne stále učím a snažím sa pochopiť pohľad a postoj iných (hlavne tých chytrejších ľudí), tak ako toho pána vo videu tak aj ten tvoj a som ti zaňho vďačný :)

Nahoru Odpovědět
6.12.2017 15:12
Act as if it was Impossible to Fail
Avatar
Marian Benčat:6.12.2017 15:35

Nestacilo prostě nalinkovat circle-ellipse problém?
https://en.wikipedia.org/…ipse_problem

Nahoru Odpovědět
6.12.2017 15:35
Totalitní admini..
Avatar
Neználek
Člen
Avatar
Odpovídá na Lubor Pešek
Neználek:6.12.2017 19:51

Díky moc za podnět k přemýšlení.

Pro jistotu přidávám celý kód, ať je jasné, o čem se bavíme.

public class Rectangle {

    private int width;
    private int height;

    public Rectangle(int width, int height) {
        super();
        this.width = width;
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

}

Jak bys naprogramoval metodu getSize?

public class Square extends Rectangle {

    public Square(int size) {
        super(size, size);
    }

    public void setSize(int size) {
        super.setWidth(size);
        super.setHeight(size);
    }

    public int getSize() {
        /* ??? */
    }

}
 
Nahoru Odpovědět
6.12.2017 19:51
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Neználek
Lubor Pešek:6.12.2017 20:57

Tak když už se tu bavíme o naprosté dokonalosti, tak ok...

  • nechápu proč voláš konstruktor třídy Object. Jestli to má nějaký hlubší význam, to mě když tak taky pouč.
  • bavíme se tu o tvarech, že? Tak proč určuješ, že bude první parametr šířka a druhý výška? já třeba budu chtít, abych měl jako první parametr výšku. Tudíž si volím víc obecnější pojmenování (tak jak to známe) "a" a "b". No a protože neuznávám krátké názvy, tak to můžem nazvat třebas "sideA" a "sideB".
public class Rectangle {

    private int sideA;
    private int sideB;

    public Rectangle(int newSideA, int newSideB) {
        sideA = newSideA;
        sideB = newSideB;
    }

    public int getSideA() {
        return sideA;
    }

    public void setSideA(int newSideA) {
        sideA = newSideA;
    }

    public int getSideB() {
        return sideB;
    }

    public void setSideB(int newSideB) {
        sideB = newSideB;
    }

}

A odpověď na tvou otázku? stejně, jako bych ti odpověděl v matematice. "Čtverec má stranu a"

public class Square extends Rectangle {

    public Square(int newSideA) {
        super(newSideA, newSideA);
    }

    @Override
    public void setSideA(int newSideA) {
        super.setSideA(newSideA);
        //nevím, proč nastavovat v takovémto kódu straně B stranu A.... trošku nelogické.
    }

    @Override
    public int getSideA() {
        //čoveče nebudeš tomu snad ani věřit, ale...
        return super.getSideA();
    }
}

Abych to shrnul, já se vyjadřuju celou dobu k tomuto topicu a ke kódu, jak by se dal ještě trošku usnadnit. V tomto konkrétním případě je to právě možné. Tím nezpochybňuji to, co bylo řečeno a souhlasím s tím, že je třeba se vždycky velmi dobře zamyslet, kdy je dědičnost vhodná a kdy ne (jak z programátorského hlediska, tak i z logiky věci). Tento konkrétní případ se dá vyložit očividně několika způsoby. Mě prostě strýček bob nebo jak mu říkají nepřesvědčil a nevyvrátil to, co říkám. Myslím tím, že bych tímto mohl program jakkoliv v budoucnu ohrozit. Já v tom vidím jen usnadnění práci, protože (a sorry, to mi nikdo nevyvrátí) čtverec je a vždycky bude speciálním případem obdélníku, který můžeme ještě nějak specifikovat, ale nemění se nic na tom, že se čtverec bude vždycky chovat jako obdélník (jestli existuje nějaký případ, kdy ne, tak sem s ním, rád se přiučím a bude-li to faktické, tak rád uznám jinou teorii)
Pro mě je tento člověk prozatím důkazem, že se hodně nudí a přemýšlí o blbostech. A to, že on přijde s nějakou teorií, tak to není pro mě důvod, abych popřel to, co používám celý život, to se na mě nezlob. Naopak on by se měl asi zamyslet nad tím, že právě existují i některé případy, které jeho teorii podkopávají.
Já třeba maximálně uznávám Martina Fowlera, ale taky ne ve všem. Je to prostě individuální a záleží na člověku, jak se na danou problematiku dívá - viz naše dva kódy. Oba dělají naprosto totožnou věc, ale ty se na to díváš z revolučního pohledu, já z konzervativního. To ale fakt neznamená, že v jiném případě budu postupovat stejně. Kdyby to tak mělo platit, tak není třeba programátorů, ale stačilo by právě jednorázově naprogramovat robota a ten by sypal jeden stejný kód podle jedné teorie a praktiky za druhým.
Tímto prosím o ukončení této debaty, protože to nikam nevede. Já téhle teorii prostě nechci rozumět, protože v ní nevidím smysl, Ty a mnozí další v tom vidíte budoucnost. Jediné, k čemu by to směřovalo, tak by byly nakonec nějaké osobní narážky a urážky. A IT network není parlament, ale skvělý český portál, kam toto nepatří. Takže za mě dobrý, díky za diskuzi, ale dál se vyjadřovat nebudu, chci si Tě spíš vážit, než se tu s Tebou přít.

Nahoru Odpovědět
6.12.2017 20:57
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Neználek
Člen
Avatar
Odpovídá na Lubor Pešek
Neználek:6.12.2017 21:56

Z tvých reakcí mám dojem, že reaguješ na něco, co jsem vůbec neřekl.

Snažil jsem se pouze upozornit na chybu v návrhu. Čirou náhodou jsem nedávno viděl video Roberta Martina a tak jsem přidal odkaz, to je vše.

K tvým otázkám

  • super() do konstruktoru mi doplnilo IDE a nevadí mi. Pokud bych ho tam neuvedl, doplnil by ho kompilátor. Byte kód bude v obou případech stejný, protože v Javě se konstruktor předka volá vždy.
  • Snažil jsem se napsat kód tak, jak jsem ho pochopil z tvých komentářů, abych se vyhnul nedorozumění. Obě varianty width/height a sideA/sideB jsou samozřejmě možné. Záleží na kontextu a konkrétním použití.
  • Pro mě osobně je tato debata přínosná, protože mi ukazuje, jak uvažují ostatní lidé. Rozhodně nemám v úmyslu nikoho urážet ani napadat.
  • Tvůj kód je špatně, protože dovoluje napsat následující nesmysl:
Square square = new Square(10);
square.setSideA(10);
square.setSideB(20);
 
Nahoru Odpovědět
6.12.2017 21:56
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na Neználek
gcx11:6.12.2017 22:08

Ale jinak je tam celkem zbytečný. Taky nebudeš psát pro každé volání funkce proměnnou, do které uložíš výsledek volání, stejně tak s iterátory, přestože to kompilátor stejně udělá.

Editováno 6.12.2017 22:08
 
Nahoru Odpovědět
6.12.2017 22:08
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 14 zpráv z 14.