Java - Method Chaining

Otazkar

Java - Method Chaining
« kdy: 15. 02. 2017, 09:19:36 »
Ahojte,
Zacinam s Javou a neviem preklenut jeden problem.. Vseobecne nieje mozne pretazit return hodnotu, napr.

Kód: [Vybrat]
public byte foo(byte input);
public short foo(byte input);

Avsak, mam moznost pouzit:

Kód: [Vybrat]
public class PCLASS{
    private byte input;
public PCLASS foo(byte input, short size){
   
    switch(size)
        byte... size = 1;
        short... size = 2;
        int... size = 4;
   
    this.input = input + (1 * size);
    return this;
}
public byte returnByte();
     return this.input;
}

public short returnShort();
     return (short)this.input;
}

z coho dostanem:

Kód: [Vybrat]
    (11)(byte) = foo(10, 1).returnByte();
    (12)(short) = foo(10, 2).returnShort();
   

Je mozne v Jave spravit nasledovne, a to zistit aky je volana nasledovna metoda, .return*(), a podla toho vyhodnotit hodnotu pre foo()?

Kód: [Vybrat]
    (11)(byte) = foo(10).returnByte();
    (12)(short) = foo(10).returnShort();
   

Snad som sa spravne vyjadril.
« Poslední změna: 15. 02. 2017, 11:45:43 od Petr Krčmář »


Kit

Re:Java - Method Chaining
« Odpověď #1 kdy: 15. 02. 2017, 09:32:07 »
Udělej si 3 třídy a máš pokoj. Zmizí tím i ten ošklivý switch.

Re:Java - Method Chaining
« Odpověď #2 kdy: 15. 02. 2017, 09:40:53 »
Z příspěvku není jasné, na co se vlastně ptáte. Každopádně to, o co se snažíte, je divné – raději popište, jaký problém chcete vyřešit. Také by pomohlo, když se ptáte na konkrétní programovací jazyk, uvést skutečný kód a ne jen nějaký pseudokód, u kterého není jasné, zda třeba textem „(byte)“ myslíte přetypování, nebo je to jen jakási poznámka.

Jinak v Javě není možné mít metody, které by se lišily jenom návratovým typem. Když kompilátor překládá kód a narazí na volání metody, vyhodnocuje jen název metody a počet a typ jejích parametrů, nezajímá se o to, co se bude dít s návratovou hodnotou (s lambda výrazy už to není úplně pravda, ale tím si to zatím nekomplikujte). Takže u metod, které se liší jen návratovým typem, by neměl jak rozlišit, kterou metodu chcete volat.

Mimochodem, podívejte se také na to, jaké se v Javě používají konvence – např. názvy tříd začínají velkým písmene a používá se CamelCase.

Re:Java - Method Chaining
« Odpověď #3 kdy: 15. 02. 2017, 09:52:16 »
Tak jak je otázka položená je odpověď jasná: java.lang.Number (místo returnShort je shortValue apod, ale to snad není problém).

Co je tak opravdová otázka za tím, to mi skutečně jasné není (jako ostatní kdo zatím reagovali).

Mimochodem: který jazyk má overloading podle návratové hodnoty? Znám jazyky které mají "out" a overloading, ale to není úplně totéž.

v

Re:Java - Method Chaining
« Odpověď #4 kdy: 15. 02. 2017, 09:57:19 »
Mimochodem: který jazyk má overloading podle návratové hodnoty? Znám jazyky které mají "out" a overloading, ale to není úplně totéž.
haskell :)


Otazkar

Re:Java - Method Chaining
« Odpověď #5 kdy: 15. 02. 2017, 10:29:50 »
Samozrejme, konvencie o programovani su mi dobre zname (nepredpokladal som ze by to niekto vytkol pri takom kuse kodu, ale dobre). Vysklitla sa zalezitost, ktoru je nutne implementovat v Jave a s tou skusenosti take nemam.

public class Calculator {

private byte [] buffer;

    Calculator(){}
   
    public Calculator calc(short value, short size){
        /* size - 1/2/4 */
        buffer = new buffer[size]; /* check na zaporne cislo alebo nenulovu hodnotu ...*/
       
        for(short cnt = 0;cnt < buffer.lenght; cnt++){
            buffer[cnt] = (value + cnt);
        }
        return this;
    }
   
    public byte returnByte(){
        return buffer[0];   
    }
   
    public short returnShort(){
        return (short) ((buffer[1] << 8) | buffer[0]); 
    }   

}

int main(){

    Calculator calculator = new Calculator();
   
    short shortVal = calculator.calc(10, 2).returnShort();
    byte byteVal = calculator.calc(10, 1).returnByte();

    return 0;
}


je mozne, nejakym postupom spravit -- v MAIN

public class Calculator2 {

private byte [] buffer;
private short size = 0;

    Calculator(){
    }
   
    public Calculator calc(short value){
        /* size - 1/2/4 */
        /* size je zistena z volania metody returnShort() alebo returnByte()*/
        ???? short size = je odpoveda z....
       
        buffer = new buffer[size]; /* check na zaporne cislo alebo nenulovu hodnotu ...*/
       
        for(short cnt = 0;cnt < buffer.lenght; cnt++){
            buffer[cnt] = (value + cnt);
        }
        return this;
    }
   
    public byte returnByte(){
        this.size = 1;
       
        return buffer[0];   
    }
   
    public short returnShort(){
        this.size = 2;
       
        return (short) ((buffer[1] << 8) | buffer[0]); 
    }   

}

int main(){

    Calculator2 calculator = new Calculator2();
   
    short shortVal = calculator.calc(10).returnShort();
    byte byteVal = calculator.calc(10).returnByte();

    return 0;
}

Nakolko vsak volanie je:
    Najprv sa zavola calculator.calc(10), kde je vypocet hodnoty calc(), nasledne potom .returnShort() kde sa vracia hodnota.
    Je mozne zistit v calc() aka je volana nasledovna metoda, aby calc() mohlo pracovat s hodnout SIZE 2?



Re:Java - Method Chaining
« Odpověď #6 kdy: 15. 02. 2017, 10:46:28 »
Za prvé – pokud size nabývá omezené množiny hodnot, je nevhodné reprezentovat ho jako obecné číslo. Nemůžete pak datovým typem (deklarativně) vyjádřit potřebná omezení, místo toho je musíte popsat v dokumentaci a v kódu pak imperativně kontrolovat. Místo toho je lepší použít enum, tam přesně určíte seznam přípustných hodnot.

Je mozne zistit v calc() aka je volana nasledovna metoda, aby calc() mohlo pracovat s hodnout SIZE 2?
Ne, to možné není. Ale pořád není jasné, jaký problém vlastně řešíte. Vaše třída Calculator vypadá, jako by byla vytvořená podle vzoru builder. Ten ale zpravidla funguje tak, že si průběžně jen ukládáte konfigurační hodnoty (metoda calc() by tedy jen poznamenala požadovanou velikost) a teprve závěrečná „budovací“ funkce provede to skutečné vytvoření objektu.

Pokud to nemá být builder, měl byste mít dvě třídy ByteCalculator a ShortCalculator, které mohou mít společné rozhraní. Protože vy ten typ objektu fixujete už v okamžiku vytvoření, bylo by špatně vytvořit Calculator se size=1 a pak volat returnShort().

Případně můžete použít generiky a nadefinovat objekt Calculator<T extends Number> s metodou T returnValue() a size odvozovat z předaného typu.

none_

Re:Java - Method Chaining
« Odpověď #7 kdy: 15. 02. 2017, 10:52:31 »
Metoda calc nema sanci zjistit, co budete volat potom. Pokud je vypocet zmenen tou druhou metodou, odlozte vypocitet az do te metody. Takovej pattern builder (vsechny metody jenom nastavuji calculator, vypocet se provede az na konci).

Otazkar

Re:Java - Method Chaining
« Odpověď #8 kdy: 15. 02. 2017, 10:59:32 »
Filip Jirsák, dakujem za vycerpavajucu odpoved, postrcil ste ma spravnym smerom.

Dakujem za odpovede

Petr

Re:Java - Method Chaining
« Odpověď #9 kdy: 15. 02. 2017, 11:37:11 »
Jen tak pro zajimavost: Kterou cestou jste se vydal? Builder, polymorfismus nebo generika?

none_

Re:Java - Method Chaining
« Odpověď #10 kdy: 15. 02. 2017, 16:42:10 »
Rekl bych, ze zalezi na pouziti.
Pokud vytvorim instanci urciteho type a pak budu 100x volat returnValue() a chci vzdycky stejnej typ, tak dedicnost s generikou je asi spravna cesta.

Pokud pro jednu  instanci budu potrebovat pri kazdym zavolani jiny datovy typ jako navratovou hodnotu, tak asi ten builder.

Polymath

Re:Java - Method Chaining
« Odpověď #11 kdy: 15. 02. 2017, 17:09:08 »
Mimochodem: který jazyk má overloading podle návratové hodnoty? Znám jazyky které mají "out" a overloading, ale to není úplně totéž.
haskell :)
A Swift :)

Re:Java - Method Chaining
« Odpověď #12 kdy: 15. 02. 2017, 18:56:22 »
Mimochodem: který jazyk má overloading podle návratové hodnoty? Znám jazyky které mají "out" a overloading, ale to není úplně totéž.
haskell :)
A Swift :)
Díky, to jsem netušil (na rozdíl od haskellu, který je ale trochu odlišný případ).