Přechod z Javy na Rust. Ano či ne?

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #150 kdy: Dnes v 11:13:28 »
Ale co třeba takové:
Kód: [Vybrat]
vaha.zvazit(osoba)
osoba.zvazitSe(vaha)
Je něco z toho zjevně dobře nebo zjevně špatně?

Někdy se hovoří o IoC (inversion of control) a jeden směr se považuje za klasický/běžný a druhý za obrácený. Jindy je to jsou oba rovnocenné a nedá se ani říct, co je obrácené a co není. Viz např. push a pull parsery, nebo si můžu zaregistrovat posluchač a čekat až mi přijde událost nebo se naopak dotazovat na další událost. Používají se oba přístupy a ani jeden bych asi nepovažoval za zvěrstvo. Nevím, jaký konkrétní případ měl Standa na mysli, ale ve mne to vyvolalo vzpomínku na to, co píšu v odstavci „Píšu o problému, na který občas narážím v praxi…“.

Nicméně v tom příkladu šlo o tu logiku, který objekt je aktivní a který pasivní a kde se nachází implementace. Jde třeba o různé ukládání nebo načítání – ať už do různých souborových formátů nebo třeba do databáze nebo odeslání na po síti. Ve většině případů považuji za špatný návrh to, aby ten datový objekt měl takovou metodu. Většinou patří spíš do jiného objektu, který se o de/serializaci příslušného formátu (PNG, XML atd.) nebo obsluhu příslušného úložiště a správu spojení stará. Je to pružnější návrh, který umožňuje přidávat další formáty a úložiště (i jiným autorům) a nezanáší to rozhraní toho objektu a nezvyšuje to komplexitu jeho implementace (v něm je jen metoda a kód pro vrácení nebo načtení nějaké kanonické implementace třeba RGB bitmapy, zatímco implementace jednotlivých kodeků je jinde).
Pak ovšem musíš vnitřní stav toho objektu zpřístupnit vnějšímu světu (pro serializaci a deserializaci), což porušuje princip zapouzdření.

Proto by tam měl být ten mezikrok s tím kanonickým tvarem – objekt poskytne nějaká abstraktní data (nebo metody pro jejich iterování), třeba nějaký abstraktní strom nebo graf uzlů a jejich atributů… a pak bude jiná třída, která tuhle abstraktní-kanonickou reprezentaci projde a vyrobí z ní konkrétní formát. Zrovna v Javě je tohle už vestavěné ve formě reflexe, takže můžeme mít třeba JAXB, který umí ukládat a načítat objekty do/z XML, aniž by tyto objekty musely cokoli vědět o XML a obsahovaly nějaký specifický kód pro XML. Stejně tak může existovat podobný mechanismus pro mapování na JSON nebo třeba relační databázi nebo cokoli jiného. Ten objekt resp. třída může dát nějakou nápovědu, jak co mapovat (anotace JAXB, JPA atd.), ale taky to může jít úplně mimo ní a může to být v nějakém externím XML souboru, který řekne JAXB nebo JPA, jak se co mapuje.

