Příklad abstraktní třídy

xyz

  • ***
  • 206
    • Zobrazit profil
Příklad abstraktní třídy
« kdy: 25. 02. 2023, 11:58:16 »
Ted jsem zase narazil na clanek o abstrakci v Jave, kde je pouzity priklad.

Kód: [Vybrat]
abstract class Vehicle {
abstract void move();
abstract void accelerate();
};

class Car extends Vehicle {
void move() {
   System.out.println("Inside the move method of the Car class...");
}

Ten clanek sam o sobe neni nejak spatny, ale proc proboha vysvetluji abstraktni tridy i v roce 2023 na techto straslivych prikladech? Prece by stacilo vzit neco s Java SDK, ne?
« Poslední změna: 25. 02. 2023, 12:49:34 od Petr Krčmář »


xyz

  • ***
  • 206
    • Zobrazit profil
Re:Priklad abstraktni tridy
« Odpověď #1 kdy: 25. 02. 2023, 12:21:04 »
Autor clanku:
Joydip Kanjilal
A Microsoft Most Valuable Professional in ASP.NET, Speaker, and Author of several books and articles. More than 25 years of experience in IT with more than 18 years in Microsoft .NET and its related technologies. He was selected as a Community Credit Winner at http://www.community-credit.com several times. He has authored 8 books and more than 500 articles in some of the most reputed sites worldwide including MSDN, Info World, CodeMag, Tech Beacon, Tech Target, Developer, CodeGuru, and more.


Re:Priklad abstraktni tridy
« Odpověď #2 kdy: 25. 02. 2023, 12:28:54 »
Asi těžko budete hledat v Java JDK jednoduchou abstraktní třídu, jejíž význam bude každému na první pohled jasný. Pokud o nějaké takové třídě víte, poraďte ji autorovi.

Ten příklad není moc dobrý z jiného důvodu – pokud se ta abstraktní třída ještě nějak neupravuje, místo abstraktní třídy by v tomhle případě bylo mnohem lepší použít interface. Abstraktní třída má smysl tehdy, když rovnou poskytuje nějakou implementaci, tedy když je tam i něco jiného, než jen abstraktní metody.

Kit

  • *****
  • 704
    • Zobrazit profil
    • E-mail
Re:Priklad abstraktni tridy
« Odpověď #3 kdy: 25. 02. 2023, 16:30:58 »
Ten příklad není moc dobrý z jiného důvodu – pokud se ta abstraktní třída ještě nějak neupravuje, místo abstraktní třídy by v tomhle případě bylo mnohem lepší použít interface. Abstraktní třída má smysl tehdy, když rovnou poskytuje nějakou implementaci, tedy když je tam i něco jiného, než jen abstraktní metody.

Pokud by se místo abstraktní třídy použilo rozhraní, potom by se asi nemělo jmenovat Vehicle, ale třeba Movable. To proto, že obsahuje metody move() a accelerate().

peete

Re:Příklad abstraktní třídy
« Odpověď #4 kdy: 25. 02. 2023, 21:05:00 »
Nejhorší je, když Javu vysvětluje někdo kdo jí rozumí, a čím víc má titulů a čím déle jí používá tím hůř. Důvod je ten, že takový člověk si myslí, že některé věci jsou samozřejmé a že jim každý rozumí od narození. Jako v jiných oborech platí, že nejsrozumitelněji vám to vysvětlí spolužák, protože má s vámi jako studentem největši empatii a nejvíc rozumí tomu, co nechápete. Pokud je někdo expert na Javu a přitom jí umí srozumitelně vysvětlit někomu, kdo na ní expert není, tak to je borec. A primitivní příklady k tomu rozhodně patří.


Re:Příklad abstraktní třídy
« Odpověď #5 kdy: 26. 02. 2023, 06:03:14 »
Kdybych Javu vysvětloval začátečníkovi, tak mu důrazně doporučím, aby se abstraktním třídám a dědičnosti vyhnul.
Je příliš jednoduchý to zprasit, že stejně nejde jedna vrstva použít bez druhé (viz třeba Spring, ten je na to poměrně odborník - např. RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping, kterej má přesně tohohle jednoho potomka).
Za 10 let každodenního používání jsem nenarazil na situaci, která by nešla stejně nebo líp vyřešit kompozicí.

Re:Příklad abstraktní třídy
« Odpověď #6 kdy: 26. 02. 2023, 09:51:42 »
Kdybych Javu vysvětloval začátečníkovi, tak mu důrazně doporučím, aby se abstraktním třídám a dědičnosti vyhnul.
Je příliš jednoduchý to zprasit, že stejně nejde jedna vrstva použít bez druhé (viz třeba Spring, ten je na to poměrně odborník - např. RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping, kterej má přesně tohohle jednoho potomka).
Za 10 let každodenního používání jsem nenarazil na situaci, která by nešla stejně nebo líp vyřešit kompozicí.

Přesně tak, je chybou prezentovat dědičnost jako hlavní rys OOP. Snadno se s ní člověk dostane do úzkých. Proto se IMHO prosazují v jiných jazycích mixiny, traity, kachny (duck-typing) a pododně. Na druhou stranu, udělat špatný návrh se dá snad úplně všude.

Arthur

  • ***
  • 168
    • Zobrazit profil
    • E-mail
Re:Příklad abstraktní třídy
« Odpověď #7 kdy: 26. 02. 2023, 10:35:08 »
Jako Java-amatér se zeptám: co přesně je na tom příkladu tak hrozně špatně? Že jsou tam jen abstraktní metody (jak píše p. Jirsák)? Kdyby tam bylo
Kód: [Vybrat]
abstract class Vehicle {
   abstract void move();
   abstract void accelerate();

