Arvutiteaduse instituut
  1. Kursused
  2. 2018/19 kevad
  3. Objektorienteeritud programmeerimine (Narva Kolledž) (LTAT.NR.003)
EN
Logi sisse

Objektorienteeritud programmeerimine (Narva Kolledž) 2018/19 kevad

  • Home
  • Materials
  • Java Glossary
  • Source Example
  • Cheat sheet (S1-S6)
  • Grading
  • Links
Session 5

Polymorphism

One of the most powerful benefits of inheritance is that it allows client class to treat different kinds of objects in the same way. For example, with the Person class hierarchy described earlier, it’s possible for client class to create an array or other data structure that contains both persons and students, and then perform operations on each element of that array. The client class will behave differently depending on the type of object that is used, because each subclass overrides and changes some of the behavior from the superclass. This ability for the same code to be used with several different types of objects is called polymorphism.

The word polymorphism literally means "having many forms". In Java, it means that one variable might be used with several objects of related classes at different times in a program.

Polymorphism is made possible by the fact that the type of a reference variable (one that refers to an object) does not have to exactly match the type of the object it refers to. More specifically, it is legal for a superclass variable to refer to an object of its subclass. The following is a legal assignment statement:

 Person p1 = new Student("Lisa","University of Tartu");

When we were studying the primitive types, we saw cases in which a variable of one type could store a value of another type (for example, an int value can be stored in a double variable). In the case of primitive values, Java converts variables from one type to another: int values are automatically converted to doubles when they are assigned.

When a subclass object is stored in a superclass variable, no such conversion occurs. The object referred to by p1 really is a Student object, not an Person object. If we call methods on it, it will behave like a Student object.

This ability for variables to refer to subclass objects allows us to write flexible code that can interact with many types of objects in the same way. For example, we can write a method that accepts an Person as a parameter, returns an Person, or creates an array of Person objects. In any of these cases, we can substitute a Student or other subclass object of Person, and the code will still work. Even more importantly, code will actually behave differently depending on which type of object is used, because each subclass overrides and changes some of the behavior from the superclass. This is polymorphism at work.

Study the following example:

// A class to represent employees in general.
class Employee {
    public int getHours() {
        return 40;
    }

    public double getSalary() {
        return 40000.0;
    }
}

// A class to represent lawyers.
class Lawyer extends Employee {
    // overrides getSalary from Employee class
    public double getSalary() {
        return 80000.0;
    }
    // this is the Lawyer's added behavior
    public void sue() {
        System.out.println("I'll see you in court!");

    }
}

// A class to represent secretaries.
class Secretary extends Employee {
    // this is the Secretary's added behavior
    public void takeDictation(String text) {
        System.out.println("Dictating text: " + text);
    }
}

// Demonstrates polymorphism by passing many types of employees
// as parameters to the same method.
public class Test {
    // Prints information about any kind of employee.
    public static void printInfo(Employee e) {
        System.out.print("Hours: " + e.getHours() + ", ");
        System.out.print("Salary: " + e.getSalary() + ", ");
        System.out.println(e); 
    }

    public static void main(String[] args) {
        Employee edna = new Employee();  
        Employee lucy = new Lawyer(); // polymorphism
        Secretary stan = new Secretary();

        // create a list to perform different operations
        Employee[] staff = {edna, lucy, stan};

        for (Employee e : staff) {
            printInfo(e);
        }
    }
}

The program output is:

 Hours: 40, Salary: 40000.0, Employee@73f792cf
 Hours: 40, Salary: 80000.0, Lawyer@2ed94a8b
 Hours: 40, Salary: 40000.0, Secretary@38082d64

Notice that the method let us pass many different types of Employee as parameters, and it produces different behavior depending on the type that is passed. Polymorphism gives us this flexibility. The last token of output printed for each employee is the employee object itself, which calls the toString method. Our classes do not have toString methods, so the program uses the method of the Object class.

The word polymorphism comes from the Greek words "poly" and "morph", which mean "many" and "forms", respectively. The lines of code in the printInfo method are polymorphic because their behavior will take many forms depending on what type of employee is passed as the parameter.

The program does not know which getSalary method to call until it is actually running. When the program reaches a particular call to an object’s method, it examines the actual object (not its instance) to see which method to call. This concept has taken many names over the years, such as late binding, virtual binding, and dynamic dispatch.

Note when we send messages to an object stored in a variable of a superclass type, it is legal only to call methods that are known to the superclass (not to the subclasses). For example, the following code will not compile because the Employee class has no takeDictation method:

   public static void printInfo(Employee e) {
        System.out.print("Hours: " + e.getHours() + ", ");
        System.out.print("Salary: " + e.getSalary() + ", ");
        System.out.println(e); // toString representation of employee
        // takeDictation() is not know to Employee; results in an error
        System.out.println("Dictation: " + e.takeDictation("Hello")); 
    }
Session 5
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused