// Java program to show working of user defined
// Generic classes

// We use < > to specify Parameter type

class Cat {
    String breed;
    String name;
    boolean castrated;

    Cat(String breed, String name, boolean castrated) {
        this.breed = breed;
        this.name = name;
        this.castrated = castrated;
    }

    public String makeNoise() {
        return "Meow";
    }

}

class Test<T> {
    // An object of type T is declared
    T obj;

    Test(T obj) {
        this.obj = obj;
    }

    public T getObject() {
        return this.obj;
    }
}

class AdHocPolymorphic {
    public String add(int x, int y) {
        return "Sum: " + (x + y);
    }

    public String add(String name) {
        return "Added " + name;
    }
}

public class Adhoc {
    public static void main(String[] args) {
        AdHocPolymorphic poly = new AdHocPolymorphic();

        System.out.println(poly.add(1,2));   // prints "Sum: 3"
        System.out.println(poly.add("Jay")); // prints "Added Jay"

        // error the fuck out
    }
}


// Driver class to test above
class Main {
    public static void main(String[] args) {
        // instance of Integer type
        Test<Integer> iObj = new Test<Integer>(15);
        System.out.println(iObj.getObject());

        // instance of String type
        Test<String> sObj = new Test<String>("GeeksForGeeks");
        System.out.println(sObj.getObject());

        Test<Cat> cObj = new Test<Cat>(new Cat("Siamese", "Fluffy", true));
        System.out.println(cObj.getObject().makeNoise());
    }
}
