Comp 401 dynamic dispatch and abstract methods
Download
1 / 40

Comp 401 Dynamic Dispatch and Abstract Methods - PowerPoint PPT Presentation


  • 51 Views
  • Uploaded on

Comp 401 Dynamic Dispatch and Abstract Methods. Instructor: Prasun Dewan. A StringHistory Implementation. public class AStringHistory implements StringHistory { public static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0;

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Comp 401 Dynamic Dispatch and Abstract Methods' - tolla


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Comp 401 dynamic dispatch and abstract methods

Comp 401Dynamic Dispatch and Abstract Methods

Instructor: PrasunDewan


A stringhistory implementation
A StringHistory Implementation

  • public classAStringHistoryimplementsStringHistory {

    • public staticfinalint MAX_SIZE = 50;

    • String[] contents = new String[MAX_SIZE];

    • int size = 0;

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == MAX_SIZE; }

    • publicvoidaddElement(String element) {

    • if (isFull())

      • System.out.println("Adding item to a full history");

    • else {

      • contents[size] = element;

      • size++;

      • }

  • }

  • }


A big stringhistory implementation
A Big StringHistory Implementation

  • public classABigStringHistoryimplementsStringHistory {

    • public staticfinalint MAX_SIZE = 500;

    • String[] contents = new String[MAX_SIZE];

    • int size = 0;

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == MAX_SIZE; }

    • publicvoidaddElement(String element) {

    • if (isFull())

      • System.out.println("Adding item to a full history");

    • else {

      • contents[size] = element;

      • size++;

      • }

  • }

  • }


Null overridden method
Null Overridden Method

publicabstractclassAnAbstractStringHistory{

booleanisFull(){};

voiduncheckedAddElement(Object element){};

publicvoidaddElement(Object element) {

if (!isFull())

uncheckedAddElement(element);

else

handleError();

}

voidhandleError () {

System.out.println("Adding item to a full history");

};

}


A stringhistory implementation1
A StringHistory Implementation

  • public classAStringHistoryextends AnAbstractStringHistory

  • implementsStringHistory {

    • publicfinalint MAX_SIZE = 50;

    • String[] contents = new String[MAX_SIZE];

    • int size = 0;

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == MAX_SIZE; }

    • voiduncheckedAddElement(String element) {

    • contents[size] = element;

      • size++;

      • }

  • }


Dynamic dispatch
Dynamic Dispatch

publicabstractclassACollection {

booleanisFull(){};

voiduncheckedAddElement(Object element){};

publicvoidaddElement(Object element) {

if (!isFull())

uncheckedAddElement(element);

else

handleError();

}

voidhandleError () {

System.out.println("Adding item to a full history");

};

}

  • public classAStringHistoryextends ACollectionimplementsStringHistory {

    • booleanisFull() { return size == MAX_SIZE; }

    • voiduncheckedAddElement(String element) {

    • contents[size] = element;

      • size++;

      • }

  • }

Which isFull() called when addElement is invoked on an instance of AStringHistory()?

Regular method: called method “statically dispatched” at compile time, so overridden isFull()

Virtual method: most specific implementation of called method “dynamically dispatched” at execution time, so overriding isFull()


Regular vs virtual method
Regular vs. Virtual Method

  • Smalltalk: had only virtual methods

    • With each object a table kept which associates method header with most specific implementation.

    • Table accessed at execution time.

  • C++: Had both virtual and regular methods

    • More efficient with regular methods

  • Java: Has only virtual methods

    • Abstract and interface method by definition are virtual methods


Correct a big stringhistory implementation
Correct A Big StringHistory Implementation

  • public classABigStringHistoryextends AnAbstractStringHistory

  • implementsStringHistory {

    • publicfinalint MAX_SIZE = 500;

    • String[] contents = new String[MAX_SIZE];

    • int size = 0;

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == MAX_SIZE; }

    • voiduncheckedAddElement(String element) {

    • contents[size] = element;

      • size++;

      • }

  • }


