Diskuze: Přetěžování operátorů v Javě

Java Java Přetěžování operátorů v Javě

Avatar
Luboš Běhounek (Satik):

To je jedna z věcí, co mi na Javě vadí - nemožnost přetěžovat operátory, přijde mi pohodlnější a přehlednější napsat pro základní operace znak než celý název funkce, třeba:

if (vec == camVector)
{
    playerVec -= (vec * camVector) + transVector;
}

než třeba javovské

if (vec.equals(camVector))
{
    playerVec.subtract((vec.multiply(camVector)).add(transVector));
}
Editováno 3.5.2013 10:38
Odpovědět 3.5.2013 10:38
:)
Avatar
David Čápka
Tým ITnetwork
Avatar
Nahoru Odpovědět 3.5.2013 10:45
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Luboš Běhounek (Satik)
David Čápka:

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í.

Nahoru Odpovědět 3.5.2013 11:02
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na David Čápka
Luboš Běhounek (Satik):

Mohl bys napsat článek s (jazykovými) rozdíly mezi C# a Javou, mohlo by to být docela zajímavé :)

Nahoru Odpovědět 3.5.2013 11:12
:)
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na David Čápka
Petr Nymsa:

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");
}
Nahoru Odpovědět 3.5.2013 11:14
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Luboš Běhounek (Satik)
David Čápka:

Určitě to někdy sepíšu, ale zakážu u něj diskuzi :D

Nahoru Odpovědět  +1 3.5.2013 11:17
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Petr Nymsa
David Čápka:

Identita, tedy zda je to ten samý objekt.

Nahoru Odpovědět 3.5.2013 11:18
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na Petr Nymsa
Luboš Běhounek (Satik):

Tady porovnáváš, jestli p1 ukazuje na stejné místo jako p2, hodnoty těch objektů tě nijak nezajímají.

Editováno 3.5.2013 11:25
Nahoru Odpovědět 3.5.2013 11:25
:)
Avatar
Petr Nymsa
Redaktor
Avatar
Nahoru Odpovědět 3.5.2013 11:35
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
Kit
Neregistrovaný
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

Zřejmě proto, aby se to nepoužívalo. Nezapadá to do OOP.

 
Nahoru Odpovědět 3.5.2013 12:00
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

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.

Nahoru Odpovědět 3.5.2013 12:11
:)
Avatar
Homo
Člen
Avatar
Homo:

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.

Nahoru Odpovědět  +2 3.5.2013 13:13
1010011 1000101 1011000
Avatar
Odpovídá na Homo
Luboš Běhounek (Satik):

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)?

Nahoru Odpovědět 3.5.2013 13:36
:)
Avatar
Homo
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Homo:

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 :-)

Nahoru Odpovědět 3.5.2013 13:39
1010011 1000101 1011000
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Homo
David Čápka:

Ano, C# narůstá obrovským tempem, ve verzi 4 do něj dokonce přidali dynamické typování.

Nahoru Odpovědět 3.5.2013 13:53
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Lukáš Hruda (Luckin):

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.

 
Nahoru Odpovědět 3.5.2013 14:37
Avatar
Odpovídá na Lukáš Hruda (Luckin)
Luboš Běhounek (Satik):

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í).

Nahoru Odpovědět 3.5.2013 14:49
:)
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Lukáš Hruda (Luckin)
David Čápka:

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.

Nahoru Odpovědět 3.5.2013 14:59
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na David Čápka
Lukáš Hruda (Luckin):

Ano, ale třeba přetížení operátoru = pak nemá smysl a u == se připravíš o možnost porovnávat reference.

 
Nahoru Odpovědět 3.5.2013 15:02
Avatar
Lukáš Hruda (Luckin):

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ě.

 
Nahoru Odpovědět 3.5.2013 15:09
Avatar
Odpovídá na Lukáš Hruda (Luckin)
Luboš Běhounek (Satik):

Ž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.

Nahoru Odpovědět 3.5.2013 15:18
:)
Avatar
Odpovídá na Luboš Běhounek (Satik)
Lukáš Hruda (Luckin):

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.

 
Nahoru Odpovědět 3.5.2013 15:34
Avatar
Odpovídá na Lukáš Hruda (Luckin)
Luboš Běhounek (Satik):

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í.

Nahoru Odpovědět 3.5.2013 15:39
:)
Avatar
Odpovídá na Luboš Běhounek (Satik)
Lukáš Hruda (Luckin):

Š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?

 
Nahoru Odpovědět 3.5.2013 16:01
Avatar
Odpovídá na Lukáš Hruda (Luckin)
Luboš Běhounek (Satik):

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 :D

Nahoru Odpovědět 3.5.2013 16:23
:)
Avatar
Luboš Běhounek (Satik):

Jednoduše řečeno se objekty v Javě/C# se předávají jako reference předávaná hodnotou :)

Nahoru Odpovědět 3.5.2013 16:27
:)
Avatar
Odpovídá na Luboš Běhounek (Satik)
Lukáš Hruda (Luckin):

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 :)

 
Nahoru Odpovědět 3.5.2013 16:38
Avatar
Odpovídá na Lukáš Hruda (Luckin)
Luboš Běhounek (Satik):

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.

Nahoru Odpovědět 3.5.2013 19:03
:)
Avatar
Odpovídá na Luboš Běhounek (Satik)
Lukáš Hruda (Luckin):

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í.

 
Nahoru Odpovědět 3.5.2013 20:20
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 30 zpráv z 30.