
abstract class Numeric <T> {
    abstract T plus(T value);
    abstract T minus(T value);
    abstract bool test(T value);
}

class Generics10_1Operator <T, T2, T3 extends Numeric<T2>> {
    T2 call_plus_method(T3 a, T2 b) {
        return a.plus(b);
    }

    bool call_test_method(T3 a, T2 b) {
        return a.test(b);
    }
}

class GenericsTestInteger extends Numeric<GenericsTestInteger> {
    int value;

    GenericsTestInteger(int value) {
        self.value = value;
    }

    void call_plus_method() {
        println("plus --> " + self.plus(self).value.toString());
    }

    virtual GenericsTestInteger plus(GenericsTestInteger integer) {
        return new GenericsTestInteger(self.value + integer.value);
    }
    virtual GenericsTestInteger minus(GenericsTestInteger integer) {
        return new GenericsTestInteger(self.value - integer.value);
    }
    virtual bool test(GenericsTestInteger integer) {
        return true;
    }
}

class GenericsTestFloat extends Numeric<GenericsTestFloat> {
    float value;

    GenericsTestFloat(float value) {
        self.value = value;
    }

    virtual GenericsTestFloat plus(GenericsTestFloat float) {
        return new GenericsTestFloat(self.value + float.value);
    }
    virtual GenericsTestFloat minus(GenericsTestFloat float) {
        return new GenericsTestFloat(self.value - float.value);
    }
    virtual bool test(GenericsTestFloat float) {
        return true;
    }
}

