Double Dispatch

1,143 views

Published on

Published in: Education, Business, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,143
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Double Dispatch

  1. 1. Stéphane Ducasse 1 Stéphane Ducasse stephane.ducasse@inria.fr http://stephane.ducasse.free.fr/ Double Dispatch?
  2. 2. S.Ducasse 2 How to invoke a method Depending on **both** the receiver and an argument… Type check are evil Overloading is plain bad Remember Java lookup? Use Double Dispatch
  3. 3. S.Ducasse 3 Type Checking for Dispatching How to invoke a method depending on the receiver and an argument? A not so good solution: PSPrinter>>print: aDocument ^ aDocument isPS ifTrue: [self printFromPS: aDocument] ifFalse: [self printFromPS: aDocument asPS] PSPrinter>>printFormPS: aPSDoc <primitive> PdfPrinter>>print: aDocument ^ aDocument isPS ifTrue: [self printFromPDF: aDocument asPDF] ifFalse: [self printFromPDF: aDocument] PdfPrinter>>printFormPS: aPdfDoc <primitive> 3
  4. 4. S.Ducasse 4 Drawbacks ofTypecheck • Adding new kinds of documents requires changes everywhere • Adding new documents requires changes everywhere • No dynamic (without recompilation) possibilities
  5. 5. S.Ducasse 5 Double Dispatch Solution: use the information given by the single dispatch and redispatch with the argument (send a message back to the argument passing the receiver as an argument)
  6. 6. S.Ducasse 6 Double Dispatch (a) PSPrinter>>print: aDoc aDoc printOnPSPrinter: self (b) PdfPrinter>>print: aDoc aDoc printOnPdfPrinter: self (c) PSDoc>>printOnPSPrinter: aPSPrinter <primitive> (d) PdfDoc>>printOnPdfPrinter: aPSPrinter aPSprinter print: self asPS (e) PSDoc>>printOnPSPrinter: aPdfPrinter aPdfPrinter print: self asPdf (f) PdfDoc>>printOnPdfPrinter:aPdfPrinter <primitive> SomeTests: psprinter print: psdoc =>(a->c) pdfprinter print: pdfdoc => (b->f) psprinter print: pdfdoc => (a->d->b->f) pdfprinter print: psdoc => (b->e->b->f)
  7. 7. S.Ducasse 7 Let’s Step Back Example: Coercion between Float and Integer Not a really good solution: Integer>>+ aNumber (aNumber isKindOf: Float) ifTrue: [ aNumber asFloat + self] ifFalse: [ self intAddPrimitive: aNumber] Float>>+ aNumber (aNumber isKindOf: Integer) ifTrue: [aNumber asFloat + self] ifFalse: [self floatAddPrimitive: aNumber] Here receiver and argument are the same, we can
  8. 8. S.Ducasse 8 Double Dispatch on Numbers (a) Integer>>+ aNumber ^ aNumber sumFromInteger: self (b) Float>>+ aNumber ^ aNumber sumFromFloat: self (c) Integer>>sumFromInteger: anInteger <primitive: 40> (d) Float>>sumFromInteger: anInteger ^ anInteger asFloat + self (e) Integer>>sumFromFloat: aFloat ^aFloat + self asFloat (f) Float>>sumFromFloat: aFloat <primitive: 41> Some Tests: 1 + 1: (a->c) 1 + 2.0 1.0 + 1.0: (b->f) 1 + 1.0: (a->d->b->f) 1.0 + 1: (b->e->b->f
  9. 9. S.Ducasse 9 Double Dispatching • Three Kinds of Messages – Primary operations – Double dispatching methods – Forwarding operations
  10. 10. S.Ducasse 9 Double Dispatching • Three Kinds of Messages – Primary operations – Double dispatching methods – Forwarding operations

×