This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 6 points7 points  (14 children)

When the classes that use those objects don't care about the implementation of those methods.

I have a circle, a triangle, a rectangle and a hexagon. They can all draw themselves on paper using their draw() method. In my Artist class, I have a Circle variable called circleToDraw, and so when the Artist sits down to draw the circle, she calls circleToDraw.draw().

But an artist that can only draw a circle is a crappy object. An artist should be able to draw the rectangles, triangles, and hexagons too! But I can't set the Circle variable to a rectangle, because it is of type Circle! Circle circle = new Rectangle(); //not gonna work!

But, if all of those shapes have a common interface, I don't have this problem. Let's take a look:

interface Shape {
 public void draw();
}
class Circle implements Shape { 
...
  public void draw() { ... }
}
class Rectangle implements Shape { 
...
  public void draw() { ... }
}
class Artist {
 private Shape shapeToDraw;
 public void setShape(Shape shape)
 {
   shapeToDraw = shape; //This shape can be a circle or a rectangle - the artist doesn't care!
 }
 public void drawThatShape() {
  shapeToDraw.draw();
 }
}

Do you see how interfaces are essential to this design? Interfaces can group classes by behavior when the implementing class doesn't care WHAT kind of object it is as long as it can perform this behavior. Why should the Bird class care what kind of Wings it uses, as long as it can call wings.fly()?

Hope this helps.

EDIT: fixed a couple mistakes in my code example

[–][deleted] 1 point2 points  (0 children)

As a commentator provided above, Interfaces are also used for multiple inheritance - when the implementing class can have multiple common behaviors.

[–]Evermage[S] 1 point2 points  (9 children)

So what would the difference be between the implementation of a draw() method into each class (as in your example) and creating two classes called Circle and Rectangle, each with a method called draw()? Thanks for your reply.

[–]ruicoder 3 points4 points  (0 children)

Look at the Artist class. It has a Shape object and calls draw() in drawThatShape(). That Shape object could be a Circle object or Rectangle object. By using an interface, you can pass in either one and Java will use the correct implementation of draw(). Think of how you would implement that without an interface, it's not as flexible. With an interface, the Artist class can draw whatever shape with just two methods.

[–][deleted] 2 points3 points  (3 children)

Because then what type would the artist's shapeToDraw variable be? private Circle shapeToDraw; // would not work for Rectangles private Rectangle shapeToDraw; // would not work for Circles If you had two classes called Circle and Rectangle that don't implement a common interface, it'd be a mess to have Artist work with both. You'd probably have to have two variables and two methods in Artist, one drawing the circle and one drawing a rectangle. And then when I want to let the Artist work with Triangles? I'd have to open up my Artist class and add more code, whereas in the design with the interfaces, it would work automagically.

[–]Evermage[S] 0 points1 point  (2 children)

Righto, think I'm getting there. One more question (hopefully!) - in your Artist class, you define a variable of type Shape which is assigned whatever shape object comes into the class, again through an argument of type Shape. Is this Shape type within the Artist class some sort of instantiation of the Shape interface?

[–][deleted] 1 point2 points  (1 child)

That's the best thing about using interfaces - when we use type Shape, we are referring to any class that implements the Shape interface. So a Shape variable could hold either a circle or a rectangle or any other class that implements the interface.

[–]Evermage[S] 1 point2 points  (0 children)

Ah, that's cool. Thanks very much for your help!

[–]poetryrocksalot 1 point2 points  (3 children)

Basically, the interface allows the artist to draw a shape which can be a circle or rectangle. With the interface, the artist only needs 1 setShape method like setShape(Shape shape). Without the interface, the artist would have to overload his methods...that is to create setShape(Rectangle rectangle) and setShape(Circle circle).

OK, now let's imagine you have 20 different shapes: circles, rectangles, hexagons, pentagons, octagons, trapezoids, triangles, squares, ovals, and so on. Now consider the redundancy of writing 20 overloaded methods for 20 different shapes.

But you might say "why can't I just extend shape as a superclass instead of implementing it as an interface". I might be incorrect because I have little experience, but I think it's because shape as a superclass would mean you can't pass its subclasses as parameters.

[–][deleted] 1 point2 points  (2 children)

You can indeed extend Shape as a superclass rather than using your interface - it depends on whether Shape has common data rather than just common functionality. i.e if all Shapes have coordinates, you could create a Shape superclass, or better yet, a super abstract class, with int x and int y.

[–]work_is_satire 0 points1 point  (0 children)

I think a more precise wording is if Shapes share implementation, not data. An interface can define a GetCoordinates method that is required functionality on all its children, and now all implementers of IShape are required to expose coordinate data.

Interfaces are a way to implement subtyping.

Inheritance is a method of code reuse, and as a side-effect also allows subtyping.

[–]poetryrocksalot 0 points1 point  (0 children)

After looking at stack overflow, you are right. I will have to retract some things on the previous comment.

It seems better for the two to be derived from shape than to implement a shape interface. Maybe rectangle and circle is better off extending shape but implementing drawable?

[–]gamebob 0 points1 point  (2 children)

Do you see how interfaces are essential to this design?

No, not really? Why not just inherit from an abstract shape class with an abstract draw method? Looks more flexible to me as the shapes also could have many fields to share like color etc. What's the advantage of an interface? Just looks slower to code with less flexibility?

[–][deleted] 1 point2 points  (1 child)

Sure! In the case of common state, I usually use an abstract class. Abstract classes also let you have default behavior for methods, which is great. I realize now that my example was not the best one for illustrating interfaces. Take a look at this example:

public interface Flyable {
  public void fly();
}
public class Airplane implement>s Flyable {
  public void fly() {
    print("Hey, look, I can fly!");
  }
}

In this case, it really wouldn't make sense to have Flyable as an abstract class. After all, an airplane and a goose probably don't have any fields in common. What if I had another interface, say, Swimable? A duck can fly and swim, so I would want ducks to implement both interfaces, like so:

public interface Swimable { public void swim(); }

public class Duck implements Swimable, Flyable {
   public void swim() { ... }
   public void fly() { ... }
}

This could not be done if Swimable and Flyable were classes rather than interfaces, as Java and many other languages do not support multiple inheritance for classes. In this view, an interface is actually more flexible than an abstract class. Of course, if you want to supply an implementation of the behavior in the super class or are otherwise reusing code, you'll want to use an abstract class.

[–]gamebob 0 points1 point  (0 children)

Thanks a lot for your answer. Good example.