티스토리 뷰

IT/프로그래밍

Java Guide - Polymorphism

NineKY 2007. 7. 31. 12:56

Overview

The word polymorphism is Greek and literally means “many forms.” In Java, polymorphism means using a superclass variable to refer to a subclass object. This ability has a wide variety of uses.

Reasoning

Polymorphism is useful in that it allows Java programs to be written more abstractly, and more abstraction allows for more efficiency and less redundancy. Imagine you are working with a family of classes, and a certain program requires use of one of the subclasses, but it will not know which subclass to use until runtime. In this case, you can use a superclass variable throughout the program, and point it to the corresponding subclass when the time is right. Polymorphism is also useful when using certain methods throughout different families of classes. In general, polymorphism allows inheritance and interfaces to be used more abstractly.

Implementation

Polymorphism is applied in certain cases where one needs to use an object, and knows the family of classes the object resides in, but does not know exactly what object to use until a certain time.

For an example of this, remember the Animal interface and hierarchy from the Abstraction and Interfaces section of the guide. Imagine you are creating a game, in which the user chooses a certain door and behind each door is a different kind of animal.

import java.util.Scanner;

public class AnimalGame
{
      public static void main(String[] args)
      {
            System.out.println("Choose one of three doors by entering the number of the door you choose.");
            Scanner input = new Scanner(System.in);
            int doorNumber = input.nextInt();

            Animal animal = null;

            if (doorNumber == 1)
            {
                  animal = new Cat();
            }

            else if (doorNumber == 2)
            {
                  animal = new Dog();
            }
            else if (doorNumber == 3)
            {
                  animal = new TRex();
            }

            else
            {
                  System.out.println("Not a valid door number");
                  System.exit(1);
            }

            System.out.println("The animal behind your door says: " + animal.talk());
     }
}

Notice right away the animal variable being created. Note that it is not being instantiated; that would be impossible since type Animal is an interface. If the user chooses door one, animal gets instantiated as a new Cat object. Likewise if the user chooses door two, animal becomes a Dog, and if they choose door three, animal becomes aTRex. The decision to make variable animal a certain type does not occur until runtime. This is a special feature of Java and it is called “late binding.” It is late binding that allows polymorphism to work.

Also notice that the talk() method is being called on the animal object, even though the compiler doesn’t know which animal the method will be called by. This is allowed because Cat, Dog, and TRex all implement the Animal interface, and thus all have a talk() method. This principle applies to inheritance between all subclasses and superclasses, whether the superclass is a normal class, an abstract class or an interface.

How Interfaces Increase Polymorphism
In the event that you want to have a method or set of methods be common between several families of classes, rather than only among one family, using an interface can stretch the ability of polymorphism over many families of classes.

For example, remember the abstract class Electronic from the Abstraction and Interfaces section of the guide. It contains one abstract method called operate(). Imagine that you want the operate() method to be available to more than just the Electronic family of classes. You can create an interface that contains the method operate(), and tell the Electronic abstract class to implement that interface.

interface Operator
{
      void operate();
}

public abstract class Electronic implements Operato
r {
      boolean powerOn = false;

      public boolean isOn()
      {
            return powerOn;
      }

      public void turnOn()
      {
            powerOn = true;
            System.out.println("Turned on");
      }

      public void turnOff()
      {
            powerOn = false;
            System.out.println("Turned off");
      }

      public abstract void operate();
}

The abstract class Electronic and its subclasses still uses the operate() method in the same way they used to, however now other families of classes may use the operate() method as well by implementing the Operator interface.

For example, class Surgeon also implements the Operator interface, and carries its own definition for the operate() method.

public class Surgeon implements Operator
{
      String selectedOrgan;

      public Surgeon(String organ)
      {
            selectedOrgan = organ;
      }

      public void operate()
      {
            System.out.println("Removed " + selectedOrgan);
      }
}

Now, subclasses of the Surgeon class may use the operate() method as well. Also, any class in the Electronic or Surgeon family can be referenced as an Operator object, allowing twice the polymorphism than before. This is how interfaces optimize polymorphism.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함