An erroneous big stringhistory implementation
An Erroneous Big StringHistory Implementation

  • public classABigStringHistoryextends AnAbstractStringHistory

  • implementsStringHistory {

    • publicfinalint MAX_SIZE = 500;

    • String[] contents = new String[MAX_SIZE];

    • int size = 0;

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == MAX_SIZE; }

    • //voiduncheckedAddElement(String element) {

    • // contents[size] = element;

    • // size++;

    • //}

  • }


Null overridden method1
Null Overridden Method

publicabstractclassAnAbstractStringHistory{

booleanisFull(){};

voiduncheckedAddElement(Object element){};

publicvoidaddElement(Object element) {

if (!isFull())

uncheckedAddElement(element);

else

handleError();

}

voidhandleError () {

System.out.println("Adding item to a full history");

};

}


Abstract methods
abstract methods

publicabstractclassAnAbstractStringHistory{

abstractbooleanisFull();

abstractvoiduncheckedAddElement(Object element)

publicvoidaddElement(Object element) {

if (!isFull())

uncheckedAddElement(element);

else

handleError();

}

voidhandleError () {

System.out.println("Adding item to a full history");

};

}

Only header of method provided as in interface


An erroneous big stringhistory implementation1
An Erroneous Big StringHistory Implementation

  • public classABigStringHistoryimplementsStringHistory {

    • publicfinalint MAX_SIZE = 500;

    • String[] contents = new String[MAX_SIZE];

    • int size = 0;

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == MAX_SIZE; }

    • //voiduncheckedAddElement(String element) {

    • // contents[size] = element;

    • // size++;

    • //}

  • }

Java complains abstract method not implemented in concrete class


Null vs abstract methods
Null vs. Abstract Methods

publicabstractclassAnAbstractStringHistory{

booleanisFull() {}

voiduncheckedAddElement(Object element) {}

publicvoidaddElement(Object element) {

if (!isFull())

uncheckedAddElement(element);

else

handleError();

}

voidhandleError () {

System.out.println("Adding item to a full history");

};

}

Null methods could replace abstract methods in this example.

Abstract method force overriding implementations in subclasses.

Provide better documentation, indicating to programmer that subclass will implement them.


Abstract method
Abstract method

  • Declared only in abstract classes

  • Keyword: abstract

  • No body

  • Each (direct or indirect) subclass must implement abstract methods defined by an abstract class.

  • Much like each class must implement the methods defined by its interface(s).


Abstract class vs methods
Abstract class vs. methods

  • Abstract method => containing class abstract

    • Cannot have an unimplemented method in an instance

  • Abstract class may not contain abstract method


Abstract class
Abstract Class

publicabstractclassAnAbstractStringHistory{

abstractbooleanisFull();

abstractvoiduncheckedAddElement(Object element);

publicvoidaddElement(Object element) {

if (!isFull())

uncheckedAddElement(element);

else

handleError();

}

voidhandleError () {

System.out.println("Adding item to a full history");

};

}


Concrete class
Concrete Class

  • public classABigStringHistoryextends AnAbstractStringHistory

  • implementsStringHistory {

    • publicstaticfinalint MAX_SIZE = 500;

    • String[] contents = new String[MAX_SIZE];

    • int size = 0;

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == MAX_SIZE; }

    • voiduncheckedAddElement(String element) {

    • contents[size] = element;

      • size++;

      • }

  • }

Move more code to abstract class?


New abstract class
New Abstract Class

  • public classAnAbstractStringHistoryimplementsStringHistory {

    • String[] contents = new String[maxSize()];

    • int size = 0;

    • abstractintmaxSize();

    • publicint size() { return size;}

    • public String elementAt (int index) { return contents[index]; }

    • booleanisFull() { return size == maxSize(); }

    • publicvoidaddElement(String element) {

    • if (isFull())

      • System.out.println("Adding item to a full history");

    • else {

      • contents[size] = element;

      • size++;

      • }

  • }

  • }


New concrete class
New Concrete Class

  • public classABigStringHistoryextends AnAbstractStringHistory

  • implementsStringHistory {

    • publicstaticfinalint MAX_SIZE = 500;

    • intmaxSize() {

    • return MAX_SIZE;

    • }

  • }

Method call needed to access constant


Another course
Another Course

