1 / 43

Polymorphism

Polymorphism. Poly => many Morph => shape Variables take on many shapes, or many classes of objects. Polymorphism. Polymorphism in OOP is caused by late-binding of procedure calls (message lookup). Program can work with any object that has the right set of methods. Object Model for Payroll.

Télécharger la présentation

Polymorphism

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Polymorphism • Poly => many • Morph => shape • Variables take on many shapes, or many classes of objects.

  2. Polymorphism • Polymorphism in OOP is caused by late-binding of procedure calls (message lookup). • Program can work with any object that has the right set of methods.

  3. Object Model for Payroll abstract class EmployeeTransaction Employee PayrollSystem date postTo: post: abstract method Paycheck SalaryChange salary pay, taxes Timecard hoursWorked vacation

  4. Examples • post: aTransaction • aTransaction postTo: self. • transactations add: aTransaction • numbers inject: 0 into: [:sum :i | sum + i]

  5. The Case Against Case Statements • Smalltalk has no case statement. • OO programmers tend to avoid case statements, and to use message sending, instead.

  6. Eliminating Cases • exp • case: 1 do: [...]; • case: 15 do: [...]. • Make classes for 1 and 15, with a method called msg. • exp msg or (dictionary at: exp) msg

  7. Class UndefinedObject • Class UndefinedObject has one instance -- nil. • All variables are initialized to nil. • Also used to indicate illegal value.

  8. Don’t Test Classes • UndefinedObject Object • isNil isNil • ^ true ^ false • notNil notNil • ^ false ^ true • Don’t test classes: use message sending and inheritance.

  9. Choices • bad • x class = UndefinedObject ifTrue: [...] • OK • x = nil ifTrue: [...] • best • x isNil ifTrue: [...]

  10. Another choice • x ifNil: [ … ] • Object • ifNil: aBlock • ^self UndefinedObject ifNil: aBlock ^aBlock value

  11. Magnitude • Magnitude () • ArithmeticValue () • Number () • .... • Point ('x' 'y') • Character () • Date ('day' 'year') • Time ('hours' 'minutes' 'seconds')

  12. Number Hierarchy • Number • Fraction ('numerator' 'denominator') • Integer () • LargeNegativeInteger () • LargePositiveInteger () • SmallInteger () • ...

  13. Magnitude comment • The abstract class Magnitude provides common protocol for objects that have the ability to be compared along a linear dimension, such as dates or times. Subclasses of Magnitude include Date, ArithmeticValue, and Time, as well as Character and LookupKey.

  14. Magnitude comment • Subclasses must implement the following messages: • comparing • < • = • hash

  15. Numbers • Numbers are part of the class hierarchy, not built into compiler. • Numbers understand +, -, *, /, <, <=, etc. • 3 / 6 => 1 / 2 • 2 sqrt => 1.41421 • 3 + 4 * 2 =>

  16. ArithmeticObject • Points, Numbers, Complex (not in image) • squared • "Answer the receiver multiplied by itself." • ^self * self

  17. ArithmeticObject • = aNumber • "Answer whether the two objects are equal. For numeric objects, the two will be equal if the difference between them is zero" • ^aNumber respondsToArithmetic • ifTrue: [(self - aNumber) isZero] • ifFalse: [false]

  18. Number • Number is also a magnitude. • Adds truncation operations • FixedPoint, Fraction, Integer, Double, Float

  19. Number • // aNumber • "Integer quotient defined by division with truncation toward negative • infinity. 9//4 = 2, -9//4 = -3. -0.9//0.4 = -3. • \\ answers the remainder from this division." • ^(self / aNumber) floor

  20. Number • \\ aNumber • "modulo. Remainder defined in terms of //. Answer a Number with the same sign as aNumber. e.g. 9\\4 = 1, -9\\4 = 3, 9\\-4 = -3, 0.9\\0.4 = 0.1" • ^self - (self // aNumber * aNumber)

  21. For an Abstract Class ... • Look for "subclassResponsibility" methods to see the core methods. • Look in subclasses to see examples. • Flow of control goes up and down the class hierarchy. • (So don't try to follow it!) • Don't send "new" to the class.

  22. Uses of Inheritance • To be shared by all subclasses • • don't redefine • Default • • probably redefine

  23. Uses of Inheritance • Parameterized by subclasses (template method) • • rarely redefine • • change it by redefining the methods it calls • True abstract methods • • must redefine

  24. Uses of Polymorphism • Method lookup finds the method that is right for the receiver. • • method always knows the class of the receiver • • different classes lead to different methods

  25. Uses of Polymorphism • Methods often depend radically on class of receiver. • isNil • ifTrue:ifFalse: • double dispatching

  26. Double-dispatching: the Problem Fl Fr Fi M * Fl Fr Fi Sc Smallinteger Fl * Fl Fl Sc Float Fr Fl * Fi Sc Fraction Fi Fl Fi Sc * FixedPoint Sc Sc Sc Sc Matrix *

  27. Arithmetic • Number * Matrix • Multiply each element by number • Matrix * Number • Multiply each element by number • Matrix * Matrix • Standard matrix multiplication

  28. Arithmetic • Integer * Integer Primitive int operations • Integer * Float Convert int to float • Float * Integer Convert int to float • Float * Float Primitive float operation

  29. Double dispatching: the Solution • Primary method (+, *, etc) sends a second message to argument, encoding the class of the receiver. • Second message knows class of both its argument and its receiver.

  30. Primary operations • Send a second message, encoding the class of the original receiver in the name of the message. • + anArg • anArg sumFromInteger: self

  31. Double Dispatching Methods • Knows the class of receiver and argument. • sumFromInteger: anInteger • ^anInteger asFloat + self

  32. The first message dispatch • 37 + 8.9 • SmallInteger+ anArg • <primitive: 1> • ^ anArg sumFromInteger: self • 8.9 sumFromInteger: 37

  33. The second message dispatch • 8.9 addSmallInteger: 37 • FloataddSmallIngeter: anArg • ^ anArg asFloat + self • 8.9 + 37.0

  34. Finishing Up • 8.9 + 37.0 • Float+ anArg • <primitive: 41> • ^aNumber sumFromFloat: self

  35. Multiplication • Fraction has two instance variables, numerator and denominator. • * aNumber • "Result is a new Fraction unless the argument is a Float, in which case the result is a Float." • ^aNumber productFromFraction: self

  36. Fraction • productFromFraction: aFraction • ^(self species • numerator: aFraction numerator * numerator • denominator: aFraction denominator * denominator) reduced

  37. Integer • productFromFraction: aFraction • ^(aFraction species • numerator: aFraction numerator * self • denominator: aFraction denominator) reduced

  38. Float • productFromFraction: aFraction • ^aFraction asFloat * self

  39. Float • * aNumber • "Answer a Float that is the result of multiplying the receiver by the argument, aNumber. The primitive fails if it cannot coerce the argument to a Float" • <primitive: 49> • ^aNumber productFromFloat: self

  40. Fraction • productFromFloat: aFloat • ^aFloat * self asFloat

  41. Shared Responsibilities • Sometimes need to select a method based on class of several objects: • Displaying object -- depends on both the kind of object and the windowing system • Arithmetic -- depends on the types of both arguments

  42. Double dispatching • Three kinds of mesages • • primary operations • • double dispatching methods • • forwarding operations • Implement inheriting from superclass of argument • Implement commutativity

  43. Cost of Double Dispatching • Adding a new class requires adding a message to each of the other classes. • Worst case is N*N methods for N classes. • However, total lines of code is not much larger.

More Related