Nebo považuješ i ten kanonický tvar za porušení zapouzdření? Svým způsobem to porušení je. Otázka jak to řešit – např. C++ má koncept přátelských tříd (friend), nebo to můžu zpřístupnit v rámci nějakého balíčku nebo modulu a pro ostatní uzavřít… Případně řídit přístup k reflexi na úrovni jazyka resp. běhového prostředí. Ale pokud má mít kdokoli možnost napsat si de/serializátor pro svůj formát, tak ta kanonická reprezentace přístupná být musí. Nevidím v tom moc problém. (ostatně kdyby ta třída v sobě měla zadrátovanou třeba metodu saveAsXml(OutputStream), tak se k datům dostanu tamtudy – ta kanonická reprezentace mi přijde určitě lepší).


Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #151 kdy: Dnes v 11:13:57 »
To je dost rozdíl oproti té serializaci do různých formátů (počet těch formátů je neomezený a předem neznámý).
No a v objektovém návrhu, jak ho chápu já, by naopak spíše objekt toužící po serializaci jiného objektu (exportu do jiného formátu...) poskytl takovému objektu objekt, pomocí kterého si to ten inkriminovaný objekt zařídí sám. Tím netvrdím, že opačný přístup je chybný, spíše bych řekl, že ve skutečnosti jen není objektový, protože narušuje zapouzdření. Ve skutečnosti může být (a také asi bude) jednodušší a efektivnější - znalost nějakých vnitřních detailů objektu může spoustu věcí usnadnit, naopak - blackboxing "za každou cenu" může vést k neřešitelným (nepředvídatelným) situacím při návrhu rozhraní.
Ona jakákoliv serializace bude v principu narušovat zapouzdření, jinak nemůže fungovat. Je jen otázka, jestli to není zapouzdřené až na úrovni toho xml, nebo už někdy dřív.
Citace
Ale to se dostáváme k samotné filosofické otázce, zda tedy vůbec OOP.
Dobrá otázka je i "Co je to vůbec OOP?". Odpověď není až tak jednoduchá :)

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #152 kdy: Dnes v 11:25:41 »
To je nepatřičná zkratka. Fyzické objekty většinou mají identitu, ta se nemění. A jejich stav se v čase může měnit (jinak by to byla konstanta), ale ten stav samotný ("otisk objektu") bude hodnotou, která je immutable, že? Nebo naopak: modifikace nějakého atributu objektu vede ke změně jeho stavu (to asi souhlasí), ale identita je zachována.

Ale asi souhlas s tím, že čím víc se vzdalujeme od matematiky (kde se pracuje s immutable hodnotami) k fuzzy reálnému světu, tím míň je funkcionální přístup přirozený.
Ta identita je jen naše abstrakce. Při bližším pohledu to drhne (např. Theseova loď nebo dědečkova sekera).

A i ten "fyzický objekt" je naše škatulka, navíc kapku neostrá.

Směřuju k tomu, že když o něčem mluvíme, tak obvykle žonglujeme s abstraktními immutable objekty, které existují leda tak v nějakém paralelním myšlenkovém nebo platonickém světě. Mapování na nějaké immutable reprezentace není nějaká matematická specialitka, děláme to úplně běžně že to ani nevnímáme.

Ano, identita je abstrakce, přesně tak. Umožňuje nám pracovat s "objekty", které se z fyzikálního hlediska mohou měnit. Jak píšeš a budu parafrázovat: identita "Jiří Havel" bezpochyby jako reprezentace objektu existuje, má mnoho referencí uložených jinde (pošta Ti doručí dopis, úřad Tě dokáže zpárovat - tedy většinou), ale třeba na úrovni molekul/atomů je to naprosto jinej objekt, než v době narození. Nicméně identita stále existuje.

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #153 kdy: Dnes v 11:33:01 »
To je dost rozdíl oproti té serializaci do různých formátů (počet těch formátů je neomezený a předem neznámý).
No a v objektovém návrhu, jak ho chápu já, by naopak spíše objekt toužící po serializaci jiného objektu (exportu do jiného formátu...) poskytl takovému objektu objekt, pomocí kterého si to ten inkriminovaný objekt zařídí sám. Tím netvrdím, že opačný přístup je chybný, spíše bych řekl, že ve skutečnosti jen není objektový, protože narušuje zapouzdření. Ve skutečnosti může být (a také asi bude) jednodušší a efektivnější - znalost nějakých vnitřních detailů objektu může spoustu věcí usnadnit, naopak - blackboxing "za každou cenu" může vést k neřešitelným (nepředvídatelným) situacím při návrhu rozhraní. Ale to se dostáváme k samotné filosofické otázce, zda tedy vůbec OOP.

Může být. Podle mého jsou legitimní oba přístupy. Ten objekt může poskytnout svoji kanonickou reprezentaci, metody pro její iterování nebo mít metody pro serializaci a deserializaci skrze nějaké abstraktní rozhraní. V obou případech ale považuji za klíčové, aby to bylo abstraktní, ne vázané na konkrétní formát.

Ty přístupy mají svoje pro a proti. Např. když ta metoda pro načtení/uložení bude v té třídě, tak ji musí někdo napsat. Zatímco když to bude řešené přes reflexi, tak to mám zadarmo, maximálně tam přidám nějakou tu anotaci, když chci něco jinak (třeba že tenhle atribut nechci v XML nebo v DB nebo že se má přejmenovat), nebo to můžu definovat na jednom místě (že chci třeba názvy v Javě jako CamelCase, zatímco v XML jako lisp-case, nebo definuji globálně formát data atd.). Může to být v externím konfiguráku nebo kódu a ty de/serializované třídy o tom vůbec nemusí vědět.

Pak můžeme narazit na problém prosakující abstrakce. I když si uděláme krásně abstraktní rozhraní, tak někdy můžeme chtít ovlivnit, jak se nějaký atribut bude v konkrétním formátu de/serializovat. To je řešitelné přes anotace (JPA, JAXB…) nebo přes externí konfiguraci (viz taky JPA nebo JAXB…) nebo tam můžu mít nějakou volnou strukturu, mapu klíč-hodnota, do které připojím nápovědu, jak to de/serializovat v konkrétním formátu (ta struktura je pořád obecná, abstraktní a klíče by měly být globálně unikátní, typicky URI).

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #154 kdy: Dnes v 11:43:59 »
Spousta těch objektů žádný protějšek v reálném světě nemá a jde čistě o konstrukt programátora… Nicméně tady bychom mohli najít třeba paralelu mezi tlačítkem na obrazovce a fyzickým tlačítkem. Ale ani to fyzické tlačítko není úplně pasivní. Zrovna co se týče zobrazení, tak to tlačítko samo nějak ovlivňuje světlo, které na něj dopadá (některé vlnové délky pohltí, jiné odrazí, některé třeba propustí skrz), a tím vytváří ten obraz. Takže to, že se tlačítko samo o sobě kreslí (místo aby se nechalo kreslit) dává smysl.* Jde ale právě o tu kanonickou reprezentaci, která je jenom jedna – kreslí se to právě jedním způsobem, negeneruje to PNG, JPEG a X dalších formátů, neobsahuje to kód kreslení pro X11, Wayland, SDL, OpenGL atd. Kreslí to např. na nějaké abstraktní plátno definované tím GUI frameworkem.
Tohle je dost blbý přístup i když potřebuju řešit subsurface scattering v tom plastu. Ve chvíli, kdy jen potřebuju vidět tlačítko, už je to naprosto zcestné.

Začíná to znít jako racionalizace toho, že cpete mutable stavy i tam, kam se vůbec nehodí. Doufám, že se v tomhle pletu.

Sice se tu diskutuje obojí, ale jsou to mimoběžná témata, řekl bych. Rozhodně nebylo záměrem tohoto komentáře podporovat nebo vyvracet nějaký názor na neměnné objekty.

Na neměnném objektu můžu mít metodu, která vyrobí konkrétní formát, stejně jako tam můžu mít metodu, která poskytne tu kanonickou reprezentaci. Totéž na objektu jehož stav se v čase mění.


Kit

  • *****
  • 889
    • Zobrazit profil
    • E-mail
Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #155 kdy: Dnes v 11:50:04 »
Ona jakákoliv serializace bude v principu narušovat zapouzdření, jinak nemůže fungovat. Je jen otázka, jestli to není zapouzdřené až na úrovni toho xml, nebo už někdy dřív.
Porušení zapouzdření je to v případě, kdy odhalují vnitřní strukturu objektu. Serializace může být na vnitřní struktuře nezávislá - poskytuje nějakou reprezentaci objektu v požadovaném formátu.

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #156 kdy: Dnes v 12:09:05 »
Ale co třeba takové:
Kód: [Vybrat]
vaha.zvazit(osoba)
osoba.zvazitSe(vaha)
Je něco z toho zjevně dobře nebo zjevně špatně?

Pokud objekt osoba zná svou váhu, tak je lepší osoba.GetVaha(). Odděluje se dotaz a vykonání, takže metoda ZvážitSe() nemá nic vracet, jen měnit vnitřní stav objektu. Tohle se odděluje proto, že při každém dalším volání ZvážitSe by se to počítalo znovu a možná s jiným výsledkem. Zásadně se odděluje část vykonání něčeho a vracení výsledku.