package courses;

publicabstractclassACourse {

String title, dept;

publicACourse (String theTitle, String theDept) {

super();

title = theTitle;

dept = theDept;

}

public String getTitle() {

return title;

}

publicString getDepartment() {

return dept;

}

abstractpublicintgetNumber();

}

Abstract Method


Alternative aregularcourse
Alternative ARegularCourse

package courses;

publicclassARegularCourseextendsACourse {

intcourseNum;

publicARegularCourse (String theTitle, String theDept, inttheCourseNum) {

super (theTitle, theDept);

courseNum = theCourseNum;

}

publicintgetNumber() {

returncourseNum;

}

}

Like interface, force implementation of getNumber()

Implementation of abstract method


Alternative afreshmanseminar
Alternative AFreshmanSeminar

package courses;

publicclassAFreshmanSeminarextendsACourse {

publicAFreshmanSeminar (String theTitle, String theDept) {

super (theTitle, theDept);

}

publicintgetNumber() {

return SEMINAR_NUMBER;

}

}

Implementation of abstract method


Abstract class1
Abstract Class

publicabstractclassAnAbstractStringHistory{

abstractbooleanisFull();

abstractvoiduncheckedAddElement(Object element);

publicvoidaddElement(Object element) {

if (!isFull())

uncheckedAddElement(element);

else

handleError();

}

voidhandleError () {

System.out.println("Adding item to a full history");

};

}

Not public


Factory abstract method
Factory Abstract Method

abstract <T> <M>(…) ;

extends

<T> <M>(…) {

returnnew <C1> (…)

}

<T> <M> (…){

returnnew <C2> (…)

}

Abstract method that returns an instance of some type T – like a factory, it creates and initializes an object.


Abstract methods vs interfaces
Abstract methods vs. Interfaces

  • Unimplemented methods become abstract methods to be implemented by concrete subclasses. Do not need explicit implements clause in subclass if no additional public methods implemented,

    • publicclassARegularCourseextendsACourse {

      ….

      }

  • A class with only abstract methods simulates interfaces.

  • No multiple inheritance in Java

  • Separation of abstract and concrete methods with interfaces.

  • A class implements but does not inherit a specification!


Abstract methods vs interfaces1
Abstract methods vs. Interfaces

  • Non-public abstract methods relevant even in Java

  • All interface methods must be public.

  • May want non public abstract methods.E.g.

    • abstractbooleanisFull() ;


Another course1
Another Course

package courses;

publicabstractclassACourseimplements Course {

String title, dept;

publicACourse (String theTitle, String theDept) {

super();

title = theTitle;

dept = theDept;

}

public String getTitle() {

return title;

}

publicString getDepartment() {

return dept;

}

}

An abstract class can implement any interface

This means all sub classes implement the interface

Interface implementation check is made for concrete classes


Alternative aregularcourse1
Alternative ARegularCourse

package courses;

publicclassARegularCourseextendsACourse {

intcourseNum;

publicARegularCourse (String theTitle, String theDept, inttheCourseNum) {

super (theTitle, theDept);

courseNum = theCourseNum;

}

publicintgetNumber() {

returncourseNum;

}

}

Saying ARegularCourse implements Course is redundant


Alternative afreshmanseminar1
Alternative AFreshmanSeminar

package courses;

publicclassAFreshmanSeminarextendsACourse {

publicAFreshmanSeminar (String theTitle, String theDept) {

super (theTitle, theDept);

}

publicintgetNumber() {

return SEMINAR_NUMBER;

}

}

No need for implementation clause


Overloading polymorphism and dynamic dispatch

Polymorphic method

ARegularCourse

AFreshmanSeminar

getNumber() in ARegularCouse

getNumber() in AFreshmanSeminar

Dynamically dispatched method

Overloaded method

Overloading, Polymorphism, and Dynamic dispatch

static void print (Course course) {

System.out.println(

course.getTitle() + " " +

course.getDepartment() +

course.getNumber()

);

}

static void print (CourseListcourseList) {

print(course);

}


Overloading polymorphism and dynamic dispatch1
Overloading, Polymorphism, and Dynamic dispatch

  • Same method name works on different types.

  • Overloading

    • Multiple (static or instance) methods with same name but different parameter types.

    • Resolved at compile time based on parameter types

  • Polymorphism

    • Same method implementation works on multiple object types.

  • Dynamic dispatch (or virtual methods)

    • Multiple instance methods with same name in different classes

    • Resolved at execution time based on type of target object


Polymorphism vs overloading and dynamic dispatch
Polymorphism vs. Overloading and Dynamic Dispatch

  • Polymorphism vs. Overloading

    • Polymorphism: single print (Course course)

    • Overloading: print (ARegularCourse course) and print (AFreshmanSeminar course) with same implementation.

  • Polymorphism vs. Dynamic Dispatch

    • Polymorphism: single getTitle() in ACourse

    • Dynamic dispatch: getTitle() in AFreshmanSeminar() and getTitle() in ARegularCourse() with same implementation.

  • Create polymorphic code when you can

    • In overloading and dynamic dispatch, multiple implementations associated with each method name.

    • In polymorphic case, single implementation.

      • Use interfaces rather than classes as types of parameters

      • Use supertypes rather than subtypes as types of parameters


Polymorphism vs overloading and dynamic dispatch1
Polymorphism vs. Overloading and Dynamic Dispatch

  • Cannot always create polymorphic method.

    • getNumber() for ARegularCourse and AFreshmanSeminar do different things.

    • print(Course course) and print (CourseListcourseList) do different things.

  • When polymorphism not possible try overloading and dynamic dispatch.


Manual instead of dynamic dispatch
Manualinstead of Dynamic Dispatch

staticvoid print (Course course) {

if (course instanceofARegularCourse)

number = ((ARegularCourse)course).getCourseNumberRegularCourse ();

else if (course instanceofAFreshmanSeminar)

number = ((AFreshmanSeminar)course).getCourseNumberFreshmanSeminar ();

System.out.println(

course.getTitle() + " " +

course.getDepartment() +

number );

}

Must update code as subtypes added

More Work


Can we get rid of manual dispatch instanceof
Can we get rid of manual dispatch/instanceof?

staticvoid print (Course course) {

if (course instanceofRegularCourse)

System.out.print(“Regular Course: ”);

elseif (course instanceofAFreshmanSeminar)

System.out.println(“Freshman Seminar”);

System.out.println(

course.getTitle() + " " +

course.getDepartment() +

course.getNumber() );

}


Cannot always get rid of manual dispatch instancof
Cannot always get rid of manual dispatch/instancof

staticvoid print (Course course) {

printHeader (course);

System.out.println(

course.getTitle() + " " +

course.getDepartment() +

course.getNumbert() );

}

staticvoidprintHeader (ARegularCourse course) {

System.out.print(“Regular Course: ”);

}

staticvoidprintHeader (AFreshmanSeminar course) {

System.out.print(“Freshman Seminar: ”);

}

Actual parameter cannot be supertype of formal parameter

At compile time, do not know if regular course or freshman seminar


Printheader in aregularcourse
printHeader() in ARegularCourse

package courses;

publicclassARegularCourseextendsACourseimplements Course {

publicvoidprintHeader () {

System.out.print (“Regular Course: ”)

}

}


Printheader in afreshmanseminar
printHeader() in AFreshmanSeminar

package courses;

publicclassAFreshmanSeminarextendsACourse implements FreshmanSeminar {

publicvoidprintHeader () {

System.out.print (“Freshman Seminar: ”)

}

}


Should not always get rid of manual dispatch instancof
Should not always get rid of manual dispatch/instancof

staticvoid print (Course course) {

printHeader (course);

System.out.println(

course.getTitle() + " " +

course.getDepartment() +

course.getNumbert() );

}

staticvoidprintHeader (ARegularCourse course) {

System.out.print(“Regular Course: ”);

}

staticvoidprintHeader (AFreshmanSeminar course) {

System.out.print(“Freshman Seminar: ”);

}

Should not put printHeader() in ARegularCourse or AFreshmanSeminar as it is UI code.

Hence need to use instanceof

Used in parsers



ad