Object-Oriented Programming 95-712 MISM/MSIT Carnegie Mellon University Lecture 4: Polymorphism.

Slides:



Advertisements
Similar presentations
Object Oriented Programming with Java
Advertisements

A subclass can add new private instance variables A subclass can add new public, private or static methods A subclass can override inherited methods A.
Big Ideas behind Inheritance. Can you think of some possible examples of inheritance hierarchies?
Intermediate Java Sakir YUCEL MISM/MSIT Carnegie Mellon University Lecture: Access Control & Reuse Slides adapted from Prof. Steven Roehrig.
DATA STRUCTURES Lecture: Inheritance Slides adapted from Prof. Steven Roehrig.
ACM/JETT Workshop - August 4-5, :Inheritance and Interfaces.
23-May-15 Polymorphism. 2 Signatures In any programming language, a signature is what distinguishes one function or method from another In C, every function.
1 CS2200 Software Development Polymorphism II A. O’Riordan, 2008 K. Brown,
Inheritance. Extending Classes It’s possible to create a class by using another as a starting point  i.e. Start with the original class then add methods,
Object-Oriented Programming MISM/MSIT Carnegie Mellon University Professor Roehrig’s Notes.
Polymorphism What is Polymorphism? Taking Advantage of Polymorphism
Intermediate Java II Sakir YUCEL MISM/MSIT Carnegie Mellon University Lecture: Exception Handling Slides adapted from Prof. Steven Roehrig.
Object-Oriented Programming MISM/MSIT Carnegie Mellon University Lecture 4: Access Control & Reuse.
1 Chapter 6 Inheritance, Interfaces, and Abstract Classes.
1 Lecture 4 Further OO Concepts I - Polymorphism Overview  What is polymorphism?  Why polymorphism is wonderful?  Why is Upcasting useful?  What is.
1 Evan Korth New York University Inheritance and Polymorphism Professor Evan Korth New York University.
Object-Oriented Programming C Sakir YUCEL MISM/MSIT Carnegie Mellon University Lecture 5: Polymorphism Slides adapted from Prof. Steven Roehrig.
Inheritance and Polymorphism Recitation – 10/(16,17)/2008 CS 180 Department of Computer Science, Purdue University.
1 Further OO Concepts (Part I) Further OO Concepts I - Polymorphism Overview l Polymorphism is Wonderful. l Usefulness of Up casting? l Method call binding?
1 Evan Korth New York University Inheritance and Polymorphism Professor Evan Korth New York University.
OOP Etgar 2008 – Recitation 71 Object Oriented Programming Etgar 2008 Recitation 7.
Chapter 10: Inheritance and Polymorphism
Intermediate Java Sakir YUCEL MISM/MSIT Carnegie Mellon University Lecture: Polymorphism Slides adapted from Prof. Steven Roehrig.
1 Lecture#8: EXCEPTION HANDLING Overview l What exceptions should be handled or thrown ? l The syntax of the try statement. l The semantics of the try.
Vocabulary Key Terms polymorphism - Selecting a method among many methods that have the same name. subclass - A class that inherits variables and methods.
Polymorphism &Virtual Functions
1 Abstract Class There are some situations in which it is useful to define base classes that are never instantiated. Such classes are called abstract classes.
1 Object-Oriented Software Engineering CS Interfaces Interfaces are contracts Contracts between software groups Defines how software interacts with.
Polymorphism, Inheritance Pt. 1 COMP 401, Fall 2014 Lecture 7 9/9/2014.
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Programming With Java ICS201 University Of Ha’il1 Chapter 8 Polymorphism and Abstract Classes.
Inheritance. Introduction Inheritance is one of the cornerstones of object-oriented programming because it allows the creation of hierarchical classifications.
Recitation 4 Abstract classes, Interfaces. A Little More Geometry! Abstract Classes Shape x ____ y ____ Triangle area() base____ height ____ Circle area()
Inheritance - Polymorphism ITI 1121 Nour El Kadri.
RIT Computer Science Dept. Goals l Inheritance l Modifiers: private, public, protected l Polymorphism.
1 Inheritance. 2 Why use inheritance?  The most important aspect of inheritance is that it expresses a relationship between the new class and the base.
Polymorphism. 3 main programming mechanisms that constitute OOP: 1. Encapsulation 2. Inheritance 3. Polymorphism.
Copyright © 2014 by John Wiley & Sons. All rights reserved.1 Chapter 10 - Interfaces.
Chapter 3 Inheritance and Polymorphism Goals: 1.Superclasses and subclasses 2.Inheritance Hierarchy 3.Polymorphism 4.Type Compatibility 5.Abstract Classes.
1 final (the keyword, not the exam). 2 Motivation Suppose we’ve defined an Employee class, and we don’t want someone to come along and muck it up  E.g.,
CS 376b Introduction to Computer Vision 01 / 23 / 2008 Instructor: Michael Eckmann.
1 Interfaces and Abstract Classes Chapter Objectives You will be able to: Write Interface definitions and class definitions that implement them.
DATA STRUCTURES Lecture: Polymorphism Slides adapted from Prof. Steven Roehrig.
Abstract Classes and Interfaces 5-Dec-15. Abstract methods You can declare an object without defining it: Person p; Similarly, you can declare a method.
Inheritance and Access Control CS 162 (Summer 2009)
Sadegh Aliakbary Sharif University of Technology Fall 2010.
Sadegh Aliakbary Sharif University of Technology Spring 2011.
Copyright 2008 by Pearson Education Building Java Programs Chapter 9 Lecture 9-2: Static Data; More Inheritance reading:
1 COSC2007 Data Structures II Chapter 9 Class Relationships.
Java Programming: From Problem Analysis to Program Design, 3e Chapter 11 Inheritance and Polymorphism.
Peyman Dodangeh Sharif University of Technology Fall 2014.
Object-Oriented Programming Dr. Ramzi Saifan Slides adapted from Prof. Steven Roehrig.
Quick Review of OOP Constructs Classes:  Data types for structured data and behavior  fields and methods Objects:  Variables whose data type is a class.
CMSC 202 Polymorphism. 10/20102 Topics Binding (early and late) Upcasting and downcasting Extensibility The final modifier with  methods  classes.
OOP in Java : © W. Milner 2005 : Slide 1 Java and OOP Part 3 – Extending classes.
Object Oriented Programming Elhanan Borenstein Lecture #7.
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
Classes Revisited Chapter 8.
OOP Basics Classes & Methods (c) IDMS/SQL News
COP 2220 Computer Science I Topics –Breaking Problems Down –Functions –User-defined Functions –Calling Functions –Variable Scope Lecture 4.
COMP Inheritance and Polymorphism Yi Hong June 09, 2015.
CSCI-383 Object-Oriented Programming & Design Lecture 17.
Notices Assn 2 is due tomorrow, 7pm. Moodle quiz next week – written in the lab as before. Everything up to and including today’s lecture: Big Topics are.
CSCI 383 Object-Oriented Programming & Design Lecture 22 Martin van Bommel.
7: Polymorphism Upcasting revisited Forgetting the object type
Inheritance and Polymorphism
Polymorphism 11-Nov-18.
More inheritance, Abstract Classes and Interfaces
Object-Oriented Programming
Polymorphism 2019/4/29.
Presentation transcript:

Object-Oriented Programming MISM/MSIT Carnegie Mellon University Lecture 4: Polymorphism

Today’s Topics Upcasting again Upcasting again Method-call binding Method-call binding Why polymorphism is good Why polymorphism is good Constructors and polymorphism Constructors and polymorphism Downcasting Downcasting

Upcasting Again class CellPhone { cellPhone() { //…} public void ring(Tune t) { t.play(); } } class Tune { public void play() { System.out.println("Tune.play()"); } class ObnoxiousTune extends Tune{ ObnoxiousTune() { // …} // … }

An ObnoxiousTune “is-a” Tune public class DisruptLecture { public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); ObnoxiousTune ot = new ObnoxiousTune(); noiseMaker.ring(ot); // ot works though Tune called for } Tune ObnoxiousTune A “UML” diagram

Aspects of Upcasting Upcasting is a cast Upcasting is a cast The exact type of the object is lost The exact type of the object is lost What gets printed in the CellPhone example? What gets printed in the CellPhone example? Tune.play() (what were you expecting?) Tune.play() (what were you expecting?) Is this “the right thing to do”? Is this “the right thing to do”? The alternative: write separate ring() methods for each subclass of Tune? The alternative: write separate ring() methods for each subclass of Tune?

Another Example class CellPhone { CellPhone() { //…} public void ring(Tune t) { t.play(); } } class Tune { Tune() { //…} public void play() { System.out.println("Tune.play()"); } class ObnoxiousTune extends Tune{ ObnoxiousTune() { // …} public void play() { System.out.println("ObnoxiousTune.play()"); }

Polymorphism The second example prints ObnoxiousTune.play() The second example prints ObnoxiousTune.play() Since an ObnoxiousTune object was sent to ring(), the ObnoxiousTune’s play() method is called. Since an ObnoxiousTune object was sent to ring(), the ObnoxiousTune’s play() method is called. This is called “polymorphism” This is called “polymorphism” Most people think it’s “the right thing to do” Most people think it’s “the right thing to do”

Polymorphism (cont.) Selecting the correct method to call (polymorphically) can’t be done by the compiler: Selecting the correct method to call (polymorphically) can’t be done by the compiler: public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); Tune t = new Tune(); ObnoxiousTune ot = new ObnoxiousTune(); double d = Math.random(); if (d > 0.5) noiseMaker.ring(t); else noiseMaker.ring(ot); }

Method-Call Binding The correct method is attached (“bound”) to the call at runtime. The correct method is attached (“bound”) to the call at runtime. The runtime system discovers the type of object sent to ring(), and then selects the appropriate play() method: The runtime system discovers the type of object sent to ring(), and then selects the appropriate play() method: –if it’s a Tune object, Tune’s play() is called –if it’s an ObnoxiousTune object, ObnoxiousTune’s play() is called

Is Java Always Late-Binding? Yes, always, except for final methods. Yes, always, except for final methods. final methods can’t be overridden, so the compiler knows to bind it. final methods can’t be overridden, so the compiler knows to bind it. The compiler may be able to do some speed optimizations for a final method, but we programmers are usually lousy at estimating where speed bottlenecks are… The compiler may be able to do some speed optimizations for a final method, but we programmers are usually lousy at estimating where speed bottlenecks are… In C++, binding is always at compile-time, unless the programmer says otherwise. In C++, binding is always at compile-time, unless the programmer says otherwise.

Another Polymorphism Example public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); Tune t1 = new Tune(); Tune t2 = new ObnoxiousTune(); double d = Math.random(); if (d > 0.5) noiseMaker.ring(t1); else noiseMaker.ring(t2); }