Stejně tak předávat váze objekt Osoba je často kravina. Ta metoda může být součástí osoby nebo získaná přes implementaci interface (třeba Golang) nebo přes dědění (Java, C++). V Golangu se ani neřeší interface (jeho jméno), prostě stačí definovat jeho metody a objekt může mít implementováno tolik rozhraní, kolik je potřeba.


Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #157 kdy: Dnes v 12:24:26 »
Pokud objekt osoba zná svou váhu, tak je lepší osoba.GetVaha(). Odděluje se dotaz a vykonání, takže metoda ZvážitSe() nemá nic vracet, jen měnit vnitřní stav objektu. Tohle se odděluje proto, že při každém dalším volání ZvážitSe by se to počítalo znovu a možná s jiným výsledkem. Zásadně se odděluje část vykonání něčeho a vracení výsledku.
Pokud metoda váhy vrací pokaždé jiný výsledek, tak to znamená, že se stav té osoby mění. Takže by se měla měnit i hodnota vracená z GetVaha. Je třeba řešit aby se správně aktualizovala ta uložená hodnota.

Pokud objekt osoba svou váhu znát nepotřebuje, tak je lepší to zvazitSe. Protože Osobě odpadá starost s udržováním aktuální váhy.

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #158 kdy: Dnes v 12:24:56 »
To je nepatřičná zkratka. Fyzické objekty většinou mají identitu, ta se nemění. A jejich stav se v čase může měnit (jinak by to byla konstanta), ale ten stav samotný ("otisk objektu") bude hodnotou, která je immutable, že? Nebo naopak: modifikace nějakého atributu objektu vede ke změně jeho stavu (to asi souhlasí), ale identita je zachována.

Ale asi souhlas s tím, že čím víc se vzdalujeme od matematiky (kde se pracuje s immutable hodnotami) k fuzzy reálnému světu, tím míň je funkcionální přístup přirozený.
Ta identita je jen naše abstrakce. Při bližším pohledu to drhne (např. Theseova loď nebo dědečkova sekera).

A i ten "fyzický objekt" je naše škatulka, navíc kapku neostrá.

Směřuju k tomu, že když o něčem mluvíme, tak obvykle žonglujeme s abstraktními immutable objekty, které existují leda tak v nějakém paralelním myšlenkovém nebo platonickém světě. Mapování na nějaké immutable reprezentace není nějaká matematická specialitka, děláme to úplně běžně že to ani nevnímáme.

Ano, identita je abstrakce, přesně tak. Umožňuje nám pracovat s "objekty", které se z fyzikálního hlediska mohou měnit. Jak píšeš a budu parafrázovat: identita "Jiří Havel" bezpochyby jako reprezentace objektu existuje, má mnoho referencí uložených jinde (pošta Ti doručí dopis, úřad Tě dokáže zpárovat - tedy většinou), ale třeba na úrovni molekul/atomů je to naprosto jinej objekt, než v době narození. Nicméně identita stále existuje.

Tak ono záleží jak moc chceme slovíčkařit a ponořit se do (z hlediska softwaru nepodstatných) detailů. Např. ty molekuly vody, ze kterých se nějaký objekt včera skládal, můžou být dneska už úplně někde jinde a patřit k jinému objektu. Kde je teď ta identita? V tom původním objektu nebo tam, kam odešla ta voda?

Ale pro potřeby návrhu softwaru je účelnější se na to dívat z nějaké přirozenější a člověku bližší perspektivy. Když někdo orazítkuje papír, tak se jeho stav změnil (nebudu si hrát na to, že dokument je pořád stejný, jen se v jeho blízkosti zrovna vyskytují molekuly barvy; nebo že v mojí představě je pořád dokument neorazítkovaný, protože jsem ho viděl naposledy včera a pamatuji si ho tak). Když se do auta natankuje benzín, tak se změní jeho stav, když se s ním jezdí, tak se mění stav tachometru… Když tam vyměním motor, tak to pořád považuji za to samé auto… Tohle jsou věci, které mne z pohledu informačního systému zajímají a které má smysl evidovat. Ten obraz reálného světa v počítači je z principu nedokonalý – jen aproximace/podmnožina zvolená tak, aby to dobře sloužilo danému účelu. V databázi si můžu historizovat předchozí stavy a v případě potřeby se na ně můžu dívat. Ale v naprosté většině případů mne zajímá aktuální stav a ne nějaká stará kopie. Pokud s tím chci v jednu chvíli pracovat z více vláken, tak to musím ve vhodnou chvíli rozkopírovat, nebo zamknout nebo obalit třídou která má jen gettery a ne settery (+ ty gettery budou obalovat i vnořené objekty). Ale to jsou technikálie. Z hlediska analýzy a návrhu eviduji nějaká měnící se data. U projektů, na kterých pracuji, se většinou v databázi vše historizuje, skoro nic se nemaže a záznamy spíš jen přibývají – to má blíž k těm neměnným objektům – ale i tam se někdy stavy mění (např. se nastaví validTo, ukončí platnost nebo se změní aktuální zůstatek - byť ty historické jinde zůstanou). Hlavně jsou ale obory a projekty, kde je zvykem ta data i v databázi vesele přepisovat a udržovat tam jen aktuální stav (a historizace se buď nedělá vůbec nebo se ukládá někam bokem pro záznam).

