Introduction: how you have used reference variables thus far...

  • So far, we have always use a reference variable to point to an object of the same class:

     ClassA x = new ClassA();    
    

  • We will learn how to use a reference variable that points to an object of a different class:

     ClassA x = new ClassB();   
    

  • What is the effect ??? and when is it safe/allowed ???

The information conveyed in a class definition

  • Consider a class definition:

    public class SomeClass
    {
        public int x = 44;
        
        public void method1() 
        {
            System.out.println("SomeClass.m1()");
        }
        
        public void method2() 
        {
            System.out.println("SomeClass.m2()");
        }
    } 

  • We have used a class to:   (1) define variables and (2) create objects:

      (1) SomeClass  a ;       // Defines a reference variable
    
      (2) a = new SomeClass(); // Create a SomeClass object

The information conveyed in a class definition

  • A class definition conveys some specify information to the Java compiler:

    public class SomeClass
    {
        public int x = 44;
        
        public void method1()
        {
            System.out.println("SomeClass.m1()");
        }
        
        public void method2()
        {
            System.out.println("SomeClass.m2()");
        }
    } 

  • A class definition tells the Java compiler the members (variables & methods) of a class:

    • A SomeClass object has a variable named x
    • A SomeClass object has a method named method1()
    • A SomeClass object has a method named method2

  How the Java compiler uses the member information of a class definition - part 1  

  • A class definition tells the Java compiler the members (variables & methods) of a class:

    public class SomeClass
    {
        has variable: public int x;
        
        has method:   public void method1()
        has method:   public void method2()
    } 

  • When we instantiate a SomeClass object:

       new SomeClass() 
    

    the Java compiler knows that this object can only do the following:

    • provide the value in a variable named x

    • perform the method method1()

    • perform the method method2()

  How the Java compiler uses the member information of a class definition - part 2  

  • A class definition tells the Java compiler the members (variables & methods) of a class:

    public class SomeClass
    {
        has variable: public int x;
        
        has method:   public void method1()
        has method:   public void method2()
    } 

  • When we define a SomeClass (reference) variable a:

      SomeClass  a ;
    

    the Java compiler will only allows the user to request the following actions using a:

    • a.x     use the variable named x

    • a.method1()     execute the method method1()

    • a.method2()     execute the method method2()

The correctness of program execution

Suppose a SomeClass variable a is referencing to an arbitrary object:

Java will allow the user to make these legal access requests:   (1) a.x   (2) a.method1()   (3) a.method2()

The correctness of program execution

Correctness condition:   a reference variable must point to an object that can fulfill all legal access requests

Reason:   if the object cannot fulfill a legal request, the program execution will fail !

The normal way to use objects

The simplest way to satisfy the rule is to reference to an object of the same class:

However: there is another safe (= correct) way due to the inheritance relationship !!

Review:   a subclass inherits all normal members from its superclass

A subclass inherits all the normal members (excluding constructors) from its superclass:

 

Review:   a subclass object contains a superclass object

A subclass object contains all normal members found in a superclass object:

 

Review:   a subclass object contains a superclass object

A subclass object contains all normal members even when we override some methods:

 

Review + intro to polymorphism:   using an instance variable to access members in an object

An instance variable a of the type SomeClass can be used to access the (public) members in SomeClass:

 

Review + intro to polymorphism:   using an instance variable to access members in an object

An instance variable a of the type NewClass can be used to access the (public) members in NewClass :

 

A subclass object can perform all actions of a superclass object

Notice that:   a subclass object can perform all actions that a superclass object performs:

 

A subclass object can perform all actions of a superclass object

Therefore, it is safe to use a superclass reference variable to request members in a subclass object:

Java allows you to access members in a subclass object using a superclass reference variable !

Example that show the legal assignment of a subclass object to a superclass variable

 

public class myProg
{
    public static void main(String[] args)
    {
        SomeClass a; // Defines a reference variable of
	             // type SomeClass
		     // Allowable requests using a:
		     //     a.x
		     //     a.method1();
		     //     a.method2();

	a = new NewClass(); // Make a reference to a NewClass object

	             // Legal, because the NewClass object
		     // can perform all actions
		     // required by the SomeClass type
    }
} 
  

DEMO: demo/13-inheritance/18-polymorphism/Demo1.java

Dynamic dispatch (a.ka.: late binding)

Furthermore:   the request a.method() will execute the method in the object that a is currently pointing to:

This feature is called "dynamic dispatch" or late binding (decision on which method to run is at the last moment)

Example using a superclass instance variable to access members in NewClass

public class myProg
{
  public static void main(String[] args)
  {
    // New way to access member in NewClass

    SomeClass a = new NewClass(); // Allowed !

    System.out.println(a.x);
    a.method1(); // exec NewClass' method1()
    a.method2();
  //a.method3(); // This is illegal !
  }
} 
public class NewClass extends SomeClass
{
  public void method1() // Override
  {
    System.out.println("**NewClass.m1()");
  }
    
  public void method3()
  {
    System.out.println("**NewClass.m3()");
  }
 
}


  
public class SomeClass
{
  public int x = 44;
    
  public void method1()
  {
    System.out.println("SomeClass.m1()");
  }
    
  public void method2()
  {
    System.out.println("SomeClass.m2()");
  }
 
}
  

DEMO: demo/13-inheritance/18-polymorphism/Demo2.java

Because a is pointing to a NewClass object, a.method1() will execute NewClass' method1() eventhough a is a SomeClass variable

Polymorphism

  • Consider the following program:

         SomeClass a; // Superclass reference variable
    
         // Use superclass variable to accces
         // overridden method in superclass
         a = new SomeClass();  // References superclass object
         a.method1();          // Calls SomeClass.method1()
    
         // Use superclass variable to accces
         // overridden method in subclass
         a = new NewClass();   // References subclass object
         a.method1();          // Calls NewClass.method1() 

    The same expression a.method1() invokes different methods !!!


  • Polymorphism = the phenomenon that the same expression (= program code) can result in different actions

  • Polymorphism is caused by (1) the ability to use a superclass variable to access overridden members in (a) the superclass and (b) their subclasses and (2) the late binding mechanism

DEMO: demo/13-inheritance/18-polymorphism/Demo3.java

The reverse case --- a superclass object may perform fewer actions than a subclass object

Notice:   a subclass object may perform fewer actions that a subclass object can perform:

 

A subclass object can perform more actions than a superclass object

Therefore, it is illegal to use a subclass reference variable to access members in a superclass object:

E.g.:   the request a.method3() is illegal because there is no method3() defined inside a SomeClass object

Example that show the illegal assignment of a superclass object to a subclass variable

 

public class myProg
{
    public static void main(String[] args)
    {
        NewClass a; // Defines a reference variable of
	            // type NewClass
		    // Allowable requests using a:
		    //     a.x
		    //     a.method1();
		    //     a.method2();
		    //     a.method3();

	a = new SomeClass(); // Make a reference to a SomeClass object

	            // Illegal, because the SomeClass object
		    // cannot perform:
		    //       a.method3();
    }
} 
  

DEMO: demo/13-inheritance/18-polymorphism/Demo4.java