Projekt D7VK dospěl do verze 1.0. Jedná se o fork DXVK implementující překlad volání Direct3D 7 na Vulkan. DXVK zvládá Direct3D 8, 9, 10 a 11.
Byla vydána nová verze 2025.4 linuxové distribuce navržené pro digitální forenzní analýzu a penetrační testování Kali Linux (Wikipedie). Přehled novinek se seznamem nových nástrojů v oficiálním oznámení na blogu.
Národní úřad pro kybernetickou a informační bezpečnost (NÚKIB) zveřejnil Národní politiku koordinovaného zveřejňování zranitelností (pdf), jejímž cílem je nejen zvyšování bezpečnosti produktů informačních a komunikačních technologií (ICT), ale také ochrana objevitelů zranitelností před negativními právními dopady. Součástí je rovněž vytvoření „koordinátora pro účely CVD“, jímž je podle nového zákona o kybernetické … více »
Vývojáři KDE oznámili vydání balíku aplikací KDE Gear 25.12. Přehled novinek i s náhledy a videi v oficiálním oznámení.
Společnost System76 vydala Pop!_OS 24.04 LTS s desktopovým prostředím COSMIC. Videoukázky na YouTube.
Byla vydána verze 1.92.0 programovacího jazyka Rust (Wikipedie). Podrobnosti v poznámkách k vydání. Vyzkoušet Rust lze například na stránce Rust by Example.
Free Software Foundation zveřejnila ocenění Free Software Awards za rok 2024. Oceněni byli Andy Wingo, jeden ze správců GNU Guile, Alx Sa za příspěvky do Gimpu a Govdirectory jako společensky prospěšný projekt.
Bylo vydáno Eclipse IDE 2025-12 aneb Eclipse 4.38. Představení novinek tohoto integrovaného vývojového prostředí také na YouTube.
U příležitosti oslav osmi let prací na debianím balíčku vyšlo GPXSee 15.6. Nová verze přináší především podporu pro geotagované MP4 soubory, včetně GoPro videí. Kdo nechce čekat, až nová verze dorazí do jeho distribuce, nalezne zdrojové kódy na GitHubu.
Monado, tj. multiplatformní open source implementace standardu OpenXR specifikujícího přístup k platformám a zařízením pro XR, tj. platformám a zařízením pro virtuální realitu (VR) a rozšířenou realitu (AR), bylo vydáno ve verzi 25.1.0. Přehled novinek v poznámkách k vydání.
Řešení dotazu:
class Zvíře {
public void hlas() {
System.out.println("Co to?");
}
public void hlasDvakrat() {
this.hlas();
this.hlas();
}
}
class Pes extends Zvíře {
@Override
public void hlas() {
System.out.println("Haf!");
}
}
class Pudl extends Pes {
@Override
public void hlas() {
System.out.println("Hif hif");
}
}
Zvíře zvíře = new Pudl();
zvíře.hlasDvakrat();
//vypíše 2× "Hif hif"
Mohl byste si myslet, že zvíře.hlasDvakrat(), která je definovaná ve třídě Zvíře, bude volat metodu hlas() ze „své“ třídy, ale tak to není – voláte metodu hlas() na instanci třídy Pudl, takže se zavolá metoda, která je v hierarchii tříd nejbližší Pudlovi (postupuje se jen směrem k rodičům) – a to je metoda přímo ve třídě Pudl. Kdyby ve třídě Pudl nebyla ta metoda překrytá, postupuje se výš a najde se ve třídě Pes. Kdybyste tam nevytvořil instanci Pudla, ale Psa, začne se od něj a metoda se najde tam, takže by to vypsalo 2× „Haf!“.
No a pokud v té rodičovské metodě chcete mít možnost zavolat i ten svůj původní kód, dáte ho do nějaké privátní metody a tu pak převoláte z té metody, která je překrytelná. Pak si při volání vyberete, kterou metodu použijete, podle toho, zda chcete použít ten váš kód, nebo kód, který mohl někdo v potomcích přetížit.
class Zvíře {
public void hlas() {
this.hlasImpl();
}
private void hlasImpl() {
System.out.println("Co to?");
}
public void hlasDvakrat() {
this.hlas();
this.hlas();
//nebo
this.hlasImpl();
this.hlasImpl();
}
}
private versus všechno ostatní) mění chování kódu. Tady je příklad:
public class Blah {
private static class Parent {
public void write() { writeOne(); writeTwo(); }
private void writeOne() { System.out.println("private parent"); }
protected void writeTwo() { System.out.println("protected parent"); }
}
private static class Child extends Parent {
private void writeOne() { System.out.println("private child"); }
protected void writeTwo() { System.out.println("protected child"); }
}
public static void main(String[] unused) {
new Parent().write();
new Child().write();
}
}
$ javac Blah.java $ java Blah private parent protected parent private parent protected child
@Override, díky které může překladač kontrolovat, že nepřekrýváte metodu omylem, nebo že naopak nevytváříte novou metodu tam, kde jste chtěl metodu jenom překrýt.
V tomto ohledu je Java trochu prase, protože změna klíčového slova přístupu (private versus všechno ostatní) mění chování kódu.Kdyby jenom
private metody. U package private metod záleží na tom, v jakém package třída je.
@Override nepomůže.
@Override.
@Override). V některých jazycích se explicitně určuje, co je překrytelná (virtuální) metoda, což u Javy nemá moc význam, protože překrytelné jsou všechny metody, které potomek „vidí“.
final slouží k tomu, aby bylo možné zakázat překrytí metody, která by jinak podle pravidel mohla být překryta. Existuje v Javě opačné klíčové slovo, které by umožnilo překrýt metodu, která by jinak nemohla být překryta?
final, takže je evidentní, že jsem v předchozím komentáři psal o těch metodách, které final nemají.
final, a tím těžko odlišíte čtyři různé stavy.
@Override, tedy pokud ji důsledně používáte, berete vážně varování kompilátoru, považujete za řešení upozornění na konflikt jmen a nutnost změny názvu, a pokud při změně knihovny vždy znovu zkompilujete aplikaci. Ale pořád je to lepší, než drátem do oka… A běžné chyby, kdy člověk při psaní kódu omylem překryje něco, co nechtěl, nebo naopak vytvoří novou metodu místo překrytí té z potomka, to odhalí spolehlivě.
To chovani je zcela prizorebe, jak by to podle vas melo fungovat, aby to nebylo "prase"?
Ne, to není přirozené. Ve světě pokřiveném Javou možná ano, ale jinak ne. Všude jinde platí přirozená zásada, že klíčové slovo určující přístupová práva a zapouzdření nemůže samo o sobě změnit chování kódu. Změna takového klíčového slova může samozřejmě způsobit, že se kód nepřeloží (když někdo k metodě ztratí přístup), ale neměla by nikdy nenápadně a bez varování změnit chování kódu. V tomto ohledu je tedy Java prase.
Jak by to mělo fungovat? Jako v C++, ideálně. Odstavec zvaný „Guideline #2: Prefer to make virtual functions private.“ velice pěkně ilustruje, o co se jedná a k čemu to může být užitečné. Že jediná možnost, jak vyrobit v Javě (de facto) nevirtuální metodu, je private metoda, to je zkrátka smutné (chro chro).
Nevirtuální metody v C++ mají při dědičnosti spoustu hezkých aplikací v případech, kdy se chování přetížené metody podstatně liší od původní implementace a kdy je cílem, aby se metoda na všech objektech z dané hierarchie tříd chovala podle toho, co si volající myslí, že daný objekt je, nikoliv podle toho, o kolik generací dědičnosti složitější je ve skutečnosti volaný objekt. Tohle představuje celkem rozsáhlou třídu design patterns, které v Javě buď vůbec neexistují, nebo jsou dosažitelné jedině lámáním přes koleno.
Jakákoliv obdoba operátoru instanceof vyžaduje alespoň RTTI nebo případně rovnou runtime jako má Java. Není to tedy univerzálně použitelné řešení. instanceof je taková poloreflexe, která všeho všudy ukazuje na chyby v návrhu a na zatloukání čtvercových kolíků do kruhových děr. A právě proto to není jedno. Když chci nevirtuální metodu, nechci ji smolit pomocí několika krypticky pojmenovaných protected, které budou povinně virtuální, jenže co naplat, když chci, aby je potomci viděli, a nebudu při každém volání něco větvit na základě instanceof. Tyhle zlozvyky z Javy mě pokaždé spolehlivě zvednou ze židle až ke stropu.
Ano, bavíme se skutečně o překrývání. Přetěžování se týká parametrů předávaných „zprava“, zatímco překrývání se týká parametru předávaného „zleva“ (this).
instanceof neobhajuji. Je to jen berlička pro ty, kteří neumí pracovat s polymorfismem.
Jakákoliv obdoba operátoru instanceof vyžaduje alespoň RTTI nebo případně rovnou runtime jako má Java.Ve skutečnosti to vyžaduje triviální odkaz na informace o třídě, což ale vyžaduje i virtualizace metod.
která všeho všudy ukazuje na chyby v návrhuTo jsou ovšem bez konkrétních příkladů a velmi dobrého zdůvodnění jen prázdná slova.
a na zatloukání čtvercových kolíků do kruhových děr.Na zatloukání čtvercových kolíků do kruhových děr nevidím nic špatného, ty díry jsou tam od toho, aby byl na kolíky trochu prostor, ne aby byly dokonale stejné. Teda aspoň pokud se bavíme o zatloukání kolíků do hlíny. Hromada řečí, argumenty žádné.
private metody rodiče. Překrýt je ale nemůže. V Javě se prostě to, zda metoda je nebo není virtuální, odvozuje pomocí určitých pravidel z ostatních vlastností té metody. Což na jednu stranu zjednodušuje jazyk (programátor nemusí vědět nic o virtuálních metodách a v obvyklých případech to funguje tak, jak by intuitivně očekával), na druhou stranu to opravdu není úplně čisté řešení. A ještě horší je to na straně potomků, protože tam se to, zda metoda jinou metodu překrývá nebo ne, může změnit, aniž byste ve svém kódu udělal jedinou změnu.
Bud metodu predka ve sve metode vyuziva a vola ji pres super, nebo ji vubec nevyuziva a svoji samostatnou implementaci.O tohle nejde, problém je v opačném směru – pokud kód předka volá překrytou metodu. Normálně by přidání nové metody do rozhraní nemělo být závažnou změnou kontraktu a mělo by být zpětně kompatibilní. Jenže se může stát, že se ta nová metoda zrovna „trefí“ do metody, která už je v potomkovi definovaná, a tím pádem ta metoda v potomkovi najednou nechtěně překryje metodu předka – a bude volána v kontextu, v jakém to nebylo zamýšleno.
public class Rodic {
public void run() {
step1();
step2();
step3();
}
protected void step1() {
}
protected void step2() {
}
protected void step3() {
}
}
Aplikace
public class Dite {
protected void validate() {
}
}
Knihovna verze 2:
public class Rodic {
public void run() {
validate();
step1();
step2();
step3();
}
protected void step1() {
}
protected void step2() {
}
protected void step3() {
}
protected void validate() {
}
}
Dite má být Dite extends Rodic. Ale jinak je snad jasné, o co jde – aplikace si ve třídě Dite nadefinuje nějakou metodu (zde validate()) pro tuto třídu a její potomky, ta metoda nemá nic společného s rodičovskou třídou. Když ale v rodičovské třídě v další verzi knihovny přibyde virtuální metoda validate() se správnou signaturou, ta metoda Dite.validate() najednou bude překrývající metodou. Přitom ta metoda může dělat něco úplně jiného, překrytí nebyl záměr, a dokud se ten kód třídy Dite znovu nezkompiluje, tak se o tom ani nedozvím. Přitom změna v té knihovně byla zdánlivě zpětně kompatibilní a neměla by rozbít žádný stávající kód.
Duck extends Bird. Kachna je ptákem. Má křídla jako pták, létá jako pták, ale vydává jiné zvuky než ostatní ptáci. Proto je metoda pro pípání překryta metodou pro kvákání.
A teď: Je nějaký důvod, proč by měla kachna pípat? Není. Proto ani není důvod, proč by se měla volat metoda rodiče, pokud je překryta.
metoda rodiče, pokud je překrytaA v tom je právě ten problém. Já napíšu kód, který metodu rodiče nepřekrývá, a aniž bych ho změnil, najednou nějakou metodu rodiče překrývá.
protected místo praktičtějšího private. S tím by se to přece nemohlo stát.
final...
public class Bird {
public static void main(String[] args) {
Bird bird = new Duck();
System.out.println(bird.sing());
}
public String sing() {
return "Beep";
}
}
class Duck extends Bird {
@Override
public String sing() {
return "Quack";
}
}
"Rodičovský podobjekt nemůže poslat překrytelnou zprávu sám sobě. Jakoukoliv překrytelnou zprávu totiž musí poslat znovu „nejvnějšnější“ instanci, v jejíchž útrobách se nachází (dceři, vnučce, pravnučce–prostě té, která už není ničím rodičovským podobjektem)."Materiály rituálně spálit a v případě elektronické podoby rozmlátit médium kladivem. Nejsem nějaký javista, ale pokud vím, tak si zprávy posílají (prostřednictvím volání metod) objekty. Pojem podobjekt dává smysl snad jen v datovém smyslu a chápal bych to u nějakého hrubšího jazyka jako je C nebo C++, ale možná se pletu. Vnější a vnitřní instance a tedy i nejvnějšnější instance mi připadají jako prázdné pojmy. Mám instanci (obecněji objekt), na tu se můžu dívat jako na instanci třídy, kterou skutečně je, nebo jako na instanci některé z nadřazených tříd v hierarchii dědičnosti. Volat metody může kdokoli, kdo ví o dané instanci. Volat může takové metody, které jsou definovány pro třídu pod kterou instance momentálně vystupuje. Ten popis mi připadá jako kdyby používal úplně jinou abstrakci než je v OOP běžná, a které je bližší spíše nějakému fyzickému paměťovému modelu. Ano instance podtřídy opravdu typicky musí nějak uložit podobjekt odpovídající nadtřídě. Ale psát, že tomu podobjektu něco posílá je úplně zbytečná personifikace. Pokud chce člověk mluvit v jazyce hardware, provádějí se instrukce a ukládá se na paměťová místa, pokud chce člověk mluvit v jazyce návrhu, „komunikují“ mezi sebou celé objekty pomocí metod, ale tenhle kočkopes je dobrý možná tak pro vývojáře VM.
Tiskni
Sdílej: