Sponsored Link •
|
Advertisement
|
Use getPlace() as an example of instanceof. Use perhaps values() and keySet() of LinkMap as example of polymorphism and dynamic binding.
Guideline could be simplified to prefer polymorphism to instanceof.
Try to design things so clients don't have to use instanceof and downcasting. This is where your modeling of abstract types comes in. When you design class Animal, you say what it means to be an animal by saying what services every Animal provides (the syntax and semantics). A good example of this is Set and List and Collection. These rich types allow abstract return types that clients don't usually have to downcast. In your APIs, set things up so people don't have to use instanceof. Sometimes, though, you may find yourself requiring clients to downcast. Show LinkMap, ModifiableLinkMap, DynamicLinkMap. Know a LinkMap is coming, but don't know whether its a DynamicLinkMap unless you use instanceof. If so, can downcast to DynamicLinkMap.
instanceof
instanceof
or reflection.
// In file rtci/ex5/Animal.java class Animal { //... } // In file rtci/ex5/Dog.java class Dog extends Animal { public void woof() { System.out.println("Woof!"); } //... } // In file rtci/ex5/Cat.java class Cat extends Animal { public void meow() { System.out.println("Meow!"); } //... } // In file rtci/ex5/Hippopotamus.java class Hippopotamus extends Animal { public void roar() { System.out.println("Roar!"); } //... } // In file rtci/ex5/Example5.java class Example5 { public static void main(String[] args) { makeItTalk(new Cat()); makeItTalk(new Dog()); makeItTalk(new Hippopotamus()); } public static void makeItTalk(Animal animal) { if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.meow(); } else if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.woof(); } else if (animal instanceof Hippopotamus) { Hippopotamus hippopotamus = (Hippopotamus) animal; hippopotamus.roar(); } } }
Orangutan
, would need to add a new if-else clause
instanceof
cast aside in favor of
polymorphism and dynamic binding
// In file rtci/ex6/Animal.java abstract class Animal { public abstract void talk(); //... } // In file rtci/ex6/Dog.java class Dog extends Animal { public void talk() { System.out.println("Woof!"); } //... } // In file rtci/ex6/Cat.java class Cat extends Animal { public void talk() { System.out.println("Meow!"); } //... } // In file rtci/ex6/Hippopotamus.java class Hippopotamus extends Animal { public void talk() { System.out.println("Roar!"); } //... } // In file rtci/ex6/Example6.java class Example6 { public static void main(String[] args) { makeItTalk(new Cat()); makeItTalk(new Dog()); makeItTalk(new Hippopotamus()); } public static void makeItTalk(Animal animal) { animal.talk(); } }
Animal
, you must be able to talk()
instanceof
and downcasting second best
Mention UI factory object in Service UI API, in that "UIFactory" is not a type that
all UI factory interfaces implement. It is a concept. Client must use the equivalent
of instanceof and downcasting. Here, to separate the codebases, there's a different
way to find out the UI factory types. (UIFactoryTypes attribute). But the reason we
did it that way was we didn't feel we could predict what was coming. By leaving it
open, by forcing clients to look for interfaces they understand, we made the UI
factory concept more amenable to future changes. Same thing with the service context
object in the current Place API. But in general, should avoid the instanceof and
downcasting thing and go for specific types (i.e, UIFactory
rather than concepts, (i.e., UI factory).
The real trouble with reflection philosophically, which I want to emphasize here, is that you lose semantics when you just look at message signatures. What types really add is the semantics to go along with the message signatures. Using reflection in Java is like using a weakly typed language. If there's a method with an appropriate signature, invoke it. What I said in most recent seminar, "How can I ask you to do something for me, if I don't know what you are going to do when I ask?"
Sponsored Links
|