References and Subclasses We’ve seen that an ObnoxiousTune object can be supplied where a Tune object is expected. We’ve seen that an ObnoxiousTune object can be supplied where a Tune object is expected. Similarly, a Tune reference can refer to an ObnoxiousTune object. Similarly, a Tune reference can refer to an ObnoxiousTune object. In both cases, the basic question is: “Is an ObnoxiousTune really a proper Tune?” Yes! In both cases, the basic question is: “Is an ObnoxiousTune really a proper Tune?” Yes! This doesn’t work the other way around: any old Tune may not be an ObnoxiousTune. This doesn’t work the other way around: any old Tune may not be an ObnoxiousTune. So, an ObnoxiousTune reference cannot refer to a Tune object. So, an ObnoxiousTune reference cannot refer to a Tune object.

Let’s Fool the Compiler! public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); Tune t1 = new Tune(); Tune t2 = new ObnoxiousTune(); noiseMaker.ring(t1); noiseMaker.ring((Tune)t2); } Nothing changes…

Let’s Fool the Compiler! public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); Tune t1 = new Tune(); Tune t2 = new ObnoxiousTune(); noiseMaker.ring(t1); noiseMaker.ring((ObnoxiousTune) t2); } Nothing changes…

Let’s Fool the Compiler! public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); Tune t1 = new Tune(); Tune t2 = new ObnoxiousTune(); noiseMaker.ring((ObnoxiousTune) t1); noiseMaker.ring(t2); } This compiles, but gets a CastClassException at runtime (even though Tune has a play() method). “Downcasting” can be dangerous!

Extensibility I public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); SimpleInput keyboard = new SimpleInput(); System.out.println("Enter number of tunes:"); int numTunes = keyboard.nextInt(); Tune[] tunes = new Tune[numTunes]; for (int i = 0; i < numTunes; i++) { System.out.println("Enter tune type"); System.out.println("(Tune=1, ObnoxiousTune=2)"); int tuneType = keyboard.nextInt(); switch(tuneType) { case 1: tunes[i] = new Tune(); break; case 2: tunes[i] = new ObnoxiousTune(); break; default: tunes[i] = new Tune(); break; } for (int i = 0; i < tunes.length; i++) noiseMaker.ring(tunes[i]); }

Extensibility II public class NiceTune extends Tune { NiceTune() {} public void play() { System.out.println("NiceTune.play()"); }

Extensibilty III public static void main(String[] args) { CellPhone noiseMaker = new CellPhone(); SimpleInput keyboard = new SimpleInput(); System.out.println("Enter number of tunes:"); int numTunes = keyboard.nextInt(); Tune[] tunes = new Tune[numTunes]; for (int i = 0; i < numTunes; i++) { System.out.println("Enter tune type"); System.out.println("(Tune=1, ObnoxiousTune=2, NiceTune = 3)"); int tuneType = keyboard.nextInt(); switch(tuneType) { case 1: tunes[i] = new Tune(); break; case 2: tunes[i] = new ObnoxiousTune(); break; case 3: tunes[i] = new NiceTune(); break; default: tunes[i] = new Tune(); break; } for (int i = 0; i < tunes.length; i++) noiseMaker.ring(tunes[i]); }

Another Example: Arithmetic public class Node { public Node() {} public double eval() { System.out.println("Error: eval Node"); return 0; } public class Binop extends Node { protected Node lChild, rChild; public Binop(Node l, Node r) { lChild = l; rChild = r; }

Arithmetic (cont.) public class Plus extends Binop { public Plus(Node l, Node r) { super(l, r); } public double eval() { return lChild.eval() + rChild.eval(); } public class Const extends Node { private double value; public Const(double d) { value = d; } public double eval() { return value; } }

Arithmetic (cont.) public class TestArithmetic { // evaluate public static void main(String[] args) { Node n = new Plus( new Plus( new Const(1.1), new Const(2.2)), new Const(3.3)); System.out.println(n.eval()); }

Arithmetic (cont.) Binary operators create a binary tree. Binary operators create a binary tree. Constants are “leaf” nodes. Constants are “leaf” nodes. We could easily add more operators and terminals. We could easily add more operators and terminals

Extensibility Both the Tunes and Arithmetic programs allow additional subclasses to be constructed and easily integrated. Both the Tunes and Arithmetic programs allow additional subclasses to be constructed and easily integrated. Polymorphism is the key in letting this happen. Polymorphism is the key in letting this happen. It was OK to make Tune objects, but we should never make Node objects. It was OK to make Tune objects, but we should never make Node objects. How to prevent this? How to prevent this?

Abstract Classes As always, get the compiler involved in enforcing our decisions. As always, get the compiler involved in enforcing our decisions. Now it’s a compiler error if we try to make a Node object. Now it’s a compiler error if we try to make a Node object. Subclasses are abstract (and we must so state) until all abstract methods have been defined. Subclasses are abstract (and we must so state) until all abstract methods have been defined. public abstract class Node { public Node() {} public abstract double eval(); }

Order of Construction Put print statements into the constructors in the Arithmetic example. The output is: Put print statements into the constructors in the Arithmetic example. The output is: Node constructor Const constructor 1.1 Node constructor Const constructor 2.2 Node constructor Binop constructor Plus constructor Node constructor Const constructor 3.3 Node constructor Binop constructor Plus constructor Node n = new Plus( new Plus( new Const(1.1), new Const(2.2)), new Const(3.3));

Construction: Glyph Example abstract class Glyph { abstract void draw(); Glyph() { System.out.println(“Glyph() before draw”); draw(); System.out.println(“Glyph() after draw”); }

Glyph Example (cont.) class RoundGlyph extends Glyph { int radius = 1; RoundGlyph(int r) { radius = r; System.out.println(“RoundGlyph(), radius=“ + radius); } void draw() { System.out.println(“RoundGlyph.draw(), radius=“ + radius); } public class GlyphTest { public static void main(String[] args) { new RoundGlyph(5); }

Glyph Example (cont.) This produces This produces Guideline for constructors: Guideline for constructors: –“Do as little as possible to set the object into a good state, and if you can possibly avoid it, don’t call any methods.” Glyph() before draw() RoundGlyph.draw(), radius=0 Glyph() after draw() RoundGlyph(), radius= 5

Inheritance is Cool, But… Composition + Inheritance is Cooler abstract class Actor { abstract void act(); } class HappyActor extends Actor { public void act() { //…} } class SadActor extends Actor { public void act() { //…} } class Stage { Actor a = new HappyActor(); void change() { a = new SadActor(); } public class Transmogrify { public static void main(String[] args){ Stage s = new Stage(); s.go(); //happy actor s.change(); s.go() // sad actor }