   protected void stop() {
      // do something
   }
};

tak je to OK?

Přesně tak, je chybou prezentovat dědičnost jako hlavní rys OOP. Snadno se s ní člověk dostane do úzkých.

můžete to nějak rozvést, třeba na jednoduchém příkladu? Resp. kdy je vhodné použít dědičnost a kdy ne?

Re:Příklad abstraktní třídy
« Odpověď #8 kdy: 26. 02. 2023, 11:11:37 »
Jako Java-amatér se zeptám: co přesně je na tom příkladu tak hrozně špatně?

Nemyslím si, že ten kód je hrozně špatně – zejména když neznáme kontext. Nicméně abstraktní třídy v Javě mají jediný účel – sdílení kódu („kód“ v širčím slova smyslu, ne jen výkonný kód, tedy třeba i definice fieldů). Přičemž v tom příkladu žádný kód ke sdílení není. Navíc v Javě jsou dva koncepty, které vypadají podobně – abstraktní třídy a rozhraní. Je potřeba se naučit mezi nimi rozlišovat – a abstraktní třída, která vlastně funguje jenom jako rozhraní, k tomu není zrovna dobrý příklad.

Ale jak jsem psal, neznáme kontext, je tady jenom jedna vytržená třída, nad kterou se xyz pohoršil, ale vůbec nenapsal, co se mu nelíbí. A spíš to vypadá, že se potřeboval vypsat ze své frustrace (nevíme, čím přesně byla způsobena), než že by o tom chtěl diskutovat.

Re:Příklad abstraktní třídy
« Odpověď #9 kdy: 26. 02. 2023, 12:29:58 »
Přesně tak, je chybou prezentovat dědičnost jako hlavní rys OOP. Snadno se s ní člověk dostane do úzkých.
můžete to nějak rozvést, třeba na jednoduchém příkladu? Resp. kdy je vhodné použít dědičnost a kdy ne?

Jednoduchá dědičnost sváže předka s potomkem příliš pevně, této vazbě navíc podléhají i další potomci, které budete chtít jednou vytvořit ale o kterých v době návrhu nic nevíte. Naproti tomu při skládání máte větší volnost - bonmotem řečeno: Předka nevyměníte, komponentu ano.

mikrom

  • ****
  • 332
    • Zobrazit profil
    • E-mail
Re:Příklad abstraktní třídy
« Odpověď #10 kdy: 26. 02. 2023, 13:40:44 »
Tu je abstraktna trieda Vehicle definovana, tak ze dava zmysel, nakolko okrem metod obsahuje aj premenne:
https://www.freecodecamp.org/news/abstract-classes-in-java-explained-with-examples/

xyz

  • ***
  • 206
    • Zobrazit profil
Re:Příklad abstraktní třídy
« Odpověď #11 kdy: 26. 02. 2023, 14:22:09 »
Tu je abstraktna trieda Vehicle definovana, tak ze dava zmysel, nakolko okrem metod obsahuje aj premenne:
https://www.freecodecamp.org/news/abstract-classes-in-java-explained-with-examples/

Diky, to je presne to, na co jsem si stezoval. Zde je javadoc u te abstraktni metody, co to ma delat. Pripadne tam muze byt i nejaky kontrakt, co maji potomci splnovat. A ne jen v potomku print "jsem uvnitr metody".

Re:Příklad abstraktní třídy
« Odpověď #12 kdy: 26. 02. 2023, 16:24:11 »
Pri vlastnom studiu som zistil, ze je potrebne hladat zdroje takeho stylu, ktore mi najviac vyhovuju. To sa tyka knih, clankov tutorialov a dalsich veci.
Vzdy mi na zaciatku trvalo +- 2 tyzdne sa prehryzst dostupnymi materialmi aby som si nasiel autora/autorov, ktory mi najviac vyhovovali(Ich vyklad bol pre mna najzrozumitelnejsi).
Skoda, ze taka moznost nebola aj v skolach. Viacere predmenty mi znechutili(horsie som ich chapal) vdaka ucitelom ale tych som vymenit nemohol.

V pripade Javy som si musel prejst viacerymi knihami, tutorialmi, kurzmi na Udemy, kym som nasiel to prave.
Nieco podobne prezivam teraz znovu pri SPRING-u.


Tazke ak niecomu nerozumies, nezda sa ti, tak skus na danu temu hladat iny zdroj ako zabijat cas snazenim sa pochopit to.

Re:Příklad abstraktní třídy
« Odpověď #13 kdy: 27. 02. 2023, 11:34:20 »
Většinou bych dával spíše přednost rozhraním a kompozici před abstraktními třídami a dědičností. Při kompozici mohu vložit více různých komponent, při dědičnosti mám jasně danou hierarchii.

Nicméně má to i své stinné stránky z hlediska náročnosti na RAM a výkon:

1. Hierarchie tříd nemá žádné další paměťové náklady na každou instanci, oproti tomu kompozice znamená další reference, i pokud tu odkazovanou komponentu používáte opakovaně. (Pokud ji vytváříte pokaždé znovu, je to ještě horší…) U tříd, ke kterým máte pár instancí, asi vyhraje použitelnost kódu, ale třeba u kolekcí je IMHO celkem odůvodněné dát přednost dědičnosti.
2. Volání metody třídy může být levnější než volání metody rozhraní, protože je jednodušší prohledat VMT pro jednoduchou dědičnost než VMT pro vícenásobnou dědičnost. Nicméně hádám, že toto obvykle fakt nemusíte řešit, mj. proto, že JVM spoustu věcí zvládne optimalizovat. (BTW, udělat na to benchmark by mohla být zábava – zejména poprat se s optimalizátorem tak, aby do toho neházel vidle…)