Computer Science Canada

Rockin' the Object-Oriented Casbah?

Author:  wtd [ Sun Jun 11, 2006 11:40 am ]
Post subject:  Rockin' the Object-Oriented Casbah?

So, you've learned about object-oriented programming. You "get" it. You're pounding out classes like they're going out of style.

But are you as much of a guru as you think?

Do you understand the following?


  • Interface inheritance
  • Properties
  • Multiple (implementation) inheritance
  • Selective access control
  • Prototype-based objects
  • Object construction in a closure like manner
  • Multiple dispatch


If this doesn't sound familiar, then ask questions.

Author:  Clayton [ Sun Jun 11, 2006 1:56 pm ]
Post subject: 

what is multiple dispatch and prototype-based objects?

Author:  Cervantes [ Sun Jun 11, 2006 3:05 pm ]
Post subject: 

I'm all for getting a lecture in any language or languages you want on any or all of these topics. Smile

Author:  wtd [ Sun Jun 11, 2006 3:06 pm ]
Post subject: 

To demonstrate multiple dispatch, let me show you an example. First I'll write it in Java, and then in Common Lisp. Java has to simulate multiple dispatch with the Visitor Pattern. The Common Lisp Object System innately works based on multiple dispatch.

code:
interface Displayer {
   public void display(Book b);
   public void display(CD cd);
}

interface Displayable {
   public void display(Displayer d);
}

class Book implements Displayable {
   private String title, author;
   
   public Book(String title, String author) {
      this.title = title;
      this.author = author;
   }
   
   public String getCoverText() {
      return title + " by " + author;
   }
   
   public void display(Displayer d) {
      d.display(this);
   }
}

class CD implement Displayable {
   private String title, band;
   
   public Book(String title, String band) {
      this.title = title;
      this.band = band;
   }
   
   public String getAlbumASCII() {
      return band + "'s " + title;
   }
   
   public void display(Displayer d) {
      d.display(this);
   }
}

class ShelfDisplayer implements Displayer {
   public void display(Book b) {
      System.out.println(b.getCoverText());
   }
   
   public void display(CD cd) {
      System.out.println(cd.getAlbumASCII());
   }
}

public class Example {
   public static void main(String[] args) {
      Book b = new Book("Yada yada", "Foo bar");
      Displayer d = new ShelfDisplayer();
      b.display(d);
   }
}


And in CLOS:

code:
(defclass book ()
  ((title  :initarg  :title
           :accessor book-title)
   (author :initarg  :author
           :accessor book-author)))
           
(defclass compact-disc ()
  ((title  :initarg  :title
           :accessor cd-title)
   (band   :initarg  :band
           :accessor cd-band)))
         
(defgeneric display (obj stream))

(defmethod display ((b book) stream)
  (format stream "~A by ~A~%" (book-title b) (book-author b)))
 
(defmethod display ((c compact-disc) stream)
  (format stream "~A's ~A~%" (cd-band c) (cd-title c)))
 
(let ((b (make-instance 'book :title "Yada yada" :author "Foo bar")))
  (display b *standard-output*))

Author:  wtd [ Sun Jun 11, 2006 3:37 pm ]
Post subject: 

A slightly more complex example:

code:
interface Displayer {
   public void display(Book b);
   public void display(CD cd);
}

interface Displayable {
   public void display(Displayer d);
}

class Book implements Displayable {
   private String title, author;
   
   public Book(String title, String author) {
      this.title = title;
      this.author = author;
   }
   
   public String getCoverText() {
      return title + " by " + author;
   }
   
   public String getTitle()
   
   public void display(Displayer d) {
      d.display(this);
   }
}

class CD implement Displayable {
   private String title, band;
   
   public Book(String title, String band) {
      this.title = title;
      this.band = band;
   }
   
   public String getAlbumASCII() {
      return band + "'s " + title;
   }
   
   public void display(Displayer d) {
      d.display(this);
   }
}

class ShelfDisplayer implements Displayer {
   public void display(Book b) {
      System.out.println(b.getCoverText());
   }
   
   public void display(CD cd) {
      System.out.println(cd.getAlbumASCII());
   }
}

class InventoryDisplayer implements Displayer {
   private OutputStream output;
   
   public InventoryDisplayer(OutputStream output) {
      this.output = output;
   }

   public void display(Book b) {
      output.println("Title: " + b.title);
      output.println("Title: " + b.author);
   }
   
   public void display(CD cd) {
      output.println("No CDs!  You stupid meatball...");
   }
}

public class Example {
   public static void main(String[] args) {
      Book b = new Book("Yada yada", "Foo bar");
      Displayer d = new ShelfDisplayer();
      b.display(d);
   }
}




code:
(defclass book ()
  ((title  :initarg  :title
           :accessor book-title)
   (author :initarg  :author
           :accessor book-author)))
           
(defclass compact-disc ()
  ((title  :initarg  :title
           :accessor cd-title)
   (band   :initarg  :band
           :accessor cd-band)))
 
(defclass inventory ()
  ((log-stream :initarg :log-stream
               :initform *standard-output*
               :accessor inventory-log-stream)))

(defgeneric display (obj stream))

(defmethod display ((b book) stream)
  (format stream "~A by ~A~%" (book-title b) (book-author b)))
 
(defmethod display ((c compact-disc) stream)
  (format stream "~A's ~A~%" (cd-band c) (cd-title c)))

(defmethod display ((b book) (i inventory))
  (format (inventory-log-stream i) "Title: ~A~%By: ~A~%"
    (book-title b)
    (book-author b)))
 
(defmethod display ((c compact-disc) (i inventory))
  (format (inventory-log-stream i) "No CDs!  You stupid meatball...~%"))
 
(let ((b (make-instance 'book :title "Yada yada" :author "Foo bar")))
  (display b *standard-output*))

Author:  wtd [ Mon Jun 12, 2006 3:42 pm ]
Post subject: 

Now, as for Prototype based programming...

Let's start with a simple class and object in Python for the heck of it.

code:
class Ninja(object):
   def __init__(self, strength=100):
      self.strength = strength

my_ninja = Ninja(strength=200)


Pretty simple, right? In Python, object is the root of the inheritance hierarchy, so Ninja inherits from it. Ninja is now a subclass of object and inherits from it all of its functionality.

Then we instantiate Ninja to get a new Ninja object.

Let's create a subclass of Ninja.

code:
class EliteNinja(Ninja):
   def __init__(self, strength=200):
      Ninja.__init__(self, strength)
      self.has_sword = true


This also pretty simple. We've inherited from Ninja, so we call Ninja's init function on self to set up the strength, and then also add the "has_sword" variable.

So we have two fundamental things going on: we can subclass another class, and we can instantiate a class to create a new object.

What if we could take classes out of the picture and unify this into a single operation?

With prototype-based languages like Io, we can. Io has Object, which is the basic object. To create anything more specialized we simply clone Object and add things to it.

code:
Ninja := Object clone
Ninja strength := 100


Now here Object is considered a prototype of Ninja. If I send a message to Ninja that it does not understand, it will check to see if its prototypes do understand it. This permits "inheritance" in Io.

So, we've seen "subclassing" in Io, but what about creating a Ninja object? Well, Ninja is already an object, so...

code:
myNinja := Ninja clone
myNinja strength = 200


Smile

Author:  rizzix [ Mon Jun 12, 2006 8:15 pm ]
Post subject: 

Ah you should talk about prototype based mulitple dispatch. I don't know any prototype based language (not good enough anyway), but I believe it would be pretty neat.


: