|
Re: Polymorphism Question
|
Posted: Jan 28, 2004 11:10 AM
|
|
> > If I understand correctly you're saying that it's foolish > to declare a parameter using a derived class because it > can cause maintenance issues later on. So, for example, > the method below would be a bad idea... > > > void someMethod (DerivedClass abc) { /* do something */
> }
>
> > However, couldn't the same method be written like this > (below) and still work regardless of if you had created > the variable with > > > "BaseClass baseClass = new BaseClass()"
>
> > ...or... > > > "DerivedClass baseClass = new BaseClass()"
>
> > If so, then I still don't see a compelling reason to use > one over the other. Am I still missing the big picture? > > > > void someMethod (BaseClass abc) { /* do something */ }
>
I'll try to answer your questions changing the examples. In class-based OOPLs, like Java, classes (and interfaces) are used to create classification hierarchies, starting from more generic classes and ending in specific instances. Let's look at part of the hierarchy of java.util.Collection:
// super-type of collections
interface Collection {
}
/* super-type of collections that can be indexed.
*/
interface List extends Collection {
}
/* super-type of collections with set-like behavior
* (i.e. no duplicates)
*/
interface Set extends Collection {
}
/* super-type of collections with set-like behavior
* and ordered iteration (i.e. iterator.next() always
* gives "smaller" elements first, obeying
* java.lang.Comparable.compareTo() ordering)
*/
interface OrderedSet extends Set {
}
public int countDuplicatedElements(Collection c) {...}
public List sort(List aList, Comparator order) {...}
public Set getAllDepartments(Set employees) {...}
public void processJobs(OrderedSet thingsToDo) {...}
So we have four types in our hierarchy (in this case they are interfaces not classes but the rationale is similar) representing the problem we want to model. The four methods use different types of this hierarchy as parameters, according to their preconditions:
- countDuplicatedElements doesn't depend on any assumptions about concrete type of c; - sort needs a Collection that can be indexed, so it can sort its elements. The parameter is a List to express this need (also Collection has no Object get(int) method, but List has); - getAllDepartments works under the assumption that the collection of employees has no duplicates, the parameter type works as a restriction/documentation, because the method doesn't use any operations on employees that aren't from Collection; - processJobs needs to do the tasks respecting their priority, which is given by some comparison operation, also we should be able to do each task once and only once. Again the parameter type works as a restriction/documentation, because the method use just the Iterator iterator() method from Collection on thingsToDo and not the fancy methods specific to OrderedSet.
The conclusion is, if your method should work with the base class (i.e. no assumptions about the subclasses invariants or doesn't use methods from subclasses) make it so. Otherwise if it needs some restriction and/or specialized operation type it using the subclass.
|
|