Neng Channa Interfaces approach allows you to extend more classes in the future.
First of all, you can write it as a utility method only if it operates on the same members/parameters across all the classes that use this method. In your case, each class has different members to display so you need to provide the isolated logic of displaying on each class hence the use of Interfaces. If there is an additional common logic you add long with interfaces approach then you can accept Interface as the method parameter of the utility method and add the logic inside.
Secondly, I don't understand your point of Next time there will be more than class dog or cat. maybe a hundred of class will use in commUtil. Ideally, a utility function should be unaffected regardless of any number of classes that exist. In case it's behaviour keeps getting affected based on the introduction of new classes then it is actually not a utility function or a flawed approach.
You cannot access child object members via parent directly. Here, Object class is in the root or parent and Cat, Dog comes under it.
So, there are a couple of approaches on how you can achieve your use case.
Object Casting: Straightforward approach. Cast your parent to your desired child instance and then you access child object's members. Ex:
public void display (Object obj){ if (obj instanceof Cat) { Cat c = obj(Cat); // cast to child // do your operation on the cat object here } if (obj instanceof Dog) { Dog d = obj(Dog); // cast to child // do your operation on the dog object here } }But this approach makes your code cluttered as the number of types increase. This is not the recommended approach anyway.
Interfaces: Write a top level interface which has a method display() and then, Dog and Cat class implements this interface. Now you can perform the display operation under each instance. Ex:
interface DisplayInterface { public void display(); } class Dog implements DisplayInterface { public void display() { // your logic here } } class Cat implements DisplayInterface { public void display() { // your logic here } } //Inside the main method Dog d = new Dog(); d.display(); Cat c = new Cat(); c.display();In this method, you would not require util class to perform the display operation(and you shouldn't do it either).
Apart from above two, there are a couple of different approaches through Reflection and Generics which I don't feel the need for this use-case.
Cheers!