Get the tools you need to learn Java skills fast!
Video tutorials, eBooks, hands-on lab exercises, sample code.
Get started
The moose likes Java in General and the fly likes Design question (polymorphism problem) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of Badass: Making Users Awesome this week in the Game Development forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Design question (polymorphism problem)" Watch "Design question (polymorphism problem)" New topic

Design question (polymorphism problem)

Winston Smith
Ranch Hand

Joined: Jun 06, 2003
Posts: 136
Hello All,
I have a Bean named "WebEntity", which models a user. Now, the user can either be a Supervisor, or a Worker (both of which are subclasses of the superclass Employee). The WebEntity class is composed of an Employee object named employee (i.e. private Employee employee; ). Now, for instance, if a Supervisor logs in, I initialize the Employee object in WebEntity as follows:
employee = new Supervisor();
And likewise if a Worker logs in. My problem arises when I'm in a jsp page, using the WebEntity bean, and I need to call a function specific to one of the two subclasses of Employee (Supervisor or Worker). For instance, assume I use the Supervisor class, and call a member function named initWorkers(). I do this as follows:
Now, the getEmployee method in WebEntity returns an Employee object, however, this object is either going to be a Supervisor or a Worker. Unfortunately, it is seen as an Employee, and thus, the method initWorkers() is not found in the class. I thought polymorphism would take care of this situation, but apparently not. When I do a getClass() on the object that is returned from getEmployee(), it returns Supervisor, funny enough. So why does it look at Employee when calling the function?
Assuming I'm doing this correctly, now I'm faced with a design issue. In my JSP pages, should I declare a Supervisor object in each page as follows:
Supervisor supervisor = (Supervisor) WebEntity.getEmployee();
By doing so, I will have access to all the functionality in the Supervisor class in that page. On the other hand, I can simply do it with each function call:
But will this second strategy create a new object in memory each time?
This problem has arisen out of my need to support different user types (i.e. Supervisor, Worker), which are modeled with seperate classes (both inherit from Employee). Some pages are common to both, ergo, I can use the superclass Employee to carry out necessary functions. Other pages are specific to one or the other, so I'm faced with the polymorphism problem described above.
Thanks for any suggestions!

for (int i = today; i < endOfTime; i++) { code(); }
Bear Bibeault
Author and ninkuma

Joined: Jan 10, 2002
Posts: 62269

Even though this occurs within a JSP, it's a general Java polymorphism issue. As such, I'm moving this topic along to the Java in General(intermediate) forum.

[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Scotty Sinclair

Joined: Jun 26, 2003
Posts: 17
The reason you cannot access the Supervisor methods even though you have a supervisor object is that the supervisor object is referred to as an employee.
You have two things:
The runtime type information on the object which is Supervisor because the actual object you are dealing with is an instance of Supervisor.
The compile time information which says we have access to some object defined to be an Employee.
Supervisor s = new Supervisor();
s.initWorkers(); //ok handle 's' is type Supervisor
Employee e = s;
e.initWorkers(); //compile error
The compiler system uses types to check what methods can and can't be called on objects. So we have to specify a type to use i.e. Employee. Then the compiler can say "hang on, initWorkers isn't part of employee".
So it is not what the object is but the type of the reference you have to it. This is also what makes polymorphism possible that we have compile time safe references to dynamic data.
It is probably simplest to just upcast to supervisor as long as you are in a context to know that the employee is a supervisor. There are other possibilities though. But thinking about it gives me headaches!
And casting doesn't create a new object it just changes the type of the reference you have to it.
Winston Smith
Ranch Hand

Joined: Jun 06, 2003
Posts: 136
Thanks, Scotty, you've cleared up several issues for me!
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Any time you need to know the subclass it might be a sign from above to rethink your design. Could you move this logic into a common method and push the common method to Employee? Worker and Supervisor would override it differently.
Now your pushing knowledge down the chain - the Employee knows what it is and what it should do instead of your calling class having to know that - and getting some real mileage out of polymorphism.
We're still getting something from WebEntity just to do some work on it. Could WebEntity hide its structure from us a little better?
This gets into some stratospheric theory and has plenty of room for debate. But I hope it gets some brain cells churning.

A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Winston Smith
Ranch Hand

Joined: Jun 06, 2003
Posts: 136
Hi Stan,
Yes, I didn't even think of overriding methods in the Employee class. This is a bit more elegant solution, I think, as opposed to explicit casting to a Supervisor object. The explicit casting at every method call just does not seem like a good idea in this context. I'm glad I can consistently get good insight and design strategies at the Ranch! Thanks again, Stan.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I'm delighted that had a positive effect on you. If you enjoy this kind of discussion, scroll on down to the UML, OO etc forum.
I agree. Here's the link:
subject: Design question (polymorphism problem)