Diskuze: Přetěžování operátorů v Javě
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 30 zpráv z 30.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
Nevím o tom Ono by na toto
téma šlo dlouze argumentovat že je pootm nepřehledné co vlastně operátor
dělá, jestli porovnává identitu nebo stav, ale co se týče čitelnosti
kódu, tak je to neskutečné plus. Pochybuji o tom, že to přidají.
Mohl bys napsat článek s (jazykovými) rozdíly mezi C# a Javou, mohlo by
to být docela zajímavé
Když už se tu o tom bavíte, došlo mi že mi něco uniklo. Když u vlastní třídy nepřetížím operátor, co se vlastně porovnává ?
class Clovek
{
public int vek;
}
main()
{
Clovek p1=new Clovek(){vek=8;}
Clovek p2=new Clovek() {vek=18}
if(p1==p2) Console.WriteLine("Bazinga");
}
Určitě to někdy sepíšu, ale zakážu u něj diskuzi
Tady porovnáváš, jestli p1 ukazuje na stejné místo jako p2, hodnoty těch objektů tě nijak nezajímají.
Zřejmě proto, aby se to nepoužívalo. Nezapadá to do OOP.
Proč to nezapadá do OOP?
Já v tom žádný problém nevidím, nenapadá mě žádný důvod, proč by
přetěžování operátorů nějak odporovalo OOP.
K pretezovani operatoru
http://java.dzone.com/…eed-operator
K rozdilum javy a c#
Myslim ze to dobry napad neni, musel by to napsat nekdo kdo dela Javu a C#
minimalne 2 roky a zna novinky a neni vysazeny na jeden jazyk. Napsat to
objektivne bez zaujati to pro zdejsi komunitu bude slozite (nechci se nikoho
dotknout, ale je to holy fakt). Vsechny porovnani co jsem videl tak v necem
pravdu meli a v necem zase ne protoze vychazeli ze starych verzi.
Clanek samotny me nepresvedcil vubec, ale jeden nazor v diskuzi ano - ze se snazi udrzet Javu jednoduchou (ze Java byla reakce na slozitost C++).
S timto argumentem mi to dava smysl, souhlasite s nim (Javiste)?
V komentech byvaji vetsinou rozumnejsi nazory
Ano s tim argumentem souhlasim. Podle meho nazoru C# tech syntaktickych veci ma
zbytecne az moc. Ale nejspis je to jen o zvyku
Ano, C# narůstá obrovským tempem, ve verzi 4 do něj dokonce přidali dynamické typování.
Imho v těchhle jazycích je přetěžování operátorů značně limitováno tím systémem referencí. Ale třeba v C++ to funguje dokonale.
Myslím, že to ten systém referencí nijak nelimituje C# s tím problém
nemá, je to jen featura jazyka.
Třeba v C# se operátor + u stringů přeloží vnitřně na funkci Concat()
(takže můžeš použít ke spojování obojí).
Reference s operátory nijak nesouvisí. Operátor se vztahuje ke 2 instancím, jestli se k nim dostaneš referencí nebo kopií nebo pointerem je úplně jedno, ve finále máš vždy na vstupu 2 instance.
Ano, ale třeba přetížení operátoru = pak nemá smysl a u == se připravíš o možnost porovnávat reference.
Navíc se přetěžování operátorů perfektně doplňuje s konverzními (popř. kopírovacími) konstruktory a konverzními funkcemi, což v systému referencí nemůže existovat, nebo jen velmi krkolomně.
Že se nedá přetížit = jsem u C# docela rád, přece jenom tam
by to mohlo člověka mást, ale můžeš přetížit konverze.
Přetížením == se nepřipravíš o možnost porovnávat reference,
pořád tam budeš mít funkci ReferenceEquals(), kterou dědí (automaticky)
všechny třídy od Object.
Ano ale bude to už asi méně přirozené, když defaultně se to dělá operátorem ==. Operátor = by šel přetížit pouze pro primitivní typy, počítám že i ty konverze fungují pouze na primitivní typy.
Teď tě moc nechápu, chceš operátor == přetížit a zároveň ho použít k porovnání referencí? Jak by pak poznal, které porovnání má použít?
V C# přetížené konverze fungují na libovolnou třídu, i na neprimitivní.
Špatně jsem se vyjádřil, myslel jsem to tak, že operátor == se
defaultně používá pro porovnání referencí, tedy je přirozené ho pro
tento účel použít. Pokud ho přetížíš, budeš muset reference
porovnávat jinak, což není tolik přirozené.
Jak to konkrétně funguje když se objekty předávají referencí? Snad ta
konverze nevytváří nový objekt?
Ono se v C#/Javě reference moc často neporovnávají, mnohem častěji se porovnávají hodnoty, takže by to ani tak nevadilo, že si (v C#) == přetížíš.
V C# i Javě se parametry předávají hodnotou.
Ale objekt se nekopíruje, kopíruje se jen reference na něj -> když
změníš jakoukoliv vlastnost oběktu kdekoliv ve funkci, tak mu ji změníš i
"mimo tu funkci".
C# navíc umí předávání referencí. Nejlíp asi když to ukážu na
příkladu:
...
Point o = new Point(5,5);
foo(o);
//tady je o stále platný Point a o.x je 10
...
private void foo(Point p)
{
p.x = 10;
p = null;
}
...
Point o = new Point(5,5);
bar(ref o);
// tady je o null
...
private void bar(ref Point p)
{
p = null;
}
Btw jsme zas lehce offtopic, možná by nebylo na škodu diskuzi přesunout
Jednoduše řečeno se objekty v Javě/C# se předávají jako reference
předávaná hodnotou
To vím, ale jak pak uděláš tu konverzi? Nebo chceš říct že se konvertuje jenom reference a objekt zůstává, protože pro konverzi je, pokud vím, potřeba vytvořit nový objekt. Lépeřečeno:
class T1 {}
class T2 {}
T1 obj1 = new T1();
T2 obj2 = new T2();
Řekněme že je definována konverze z T1 na T2, co pak provede následující kód?
obj2 = obj1;
popřípadě:
public void function(T2 obj){}
...
function(obj1);
Řekl bych, že zase až tak offtopic nejsme
Jo takhle to myslíš
Takhle jednoduše napřímo u tříd, které nemají nic společného, to (pokud vím) v C# nejde. Musely by ty třídy T1 a T2 mít něco společného, buďto třeba předka (na kterého bys přetypovával) nebo třeba rozhraní, ale takhle dva obecné objekty asi úplně jednoduše nejdou.
Možná by to nějak šlo přes pointery v unsafe kódu nebo přes třídu Marshal (http://msdn.microsoft.com/…marshal.aspx ), ale s tím nemám moc zkušeností, zatím jsem to krom několika malých případů nepotřeboval.
Ano, přesně tak jsem to myslel, v C++ totiž můžeš definovat konverzi na cokoliv, stejně tak můžeš mít konverzní konstruktor nebo přetížený operátor = pro cokoliv. Konverze z potomka na předka je samozřejmost, i když v C++ je to poněkud složitější, ale platí to v podstatě stejně, alespoň u pointerů a referencí.
Zobrazeno 30 zpráv z 30.