Method overloading & polymorphism - what is a cleaner way to do this?

This isn't a matter of polymorphism. This is a matter of method overloading When you pass instance3 to process() it will call process(SuperClass obj) because as far as the JVM is knows instance3 is a SuperClass since that's what you declared it as If you want the desired behavior (test#3 printing out "Process Instance 1"), you should define your process() method like so: private void process(SuperClass obj) { System.out. Println("Process " + obj.name()); } And your classes like this: abstract class SuperClass { String name() { return "SuperClass"; } } class Instance1 extends SuperClass { String name() { return "Instance 1"; } } class Instance2 extends SuperClass { String name() { return "Instance 2"; } } This will work because of dynamic (or late) method binding.

This isn't a matter of polymorphism. This is a matter of method overloading. When you pass instance3 to process(), it will call process(SuperClass obj) because as far as the JVM is knows, instance3 is a SuperClass since that's what you declared it as.

If you want the desired behavior (test#3 printing out "Process Instance 1"), you should define your process() method like so: private void process(SuperClass obj) { System.out. Println("Process " + obj.name()); } And your classes like this: abstract class SuperClass { String name() { return "SuperClass"; } } class Instance1 extends SuperClass { String name() { return "Instance 1"; } } class Instance2 extends SuperClass { String name() { return "Instance 2"; } } This will work because of dynamic (or late) method binding.

I'm not really following this as a solution. What I need is for the correct process() function to be called. What is being printed out is irrelevant in the demo.

I'm trying to find a better solution than using the instanceof operator. – Collin Peters Aug 5 at 18:36.

Either make it a virtual function inside hierarchy: abstract class SuperClass { public void process() { System.out. Println("Process super class"); } } class Instance1 extends SuperClass { public void process() { System.out. Println("Process instance1"); } } class Instance2 extends SuperClass { public void process() { System.out.

Println("Process instance2"); } } or check various approaches to multiple dispatch which is not natively supported in Java. http://en.wikipedia.org/wiki/Multiple_dispatch#Java.

The process() call takes a SuperClass (or sub-class) as an argument. It is not part of SuperClass – Collin Peters Aug 5 at 18:37.

If so, you should declare abstract method SuperClass.process() and implement it in the subclasses. To make test#3 work, you could add casting: test. Process((Instance1)instance3);.

Ugly. You could also define a factory class, and encapsulate type switching inside it. You'd have ProcessFactory with a ProcessObject getInstance(SuperClass obj) method that returns objects of type ProcessObjectInstance1 or ProcessObjectInstance2, with a method process().

ProcessFactory would work similar to your test#4.

This is what I currently doing. Basically turning the problem inside out a bit. Not sure if this counts as a visitor pattern.

Basically I just added an executeProcessor(Test test) abstract function within SuperClass, and the concrete classes implicitly know which function to call so they can simply use a cast. What do you think? Is this code smell?

Or a neat solution? Public class Test { private void process(Instance1 obj) { System.out. Println("Process Instance 1"); } private void process(Instance2 obj) { System.out.

Println("Process Instance 2"); } /** * @param args */ public static void main(String args) { Test test = new Test(); // Test 1 Instance1 instance1 = test. New Instance1(); instance1. ExecuteProcessor(test); // Test 2 Instance2 instance2 = test.

New Instance2(); instance2. ExecuteProcessor(test); // Test 3 (note this is not strongly typed) SuperClass instance3 = test. New Instance1(); instance3.

ExecuteProcessor(test); } abstract class SuperClass { public abstract void executeProcessor(Test test); } class Instance1 extends SuperClass { @Override public void executeProcessor(Test test) { test. Process((Instance1)this); } } class Instance2 extends SuperClass { @Override public void executeProcessor(Test test) { test. Process((Instance2)this); } } }.

As others have pointed out, this isn't really something you can do in Java. If you absolutely must, you can use reflection to do something like: private void process(SuperClass obj) { try { Class klass = obj.getClass(); Method m = this.getClass(). GetMethod("process", klass); m.

Invoke(this, obj); } catch (Exception e) { // default behavior System.out. Println("Process superclass"); } } I would really follow one of the other suggestions however.

Couple suggestions for cleaner way to do what you are doing: Options 1: Abstract method Define process() on Superclass, and override it on Instance1 and Instance2: abstract class SuperClass { public void process(String args) { System.out. Println("Process superclass"); } } class Instance1 extends SuperClass { @Override public void process(String args) { System.out. Println("Process Instance 1"); } } class Instance2 extends SuperClass { @Override public void process(String args) { System.out.

Println("Process Instance 2"); } } Option 2: Visitor Pattern Define an class that does the processing, and is an InstanceVisitor public interface InstanceVisitor { public void processSuperclass(Superclass obj, String args); public void processInstance1(Instance1 obj, String args); public void processInstance2(Instance2 obj, String args); } public class InstanceProcessor implements InstanceVisitor { public void processSuperclass(Superclass obj, String args) { System.out. Println("Process superclass"); } public void processInstance1(Instance1 obj, String args) { System.out. Println("Process Instance 1"); } public void processInstance2(Instance2 obj, String args) { System.out.

Println("Process Instance 2"); } } Then each subclass accepts a visitor, and calls the correct method: abstract class SuperClass { public void accept(InstanceVisitor v, String args) { v. VisitSuperclass(this, args); } } class Instance1 extends SuperClass { @Override public void accept(InstanceVisitor v, String args) { v. VisitInstance1(this, args); } } class Instance2 extends SuperClass { @Override public void accept(InstanceVisitor v, String args) { v.

VisitInstance2(this, args); } }.

I have a similar comment to the previous post. The process() function takes an instance of SuperClass as an argument. It doesn't have the process() function inside it.

I am going to clarify the original question – Collin Peters Aug 5 at 18:41.

Update: I like the idea of having a generic process() function that all Fruit are required to implement. But what if I now want to add a Lemon and want to juice that?

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions