instanceof versus polymorphism - java

I am having troubles with the instanceof operator. I'm trying to avoid it. Basically, I have the following structure:
class Shape {}
class Triangle extends Shape {}
class Rectangle extends Shape {}
ShapeParser s;
while (s.hasNext())
parseShape(s.next()); // returns a Shape object
void parseShape(Triangle t) { // do stuff } // KEY POINT HERE
void parseShape(Rectangle t) { // etc }
The key point I'm making is: I want to do a parameter overload of the function, but it's not working as I intend it to (compile-error). I am trying to avoid:
void parseShape(Shape s)
{
if (s instanceof Triangle) ...
}
UPDATE: it seems that the consensus is to create a base class method: parseShape() to do the
lifting. I wanted to clarify my question: the motivation of this question is relative to the observer pattern. Suppose I have the following Observer object payload method:
public void update(Observable obj, Shape objectPayload){}
// note: the objectPayload is usually of type Object
Instead of performing:
public void update(Observable obj, Shape objectPayload)
{
if (objectPayload instanceof Triangle)
// do stuff
else if (objectPayload instanceof Rectangle)
// etc
}
I want to do:
public void update(Observable obj, Shape objectPayload)
{
parseShape(objectPayload);
}
void parseShape(Triangle t) { } // do stuff
void parseShape(Rectangle t) { }

You can move the parseShape into each Shape class. Alternatively, you can use the Visitor pattern. There's a neat trick with reflection shown in the solution to this thread that avoids the complexity of a full visitor pattern in Java.
UPDATE:
Here's a recipe for the visitor pattern:
Declare an interface:
public interface ShapeVisitor {
visit(Triangle);
visit(Rectangle);
// ...
}
In Shape, declare an abstract method acceptVisitor:
class Shape {
public abstract void acceptVisitor(ShapeVisitor visitor);
}
In each concrete class, implement acceptVisitor:
class Triangle extends Shape {
public void acceptVisitor(ShapeVisitor visitor) {
visitor.visit(this);
}
}
Declare your ParseVisitor class to implement ShapeVisitor and implement all the required methods (simply rename each of the parseShape methods to visit).
The nice things about this are, first, it keeps the parsing code out of your Shape hierarchy and centralizes it in a separate parsing class; second, if you later decide that you need to do some other operation (like, say, render), you can apply the same pattern without ever changing any Shape class. The big down side of this approach is that you will have to change all classes that implement ShapeVisitor if you decide to add another Shape subclass.

If your parseShape() method were declared in Shape, it could be overridden in Triangle and Rectangle.
That is:
ShapeParser s;
while (s.hasNext())
// Calls the proper implementation of parseShape()
s.next().parseShape();

Um, add a parse method to the base class then just loop and iterate through the list of shapes and call s.parse()?

I assume that the error is because s.next() returns Shape. Logical thing would be
to add parse() method to shape and call s.parse()

Related

Comparing custom object within a method

In my app (which is an Android game - so, Java), I have a custom class called Quad which I use for my games objects. The class creates a textured openGL quad.
I have another class called Enemy which extends Quad.
I have a method which is called from my game class and I can pass in various objects. Now, I want to do different things depending on which object was passed in, I'll try to demonstrate with some code.
bird = new Enemy(); //Create a bird sprite
snail = new Enemy(); //Create snail sprite
public void doSomething(Quad sprite){
//Do work here regardless of which object was passed in
move(object);
if (sprite == bird){
//Do bird specific stuff here
}
else if {sprite == snail}{
//Do snail stuff here
}
}
So, as you can see, I want to execute some common code regardless of the object passed into the method, (whether a bird, snail or some other object), then after the common code, there should be some object specific code run.
Now, I remember reading on one of my other questions that although this worked, it wasn't the correct thing to do.
Since the ratio of code is heavily skewed in the favour of the common code, (ie, the majority of the code in the method should run regardless of what the object is), it doesn't seem a great idea to create different methods for birds and snails. Too much code duplication.
I could do this:
public void doSomething(Quad sprite){
move(object);
}
public void doBirdStuff(){
doSomething(bird);
//Bird specific code here
}
public void doSnailStuff(){
doSomething(snail);
//Snail specific code here
}
And then just call the specific object, so:
doSnailStuff(snail);
doBirdStuff(bird);
However, this just seems overly complicated and inefficient
So my question is, if comparing custom objects in this way isn't the 'Java' thing to do, how can I achieve my goal in a more acceptable way and why exactly is the first method deemed unacceptable?
You can create two classes (Bird and Snail) that extends Quad and use instanceof :
public void doSomething(Quad sprite){
//Do work here regardless of which object was passed in
move(object);
if(sprite instanceof Bird) {
//Do bird specific stuff here
}
else if {sprite instanceof Snail}{
//Do snail stuff here
}
}
An example of how to use it :
public void main(){
Bird bird = new Bird();
Snail snail = new Snail();
// Do something with a bird
doSomething(bird);
// Do something with a snail
doSomething(snail);
}
Update
Because most code isn't specific to bird/snail the best way is to use an enum that define enemy type :
public enum EnemyType{
Bird,
Snail
}
And use it in your Enemy class :
public class Enemy extends Quad{
private EnemyType mType;
//All other class members...
// Constructor with type
public Enemy(EnemyType type){
this.mType = type;
}
public void doEnemyStuff(){
if(isBird()){
// Bird Stuff
}
else if(isSnail()){
// Snail Stuff
}
}
//Check if current enemy is a Bird
public boolean isBird(){
return mType == EnemyType.Bird;
}
//Check if current enemy is a Snail
public boolean isSnail(){
return mType == EnemyType.Snail;
}
}
And finally wherever you want you can use a method like :
public void doSomething(Quad sprite){
//Do work here regardless of which object was passed in
move(object);
if(sprite instanceof Enemy) {
//Do enemy specific stuff here
((Enemy) sprite).doEnemyStuff();
}
}
With your first idea you were creating objects and keeping references to them only to make a check. Moreover it shouldn't work because the default behavior of "==" is to check equality of references (There is a little explanation about == operator).
Either create a Bird and a Snail class and let the classes extend from Quad. Then you can check with
if (sprite instanceof Bird) {
// ...
}
Or you could create a enumeration and add an attribute to Quad.
This looks like an example of using an object oriented language (Java), but not applying object oriented concepts.
The natural object oriented way is to have the code that does "bird stuff" in a Bird class, and the snail specific code in a Snail class. Sketching this out in your example, the code shared for all enemy types would go into the Enemy class:
public class Enemy extends Quad {
...
public void doSomething() {
// common stuff
}
...
}
Then you derive the specific enemies from this class, and implement methods with the specific behavior. These methods invoke the common behavior from their base class:
public class Bird extends Enemy {
...
#Override
public void doSomething() {
// invoke base method that does common stuff
super.doSomething();
// bird stuff
}
...
}
public class Snail extends Enemy {
...
#Override
public void doSomething() {
// invoke base method that does common stuff
super.doSomething();
// snail stuff
}
...
}
Then you need no ugly type checks to invoke specific behavior. You simply call the method, and the specific implementation for each type of enemy is invoked. If badEnemy is a variable of type Enemy:
badEnemy.doSomething();
This encapsulates all behavior of a specific enemy type in a class, while the rest of the code does not need to know anything about specific enemy types. When you want to introduce a new kind of enemy, you simply implement a new Enemy subclass with the same interface, and it will work within the system without additional changes.

Java method which takes unknown parameter

Is there a way in java to write a method which will take an unknown object as a parameter? The objects will always have a common method which the method will then need to call. Here is an example:
public void aMethod (MultipleObjects object){
object.commonMethod();
// Do some stuff here
}
I'm not sure what this is called (if it exists) so its difficult to search on Google.
You need an interface:
interface MyInterface {
void commonMethod();
}
class MyClass implements MyInterface {
// implement `commonMethod()`
}
Now your method would be:
public void aMethod(MyInterface object) {
...
object.commonMethod();
...
}
You can now pass an instance of MyClass (or any other class that implements MyInterface) to aMethod().
You can make all those classes (which share the common method) to implement an interface, so you define the method like:
public void aMethod(SomeInterface obj) {
obj.commonMethod();
// ...
}
The interface would be:
public interface SomeInterface {
public void commonMethod();
}
The usual way to do this is to define an interface that has just that method in it, then make sure all the classes that you might pass to aMethod implement that interface. E.g.:
interface CommonMethodHaver {
void commonMethod();
}
class Class1 implements CommonMethodHaver {
yadda yadda yadda;
void commonMethod() {
do class1-specific stuff here;
}
}
...
public void aMethod(CommonMethodHaver cmh) {
cmh.commonMethod();
// Do some stuff here
}
If you truly don't know what objects will be passed in and those object are not related through any kind of common base class or interface, then you will need to pass the object in as an Object reference and use reflection to find out if the object implements the method you want to call. If it does, then you again use reflection to call it.
I understand a lot of people are interpreting your question to mean you want to know about interfaces but I am interpreting this "write a method which will take an unknown object as a parameter?" to mean how do I write a method to handle unknown objects. As the other answers already tell you unless they share a common interface you can't have them all call the same method. But in case you are asking for this(which is what I think your question is asking for) this is how you would custom handle different unknown parameters...
public void aMethod(Object... object) {
if(object==null)
{
//whatever you want to do if no parameters are entered.
return;
}
for (Object o : object) {
if (o == null) {
continue; //what to do if null entered
}
if (o instanceof Integer) {
//whatever you want to do if it is an Integer
}
else if(o instanceof Double)
{
//whatever you want to do if it is a Double
}
else if(o instanceof Character)
{
//whatever you want to do if it is a Character
}
//and so on
}
}

Valid use of polymorphism?

I have 2 classes that perform a very similar task, but require different data types passed to them in order to perform those functions.
They both ultimately write to files and have expose a single public method: write() using the constructor for simple dependency injection.
This is where they differ - 1 class accepts a single object of a specific type, while the other accepts an array of that object type.
Is this a valid case for polymorphism? I think it can be but tehcnically should not?
How is this situation to be correctly handled i.e. 2 or more classes which perform a very similar function, but in a slightly different way and crucially, require different data types passed in as dependencies?
You need overloaded methods in this case. One which works with single object and other with a number of objects. They should be in the same class.
Here is an easy-to-remember way of when to use what:
1. Overloading is when you need to do the same thing with different data
2. Overriding is when you need to do the same thing with the same data in a different way
public class FileWriter {
public void write(File from){ // single file
// magic logic
}
public void write(File... from){ // multiple files using varargs
// magic logic
}
}
If you only have two Write methods, one taking a single object and the other taking a List of objects -> I would put both methods on the same class.
If you have one Write for each type, I would go for generics.
Introducing a base class wouldn't be my first choice, better to extract the general stuff into another class and use it from different classes (has-a instead of is-a).
Polymorphism is only useful if you have the same method signature but need to do stuff in different ways.
Hard to answer without a particular code sample, but the scenario you've presented fits something similar to a decorator pattern:
class X
{
public void doSomething(int number) { ... }
};
class XForCollections
{
public XForCollections(X x) { ... }
public void doSomething(int[] numbers) { ... }
};
Note, that it's not really a decorator, as XForCollection doesn't inherit X.
Use an abstract generic superclass with the common stuff.
If you want WriterA that writes an argument of type ArgA, and WriterB that writes an argument of type ArgB, you'll make
an abstract Writer<T> with all of the common stuff in it, and an abstract method such as public void write(T arg)
WriterA that extends Writer<ArgA>
WriterB that extends Writer<ArgB>
Say you have this:
class A{
void write(int a){}
}
class B{
void write(int[] a){}
}
Since you say the implementations for those methods vary deeply between each other, then varargs probably wouldn't be a suitable option. To simplify things, do this::
class WriteStuff{
void write(int a){}
void write(int[] a){}
}
This would let you attain a higher level of cohesion for your classes. Polymorphism isn't really necessary here.
Then again, it's really too little information to go on with. You should probably write up some example code.
Polymorphism – means the ability of a single variable of a given type to be used to reference objects of
different types, and automatically call the method that is specific to the type of object the variable references. In a
nutshell, polymorphism is a bottom-up method call. The benefit of polymorphism is that it is very easy to add new
classes of derived objects without breaking the calling code that uses the polymorphic classes or interfaces. When you send a message to an object even though you
don’t know what specific type it is, and the right thing happens, that’s called polymorphism. The process used by
object-oriented programming languages to implement polymorphism is called dynamic binding.
Example:
Launcher
private void init() {
//client or calling code
double dim = 5.0; //i.e. 5 meters radius or width
List<Shape> listShapes = new ArrayList<Shape>(20);
Shape s = new Circle();
listShapes.add(s); //add circle
s = new Square();
listShapes.add(s); //add square
getTotArea (listShapes,dim); //returns 78.5+25.0=103.5
//Later on, if you decide to add a half circle then define
//a HalfCircle class, which extends Circle and then provide an
//area(). method but your called method getTotArea(...) remains
//same.
}
/** called method: method which adds up areas of various
** shapes supplied to it.
**/
public double getTotArea(List<Shape> listShapes, double dim){
Iterator<Shape> it = listShapes.iterator();
double totalArea = 0.0;
//loop through different shapes
while(it.hasNext()) {
Shape s = (Shape) it.next();
totalArea += s.area(dim); //polymorphic method call
}
return totalArea ;
}
}
Shape
public abstract class Shape {
protected abstract double area(double dim);
}
Square
public class Square extends Shape{
#Override
protected double area(double dim) {
return dim*dim;
}
}
Circle
public class Circle extends Shape{
#Override
protected double area(double dim) {
return Math.PI*dim*dim;
}
}

How to iterate only over specific kind of elements?

I have an array list as such:
private List<GameObject> gameObjects = new CopyOnWriteArrayList<GameObject>();
GameObject can be one of 3 classes: Spaceship, Beam and Asteroid. They all are similar so I keep them in one array. However spaceships have addition method shoot which is used every 100ms in other thread (which is called ShootRunnable). So I would like to iterate in it only over Spaceship because other doesnt implement shoot method. What is the best way to achieve this?
for (GameObject ob : gameObjects) {
if (ob instanceof Spaceship) {
ob.shoot();
}
}
Can I iterate over it using something like the above? Just with the use of a cast or something? Please help.
The path you're on is technically feasible, though a good rule of thumb is that if you start using reflection, you're probably doing something wrong. In this case, it might be wisest to have a two collections, one for all your game types, and one specifically for spaceships.
In your game, are there any other actions that happen periodically?
If so, you could change the shoot() method into an abstract method (could be named periodicAction()) and place it in the GameObject class. The Spaceship class would implement this method by shooting, the other class with its specific periodic behavior and the Asteroid class by doing nothing.
You should put your shoot() method into the Spaceship class beacause no asteriod or beam will use this method. Done this, you should also keep at least two collections. One of them should only contain your spaceships.
I would rather do this way:
Iterator<Spaceship> getSpaceships(){
// return Iterator over Spaceship objects through use of instanceof
}
...
Iterator<Spaceship> it = getSpaceships()
while(iter.hasNext()) it.next().shoot()
To me it looks more clear.
You could create an interface Action or a method into GameObject:
public interface Action {
void performAction();
}
public abstract class GameObject implements Action {
//...
public void performAction() {
// subclasses should override this method.
// otherwise, it will do nothing.
}
}
and then, implement Spaceship:
public class Spaceship extends GameObject {
#Override
public void performAction() {
this.shoot();
}
}
To Beam and Asteroid, you can leave the method performAction:
Then, you can interate over:
for (GameObject ob : gameObjects) {
ob.performAction();
}

Is this polymorphism?

I recently was in an interview and during that interview I realized my programming concepts aren't as concrete as I thought.
I was asked, describe a time in your previous job where you used polymorphism?
After some thinking I said that we had a record class which every new record extended. So if we have a AddRecord or a RemoveRecord or any other type of record, they would extend Record. The record interface looked something like this:
public abstract Record{
public writeLine(String line);
public getColumn(int column);
public setHeader(String header);
...
}
public AddRecord extends Record{
public writeLine(String line){
// do something
}
// etc...
}
public MakeRecord{
Record r;
public setRecord(Object s){
if(s instanceof Record){
r = s;
}
}
public void printNewRecord(){
while(thingsToWrite){
r.writeLine(something);
}
}
}
I just shorthanded it so don't nit pick it please.
I told them this was using polymorphism because regardless of the record type, it could be wrote without knowing what type of record it was. This was valuable because we are writing files that needed to be padded correctly, either zero filled or padded with spaces etc...
If this isn't polymorphism, please tell me how I can change my example into something that uses polymorphism.
Long answer short: yes
Polymorphism is, according to webster:a (1) : existence of a species in several forms independent of the variations of sex (2) : existence of a gene in several allelic forms (3) : existence of a molecule (as an enzyme) in several forms in a single species b : the property of crystallizing in two or more forms with distinct structure
we are focused with definition a. this describes, in java terms, as using 1 "top" class to reference two "bottom" classes. That is shown in the above example, to the best of my knowledge.
A very basic example of polymorphism:
import java.util.ArrayList;
public class TestClass{
public static void main(String args[]) {
ArrayList animals = new ArrayList();
animals.add(new Bear());
animals.add(new Fish());
animals.add(new Animal());
for (Animal a : animals){
a.someMethod();
}
}
}
class Animal {
public void someMethod(){
System.out.println("I am an Animal");
}
}
class Bear extends Animal{
public void someMethod(){
System.out.println("I am a Bear");
}
}
class Fish extends Animal{
public void someMethod(){
System.out.println("I am a Fish");
}
}
The output of this is:
I am a Bear
I am a Fish
I am an Animal
So we can see here that the loop calling the methods on each type of object calls them all on Animal, and yet the actual method called on each object is that objects own implementation of that method.
Clearly for this to work every object in the collection MUST have an implementation of this method, although it can obviously use the superclass’ version if that is appropriate for that object.
This means that the objects in a collection (as an example of how it may be used) can be decided at runtime, and don’t have to be individually type cast back to their true form, but can simply be called by a parent class type or interface type. This allows for far more flexibility in the code, and makes it easier to maintain. It also allows for code which is more generic and loosely coupled.
So there it is in a nutshell. There are tons of examples online to have a look at. It’s a brilliant concept, and one which is well worth investing some time into understanding.
The example is not good for explaining polymorphism.
Addrecord is not good extension of Record class. Addrecord should be method and not a class.
So basically you should have Record class having Addrecord method and this method can be overriden by special records like - ColumnnameRecord.
In the case where you have specialRecord class derived from Record class and Record Class have methods which are overriden by derived classes then you have good examples of polymorphism.
Current example is technically correct but not conceptual correct.
Another example for Polymorphism:
abstract class PolyGeometricEntity
{
public int center_x__mm; // commen superset
public int center_y__mm; // commen superset
public void move(int d_x__mm, int d_y_mm) // commen superset
{
center_x__mm += d_x__mm;
center_y__mm += d_y_mm:
}
public abstract int area(); // commen superset on abstract level, but specialized at implementation level
public abstract void draw(); // commen superset on abstract level, but specialized at implementation level
}
class CircleEntity : PolyGeometricEntity
{
public override int area()
{
// circle specific
return 1;
}
public override void draw()
{
// draw a circle
}
}
class TriangleEntity : PolyGeometricEntity
{
public override int area()
{
// triangle specific
return 1;
}
public override void draw()
{
// draw a triangle
}
}
class PolyCanvas
{
List<PolyGeometricEntity> entities = new List<PolyGeometricEntity>();
void CreateEntity(string toCreateClass)
{
// assume that code is called by the ui
// you do not know what the user decides at runtime
// Polymorphism 'starting' now:
PolyGeometricEntity toCreate = null;
if (toCreateClass == "c") { toCreate = new CircleEntity(); }
else if (toCreateClass == "t") { toCreate = new TriangleEntity(); }
entities.Add(toCreate);
}
void ReDraw()
{
foreach (PolyGeometricEntity toDraw in entities)
{
toDraw.draw(); // polymorphism in action!
}
}
}

Categories