Duck-typingDuck-typing (anglická výslovnost [dak ˈtajpiŋ], česky kachní typování) je způsob dynamického typování, kdy se posuzuje objekt nikoli z hlediska jím deklarovaných předků nebo implementovaných rozhraní, ale jen na základě jeho metod. Původ systému je přisuzován větě Jamese Whitcomba Rileyho:
Upřesnění definiceSoučasná implementace duck-typingu tak, jak byla popsána v úvodu, se od této ideje poněkud liší. Při duck-typingu se nezkoumá, zda objekt kváká jako kachna, ale posuzovatele zajímá jen, zda implementuje metodu kvákni();. Po úpravě se tedy tvrdí, že:
Objekt rozpoznaný pomocí duck-typingu se tedy chová stejně jako objekt implementující rozhraní: public interface IDuck { /** * Walk like a duck. */ public void walk(); /** * Swim like a duck. */ public void swim(); /** * Quack like a duck. */ public void quack(); } s tím rozdílem, že při duck-typingu není třeba implementovat rozhraní jako takové – stačí implementace zmíněných metod. Problémy duck-typinguJsou způsobené právě zmíněnou vlastností, kdy je zkoumáno jen rozhraní (název a datové typy metod) bez ohledu na kontrakt, předky nebo implementovaná rozhraní. Mezi kachny se tak může dostat nejen myslivec, který se rozhodl přihlásit k rozhraní IDuck (pravděpodobně z důvodu vyšší úspěšnosti lovu), ale i dítě, které má v kapse vábničku na kachny a které se kachen bojí. Z tohoto důvodu se k duck-typingu přistupuje zejména v případech, kdy je k dispozici známá množina objektů a nehrozí dezinterpretace. Pokud by se pomocí duck-typingu například hledaly Hodiny jako objekty implementující metodu public void natáhni(); mohlo by dojít k nepříjemným překvapením, pokud by mezi dostupnými třídami existovala třída Facka. DuckapterDuckapter[1] je knihovna vytvořená Vladimírem Oraným, která přináší duck-typing do programovacího jazyka Java, kde jinak nelze použít duck-typing jinak než pomocí reflexe. Knihovna vychází z již zmíněné podobnosti s implementací rozhraní. V případě zájmu o zkoumání, zda instance kachna třídy Kachna je dle duck-typingu kachnou (i když se nehlásí k implementaci rozhraní IDuck), by se volalo: boolean isDuck = Duck.test(kachna, IDuck.class); a pro použití například: if (Duck.test(kachna, IDuck.class)) { IDuck theDuck = Duck.type(kachna, IDuck.class); System.out.println(theDuck.quack()); } GroovyMnohem jednodušeji než „čistá“ Java přistupuje k duck-typingu jazyk Groovy class Duck { def walk() { println "I'm a Duck, I can walk…" } def swim() { println "I'm a Duck, I can swim…" } def quack() { println "I'm a Duck, I can quack" } } class Person { def walk() { println "I'm a Person, I can walk…" } def swim() { println "I'm a Person, I can swim…" } def talk() { println "I'm a Person, I can talk…" } } def d = new Duck() def p = new Person() d.walk() // Ok, duck has walk() method d.swim() // Ok, duck has swim() method d.quack() // Ok, duck has quack() method p.walk() // Ok, person has walk() method p.swim() // Ok, person has swim() method p.quack() // Runtime error, no quack() method Reference
Literatura
|