2018.07.26 19:37 statyczne typowanie nie jest łatwe

Czasem się zdarza, że z kimś rozmawiam i mówię, że statyczne typowanie jest trudne, a ten ktoś mi nie wierzy. W takich razach przyda mi się mieć pod ręką poniższy przykład. Nie tak łatwo dojść, czy to się w ogóle skompiluje, a jeśli nie, to jaki będzie błąd i jak to naprawić. Oto ten przykład:
abstract class Lista<T> {
    public abstract boolean czyPusta();
    public abstract T głowa();
    public abstract Lista<T> ogon();

    public Lista<T> dołącz(T liczba) {
        return new Niepusta<T>(liczba, this);
    }
}

class Pusta<T> extends Lista<T> {
    @Override
    public boolean czyPusta() {
        return true;
    }

    @Override
    public T głowa() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Lista<T> ogon() {
        throw new UnsupportedOperationException();
    }

    @Override
    public String toString() {
        return "-";
    }
}

class Niepusta<T> extends Lista<T> {
    private final T głowa;
    private final Lista<T> ogon;

    public Niepusta(T głowa, Lista<T> ogon) {
        this.głowa = głowa;
        this.ogon = ogon;
    }

    @Override
    public boolean czyPusta() {
        return false;
    }

    @Override
    public T głowa() {
        return głowa;
    }

    @Override
    public Lista<T> ogon() {
        throw new IllegalArgumentException();
    }

    @Override
    public String toString() {
        return głowa + ", " + ogon;
    }
}

public class Problem {
    public static void f(Lista<Number> lista) {
        Number pi = 3.14;
        Lista<Number> lista2 = lista.dołącz(pi);
        Number głowa = lista2.głowa();
        System.out.println(głowa);
    }

    public static <T> Lista<T> stwórzListę(T... liczby) {
        Lista<T> lista = new Pusta<>();
        for (T liczba : liczby) {
            lista = new Niepusta<>(liczba, lista);
        }
        return lista;
    }

    public static void main(String[] args) {
        Lista<Integer> mojaListaIntów = stwórzListę(3, 7, 5);
        f(mojaListaIntów);
    }
}


komentarze:
2018.08.17 08:07 Piotrek

Uzupełnienie: chodzi mi głównie o metodę dołącz(). Czy ona się skompiluje? Jasne że nie, bo nie byłoby zagadki. A dlaczego nie? I co zrobić, żeby się skompilowała?


2018.09.10 05:55 Piotrek

A oto druga zagadka. Czy ten kod się skompiluje? A jeśli tak, to jakiego typu jest zmienna para2 (no, oprócz tego, że jak wszystko w Javie jest typu Object)?
class A {}
class B extends A {}
class C extends B {}
class D extends C  implements N1, N2 {}

class W {}
class X extends W {}
class Y extends X {}
class Z extends Y implements N1, N2 {}

interface N1 {}
interface N2 {}

class Para<T> {
    private final T a;
    private final T b;

    public Para(T a, T b) {
        this.a = a;
        this.b = b;
    }

    public T getA() {
        return a;
    }

    public T getB() {
        return b;
    }

    public static <U> Para<U> replace(Para<? extends U> staraPara, U noweA) {
        return new Para<U>(noweA, staraPara.getB());
    }
}

public class Problem2 {
    public static void main(String[] args) {
        Para<D> para1 = new Para<>(new D(), new D());
        Z z = new Z();
        Object para2 = Para.replace(para1, z);
    }
}




ksywa:

tu wpisz cyfrę cztery: (to takie zabezpieczenie antyspamowe)

komentarze wulgarne albo co mi się nie spodobają będę kasował


powrot na strone glowna

RSS