Jde o to, co myslíte tím hraním s polymorfismem. Já to chápu tak, že byste očekával následující význam:
ArrayList<String> al = new ArrayList<String>();
Jenže většina programátorů chce být na nějaké hrátky s polyformismem připravená, a tak očekávají
List<String> al = new ArrayList<String>();
V tom druhém případě by to ale znamenalo, že by se do popisu jazyka dostala tvrzení jako "třída java.util.ArrayList je implementací rozhraní java.util.List". A to tvůrci jazyka nechtěli.
A v cem to zhorsuje citelnost? Zapis s var je dobry tak maximalne pro privatni promene v metode. Tech se zas tak moc netvori, kamkoli jinam stejne date rozhrani misto implementace proto, aby bylo mozne nasazovat mocky a cely kod testovat. Nehlede na to typ promene urcujete az podle prirazeni coz mi prijde dost hruzne a naopak daleko hure citelne, protoze musite precist cely radek byste vedel o co vlastne jde, jinak vam staci precist pouze kus radku do znaku =.
Ok, dam priklad z praxe.
Drajver z oraclu. Vypytam si od neho prepared statement
PreparedStatement xy = connection.prepareStatement("Blabla");
Automaticky som cakal, ze byde typu OraclePreparedStatementm ale nie OraclePreparedStatement je az fieldom OraclePreparedStatementWrapper. Ok, takze reku, ze uz ho mam. Ale ono to zasa bolo typu T4CPreparedstatement, ktory dedi od OraclePreparedStatement.Tak ok, zasa som potreboval ziskat subclassu a z nej fieldy a tie az mi na nieco boli dobre.
Vsimnite si ten maglajz v predchadzajucom odstavci, zda sa to ako bluznenie, ale je to pravda .Proste potreboval som sa v tom vrtat a nejake veci si vytiahnut pomocou reflexie a zalogovat.
Ano chapem vyuzitie rozhrani v dependency injection, na ktore narazate. Predsalen tam sa to s tymi rozhraniami az tak neprehana a je to zrozumitelnejsie.
Ale vyuzivanie polymorfizmu v jave niekedy sposobuje, ze by si clovek radsej vyskriabol oko. Skratka niekedy sa veci zbytocne komplikuju, aj ked nemusia.
Ale to nie je o docitani riadku, ale o debugovani a rypani sa v neprehladnom kode.
Preto mi ten zapis, neprijde taky uleteny.
var a = new LinkedList<String>()
by znamenalo
LinkedList<String> a = new LinkedList<String>().
A co?
var a = new LinkedList<String>() // by znamenalo LinkedList<String> a = new LinkedList<String>().
imho neco takoveho v staticky typovanem jazyce nema co delat.
staci si vzit nejaky kod typu:
var foo = bar.baz();
a bez IDE clovek stravi pul dne hledanim, co to je vlastne za hodnotu.
A bez tech IDE se poserete z toho psani
LinkedList<String> a = new LinkedList<String>();
Jako opicka opisujete, opisujete a vubec to neni citelne. Jen dalsi tuna naprostu zbytecneho balastu. Nastesti jini maji mozek a pri navrhu staticky typovaneho jazyka tohle zavrhli ci zminimalizovali nutnost to psat. Doporucuji se podivat na Scalu.
A co dela clovek pul dne bez IDE? Ja casto byvam bez IDE i mnohem dele :D ale to je mi pak jedno jaka hodnota to je, protoze bez IDE proste delam neco jinyho (treba spim nebo jdu ven). Situace ze bych chtel programovat a nemel IDE samozrejme nastat muze, treba vypadek proudu, ale pak bych nemel ani ten kod.
Jinak pro lokalni promenne absolutne nema smysl resit jestli to bude List nebo krasne podle zasad LinkedList. V okamziku kdy budu potrebovat interface, tak to proste zmenim.
Ale tady resite problem navratove hodnoty a nikoli deklarace promene. To jsou dva naprosto odlisne pripady.
--
Ja bych ocekaval z tohohle DB2PreparedStatement a nekdo jiny zase ODBCPreparedStatement. A nejprve by bylo potreba se prohrabat tunou predchoziho kodu, aby clovek vlastne zjistil o jakou connection se jedna a co mu muze vracet.
--
A co by znamenalo?:
var a;
if (cokoli) {
a = LinkedList<String>();
} else {
a = HashSet<String>();
}
A jak byste pak kod refaktroval? A IDE by vam navrhovalo metody objektu podle ceho?
A co třeba se inspirovat u konkurence? Když se konkurence mohla inspirovat od Javy
void Correct()
{
var v = new List<string>();
v.Add("Test");
}
==> O.K.
void Incorrect(bool b)
{
var v;
if (b)
v = new List<string>();
else
v = new HashSet<string>();
v.Add("Test");
}
==> Error CS0818: An implicitly typed local variable declarator must include an initializer
No nevím, ale tady podle mě nejde o polymorfismus. ArrayList není potomkem Listu, ale je to jeho implementace. Tady se jedná o oddělení rozhraní od implementace.
K tomu var bych řekl, že v javě se to tak prostě nepíše a nevidím důvod proč tam cpát každý jazykový konstrukt, který existuje jinde. Na platformě Java existují jazyky kde to tak psát jde(Scala, Groovy, Jython ...), tak komu to vadí ať použije je.