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


Thank You!
send