Miért ezt írja ki a program? (Java)

Fórumok

Lehet, hogy elmaradtam valamiben. Nem szoktam publikus változókat használni, csak ritkán.

Miért ezt írja ki az alábbi progi?: "B 2"


class A {
public int a = 2;
public void f() {
a+=5;
System.out.print("A ");
}
}

class B extends A {
public int a = 7;
public void f() {
this.a += 3;
System.out.print("B ");
}
}

public class task4 {
public static void main(String[]args) {
A x = new B();
x.f();
System.out.println(x.a);
}
}

Hozzászólások

Hát én pl. Debuggolnam az ide-ben és akkor kiderül. Nem programoztam javában, de gondolom a debug során jól látszana mi történik.

Az a fieldet a B-ben definiált field elrejti, viszont az f metódust a B-ben definiált metódus overrideolja. Ezért az x.f() hívás a B implementációját futtatja és a B fieldjét módosítja, de az x.a már az A fieldjét adja vissza, mivel az x referenciának A a típusa.

Jók ezek a szélsőséges dolgok, amelyek a nyelv értelmezésének a határát feszegetik, csak rettentő messze vannak a valós megoldásoktól és az ilyenre szoktam azt mondani, hogy mindenáron kerülendő anti-pattern, mert nem lesz jól olvasható a program, szopás lesz később nem csak módosítani, hanem megérteni is, hogy mi történik. A legtöbb kódellenőrző szoftver is percekig fejhangon sikít egy ilyen példától...

--
https://iotguru.live

Valóban production kódban ilyennek helye nincs, de tanulni még jó.

Egyébként leginkább a Java nyelv tervezői tanulhatnának belőle. Lehet jobb lenne az elrejtést syntax errornak venni, és @Override helyett szerintem pl. a C# szebben oldotta meg a kötelező override kulcsszóval.

Én is rühellem az ilyeneket, de fenntartom, hogy a nyelv apró "szépségeit" néha ilyen kifacsart példákkal lehet szemléltetni. Egy ilyen feladványra magától is rájöhet valaki, ha rengeteget tud már a nyelvről. De ha nem jön rá, abból nem igazán következik semmi, ezért nem jó interjúra. Főleg az a baj interjú szempontjából, hogy a valósághoz nem sok köze van a feladatnak. Egyrészt ugye valóságban ilyet nem ír az ember, másrészt a valóságban IDE-t használunk, amiben van jump to funkció, meg debugger, és ki lehet bogozni, ha mégis ilyennel találkozunk össze.

Nem, az az igazán kafa, amikor ezt még megspékeled egy jó kis reflectionnel és futási időben valahol húsz szint mélységből kapod a Class példányt, aminek a megfelelő Fieldjét string névvel kikeresed :) Happy debugging motherfucker :P Happy debugging, suckers :P

Szerk.: idézni csak pontosan, szépen, ahogy a csillag megy az égen, úgy szabad. Én meg rosszul idéztem, javítva.

package helloworld;

public class HelloWorld {

    public static class A {

        public int foo = 4;

    }

    public static class B extends A {

        public int foo = 5;

    }

    public static void main(String[] args) throws Exception {
        B inst = new B();
        System.out.println(inst.foo); // 5
        System.out.println(((A) inst).foo); // 4
        System.out.println(((B) inst).foo); // 5
        System.out.println(Class.forName("helloworld.HelloWorld$A").getField("foo").getInt(inst)); // 4, de ugye a Class-t hozhatod bárhonnan ;)
        System.out.println(Class.forName("helloworld.HelloWorld$B").getField("foo").getInt(inst)); // 5, de ugye a Class-t hozhatod bárhonnan ;)
    }

}

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)