Trochu se omlouvám za to rýpnutí do funkcionální víry ale nedalo mi to :-) Ona je to svým způsobem úžasná věc, čistá, matematicky dokonalá. Jen to praktické využití trochu drhne (např. Lisp a Scheme úplně čisté nejsou; Haskell čistý je, jenže monády jsou utrpení a hlavně pak člověk zjistí, že velká část aplikace je právě o těch vedlejších efektech). Na jedné straně jsou analytici a uživatelé, kteří uvažují a mluví o měnících se objektech a koncept „immutable“ je jim cizí. A na druhé straně máme hardware – hodnoty registrů procesoru se mění, volají se instrukce, program/procesor obdělává paměť. Vše je proměnlivé a uprostřed toho si funkcionální programátor snaží konstruovat nějaký svůj dokonalý svět.

Nechci to úplně zatracovat, nějaké využití to má – hlavně tam, kde se řešená úloha blíží matematice. Ale došel jsem k tomu, že pro většinu softwaru lépe slouží „nečisté“ multiparadigmatické jazyky, kde toho můžu psát (asi) většinu objektově, něco procedurálně/funkcionálně, něco deklarativně.

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #159 kdy: Dnes v 12:47:43 »
Pokud objekt osoba svou váhu znát nepotřebuje, tak je lepší to zvazitSe. Protože Osobě odpadá starost s udržováním aktuální váhy.

Myslím, že jde hlavně o to, kdo ten algoritmus píše a kdy, jestli jsou algoritmy známé v době napsání té třídy nebo jestli mohou nějak nekontrolovateleně vznikat i později… a čí odpovědnost tyto algoritmy jsou (princip SRP).

Ta váha je příliš jednoduchá, proto je to zavádějící (člověk přece zná svoji váhu, je to jen jedno číslo, tak si ho může pamatovat a mít metodu, kterou nám váhu sdělí). Ale ten algoritmus může být mnohem složitější, může něco počítat rekurzivně nad celým stromem objektů a hlavně můžeme mít řadu alternativních algoritmů, můžou pracovat nad různými daty, můžeme chtít, aby je mohl definovat i někdo jiný později než byla definována daná třída. Tohle pak vede k tomu, že ten algoritmus (metoda) často patří jinam než do té třídy, nad kterou pracuje.

(taky můžeme dojít k tomu, že to je odpovědnost té třídy, nebo že chceme vědomě porušit princip SRP, ale to budou asi dost výjimky)

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #160 kdy: Dnes v 12:48:56 »
Ale pro potřeby návrhu softwaru je účelnější se na to dívat z nějaké přirozenější a člověku bližší perspektivy. Když někdo orazítkuje papír, tak se jeho stav změnil (nebudu si hrát na to, že dokument je pořád stejný, jen se v jeho blízkosti zrovna vyskytují molekuly barvy; nebo že v mojí představě je pořád dokument neorazítkovaný, protože jsem ho viděl naposledy včera a pamatuji si ho tak).
No právě. Opravdu se ten dokument mění? Je furt stejný, jen jsme k němu přidali nějaké ověření. Že je to jiný inkoust na stejném papíře je nepodstatný detail. V programu to může být druhý objekt, který se odkazuje na ten původní nezměněný dokument.

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #161 kdy: Dnes v 13:22:43 »
Ta váha je příliš jednoduchá, proto je to zavádějící (člověk přece zná svoji váhu, je to jen jedno číslo, tak si ho může pamatovat a mít metodu, kterou nám váhu sdělí). Ale ten algoritmus může být mnohem složitější ...
Právě že váha je IMO dobrý příklad. Člověk zná svou váhu jen zhruba protože ji ovlivňuje mračno věcí a mění se prakticky neustále. Takže když chce někdo vědět, kolik vážím, tak je podstatně jednodušší na tu váhu stoupnout až podle potřeby. Nemusím řešit, jak moc můj odhad oddriftoval od správné hodnoty :)

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #162 kdy: Dnes v 14:21:13 »
Trochu se omlouvám za to rýpnutí do funkcionální víry ale nedalo mi to :-)
Nejde o víru, ale o paradigma. Skrz co interpretujete svět a jaké základní kameny používáte při stavbě toho modelu.

