Friday, March 23, 2012

Java: A Practical use of Interfaces

On the last post, I used an interface to help call an overrided method when some event is triggered (such as the Back button).

So to jot things down, here is what an interface seems to me.

Button: Overriding onClick example

Okay, so you have an interface like this:

public interface IClass {
      public void methodOne();
      public String methodTwo ( int i );
}

This is some interface class, and if you haven't worked with interfaces much, then you'll probably be like, "This has no use to me." Anyways, lets try to make some module...hmmm...lets try a Button class.

public class MyButton {
   IClass listener;
   MyButton() {}
   public void onClick() { listener.methodOne(); }
   public void setOnClickListener(IClass listener) { this.listener = listener; }
}

Now, here's the situation. You created the MyButton in some bigger context class, but you can't override it. For example, in Android, you call in your components statically like this:

(MyButton) findViewById(R.id.mybutton);

This doesn't allow you to override methods like this:

new MyButton () {
   @Override
   public void onClick() { //do something }
};

So in times like these, you ask how am I going to customize that onClick method? That's what setOnClickListener is for. You pass in a new Interface into the method like this:

setOnClickListener(new IClass() { 
@Override
methodOne() { // do stuff  }
};

Now since the onClick() function is defined to use the listener's method, it will now run the methodOne that you overrode. So in a way, it's like passing in a method as a parameter.
BUT!!! I just realized....couldn't I have done it with a normal class? Yes. I believe so. So next question is...What is the advantage of using an interface than a class in this situation? Or what is the advantage of implementing an interface that forces you to override all it's methods?

Uses of Interfaces

From what I read, if you app is constantly on update mode, use interfaces since you can implement interfaces as many times as you want like:

public class MyClass implements Interface1, Interface2, Interface3

Or you can extend an interface with multiple interfaces like:

public interface Interface1 extends Interface2, Interface3

Type Casting these babies

Another usage is to connect two different typed objects together by casting. Say you have two class that implements some interface:

public class Ball implements Relatable
public class Car implements Relatable

Where the interface Relatable coded like this:

public interface Relatable {
      public boolean isSofterThan(Relatable otherObject);
}

Now, if you wanted to make the method isSofterThan work with just the two classes (no interface), you'd have to make specific methods for each class like this:
(Reminder: For the following examples, interfaces is not implemented)
For Ball class:
public boolean isSofterThan(Car object);

For Car class:
public boolean isSofterThan(Ball object);

Now let's say that a class called Plushie comes along, then the Ball and Car class would have to add:
public boolean isSofterThan(Plushie object);

The point here is that you'd have to keep producing more of the same method with different signatures. Now this is where the interface comes in. Assume that each class has a variable called softness. So in each class that now implements Relatable, you can define the isSofterThan method like:

@Override 
public boolean isSofterThan(Relatable otherObject) {
    return (this.softness > otherObject.softness) ? true : false;
}

Now that this method is defined in the Ball, Car and Plushie classes. Lets try to use this in actual code.

Ball ball = new Ball();
Car car = new Car();
Plushie plushie = new Plushie();

ball.softness = 5;
car.softness = 2;
plushie.softness =  99999999999999999999;

Relatable rBall = (Relatable)ball;
Relatable rCar = (Relatable)car;
Relatable rPlushie = (Relatable)plushie;

if (rBall.isSofterThan(rCar)) println("Ball is softer than car!"); 
else println("Car is softer than Ball");

if (rPlushie.isSofterThan(rCar) println("OVER 9000000!");


Okay so I will disclaim that I haven't really tested this out. But the main thing to look at is that I type casted two different objects into one similar object, which is displayed in hot, red text. I learned this thing from:

http://docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html

That's it for now... Remember, I'm a programming noob. So help me, don't bash me. :)

No comments:

Post a Comment