5
interface Shape {
    public double area();  
}

class Circle implements Shape {
      private double radius;

      public Circle(double r){radius = r;}

      public double area(){return Math.PI*radius*radius;}
}

class Square implements Shape {
      private int wid;

      public Square(int w){wid = w;}

      public double area(){return wid *wid;}
}

public class Poly{
     public static void main(String args[]){
               Shape[] s = new Shape[2];
               s[0] = new Circle(10);
               s[1] = new Square(10);

               System.out.println(s[0].getClass().getName());
               System.out.println(s[1].getClass().getName());
      }
}

In an effort to understand the concept of polymorphism, I found the following post (https://stackoverflow.com/a/4605772/112500) but I noticed that Charlie created the Shape class with a unimplemented method.

As one can see from my code, I converted that class into an interface and then used it to instantiate an anonymous class which then called the appropriate method.

Could someone tell me if my solution is sound? Would you have written the code in a different manner? Why does the use of an interface on both sides of the equal sign function as it does?

Thanks.

Caitlin

Community
  • 1
  • 1
CaitlinG
  • 1,955
  • 3
  • 25
  • 35
  • 2
    Where did you create the anonymous class in the posted code ? – AllTooSir Jul 18 '13 at 09:14
  • 3
    Do you mean the line `Shape[] s = new Shape[2]`? You don't create any instance of `Shape` there, only an array that can contain 2 `Shape`s. – Vincent van der Weele Jul 18 '13 at 09:17
  • @Heuster Nice inference ! – AllTooSir Jul 18 '13 at 09:19
  • I read that when an interface is used on the left side (super class/parent class) that an anonymous class is created behind the scene and it calls the requested method. Is this incorrect? – CaitlinG Jul 18 '13 at 09:19
  • can you explain more about what you want ? (i don't understand your problem) – pouyan Jul 18 '13 at 09:20
  • Is the fact that Shape is an interface problematic in any manner? When I say: Shape[] s = new Shape[2], I was slightly surprised that functioned since I've read that the right side had to be class. – CaitlinG Jul 18 '13 at 09:22

3 Answers3

5

An anonymous class in Java is a class not given a name and is both declared and instantiated in a single statement. You should consider using an anonymous class whenever you need to create a class that will be instantiated only once.

An anonymous class must always implement an interface or extend an abstract class. However, you don’t use the extends or implements keyword to create an anonymous class. Instead, you use the following syntax to declare and instantiate an anonymous class:

new interface-or-class-name() { class-body } 

One example would be :

Shape s = new Shape() // no square brackets here
{
    public double area()
    {
        return 10.0;
    }
};

No where in your posted code you are creating any anonymous class.

Read the Oracle tutorial and this for more.


When you do this :

Shape[] s = new Shape[2] // notice the square brackets : "[2]"

You are actually creating an array which can have references to objects of Shape and its subtypes. So , this array can contain reference to objects of any class which implements Shape :

s[0] = new Circle();
s[1] = new Square();
AllTooSir
  • 48,828
  • 16
  • 130
  • 164
  • http://stackoverflow.com/questions/9157784/java-interface-with-new-keyword-how-is-that-possible The second answer is what I read. – CaitlinG Jul 18 '13 at 09:27
  • @CaitlinG The question is different there and even the sample code . – AllTooSir Jul 18 '13 at 09:29
  • Ahh, I see! The concept of polymorphism is starting to become less ambiguous. Without the array in the "driver", I could have called the methods with a simple s.method? – CaitlinG Jul 18 '13 at 09:37
4

Your approach is good - it is always recommend to programm to an interface (shape) rather to an concret implementation (circle). Polymorphism means that every concrete implementation of shape can take place as a shape.

e.g. (more like pseudo java)

Circle c = new Circle(10); // not polymorph, as c = new Square(10) will throw an error

but

Shape s = new Circle(10);
... some other code
s = new Square(10) // totaly fine

You can improve you code by using factorys for creating your shapes, e.g.

    public class ShapeFactory {
    public Shape createCircle(int param) { 
return new Circle(param);
}

public Shape createRectangle(int param, int param2) {
return new Rectangle(param, param2) };

and so on

See http://en.wikipedia.org/wiki/Factory_method_pattern

To sum up: you are on the right way!

Mirco
  • 2,940
  • 5
  • 34
  • 57
  • Thanks @verbose-mode. So I can use an interface on the left side only if the class on the right implements the interface? Can an interface exist on both sides of the "="? – CaitlinG Jul 18 '13 at 09:29
  • No! There can not be an instance (new XYZ()) of an interface. An interface describes the public methods of a class. So if you want to do something like this InterfaceA a = new ClassA(); ClassA() needs to implement that interface. See an interface as a summary of methods "shared" over all implementors of that interface. – Mirco Jul 18 '13 at 09:52
  • Danke schön @verbose-mode. An interface is then analogous to a "contract" between two parties and represents an "is-a" relationship whereby only those methods defined in the interface and implemented in those classes that implement the aforementioned interfaces are capable of being called. Is this correct? – CaitlinG Jul 18 '13 at 10:02
  • Correct. 100 points ;-) the comparison interface - contract is often made. – Mirco Jul 18 '13 at 10:04
  • Excellent! Thank you so much for your patience and help. Thanks to all the other respondents as well :) – CaitlinG Jul 18 '13 at 10:06
4

That looks fine to me - though you're not using anonymous classes anywhere, it does show how basic polymorphism works.

In general, in code like

Shape s1 = new Circle(2);
Shape s2 = new Square(2);

both the lines above work because Circle and Square implement Shape, which is really saying 'Circle is a Shape' and 'Square is a Shape'. By declaring 's1' as being type Shape you are saying that it can refer to anything that is-a Shape, ie. anything that implements Shape. Note that you can only call methods defined in the Shape interface through s1 and s2. Say that Circle had a method diameter then:

Shape s1 = new Circle(2);
s1.diameter();

will fail, because diameter doesn't exist on the Shape interface: The type a variable is declared as defines what methods can be seen, not the actual class of the instance the variable refers to. But the implementation that is called is determined by the actual class of the instance referred to - this is the core of polymorphism.

Steve Allison
  • 1,091
  • 6
  • 6