U vás jsou to zdá se akce. Viz štempl - vidíte akci i když jejím cílem je nějak označit stav před tou akcí. Nebo ty zálohy - soustředíte se na akci zálohování ne na ten stav co chcete zazálohovat. Jako by stav systému byl jen součtem předchozích akcí.

Naproti tomu ve funkcionálním paradigmatu se soustředíte na hodnoty. Akce je jen nějaké přepnutí z jedné hodnoty na druhou.

Není to jenom o modelování matiky. Vidět posloupnost zamrzlých stavů se hodí i ve spoustě dalších případů. Transakce, atomické změny, undo, flyweight pattern, nebo třeba exception safety. Všechno to krásně pasuje na přístup, kdy vytvoříte nový zamrzlý stav a až je hotový tak na něj jen přepnete.

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #163 kdy: Dnes v 14:39:44 »
Btw asi velmi dobré porovnání OOP s funkcionálním přístupem (identity, stavy) napsal Hick Hickey https://clojure.org/about/state

Minimálně za přečtení a zamyšlení to stojí. Možná to automaticky vyřeší ten problém s "lejstrem" vs "lejstrem se štemplem" - imho je to jen otázka správného pojmenování jednotlivých abstrakcí.

Re:Přechod z Javy na Rust. Ano či ne?
« Odpověď #164 kdy: Dnes v 15:02:40 »
2/ většina jazyků lepší nástroj pro reusable kódu jak dědičnost nemá (Java), některé nemají dokonce ani rozhraní (C++) (Překvapivě takový odsuzovaný jazyk jako je PHP ano.)

Myslel som si, že nemáte skúsenosti iba s aktuálnym C++, ale vy ich pravdepodobne nemáte ani s tým základným.

O abstraktných triedach ste niekedy počuli?

To, že C++ nemá kľúčové slovo interface neznamená, že nepodporuje ten koncept, alebo že nerealizuje požiadavky, ktoré realizuje to, čo sa volá rozhranie.

Rozhranie je realizácia požiadavky a tou je definícia kontraktu.

Rozšírenie rozhrania je tiež realizáciou požiadavky a tou je prevzatie kontraktu z rozširovanej triedy a jeho doplnenie.

Obe tieto požiadavky sa dajú realizovať už od Simuly a to práve abstraktnými triedami. Bez implementácie a bez dátových zložiek.

Používa sa na to dedičnosť. Ale v jej všeobecnom význame.

Dedičnosť je vo svojej podstate prevzatie od predka. (V bežnom živote v určitej situácii.)

Zdalo sa byť rozumné použiť to slovo aj v oblasti vývoja softvéru, ktorá je analógií s bežným svetom plná. A to na opakované použitie.

A teraz je otázka: prevzatie/opakované použitie čoho?

Možnosti, čo sa v tejto súvislosti dá prevziať máte minimálne dve: iba kontrakt alebo kontrakt aj s implementáciou.

Je rozšírenie rozhrania niečím iným ako prevzatím kontraktu z rozširovaného rozhrania a jeho doplnením? Nie je.

Je dedenie abstratnej triedy niečím iným ako prevzatím kontraktu zo základnej triedy a jeho doplnením? Tiež nie je.

To, že okrem prevzatia kontraktu môžete prevziať aj implementáciu je v tomto kontexte absolútne nepodstatné. V základnej triede totiž implementácia nemusí vôbec existovať.

A v súvislosti s týmto sa už desiatky rokov hovorí o dedičnosti rozhrania a o dedičnosti implementácie.

Nakoniec, existujú o tom kvantá literatúry, napríklad už na prelome ticícročí o COM od Microsoftu.