CS212 Lecture 4/2/98 by Melissa Ho ---------------------------------------------------------------- Object-Oriented Programming: * A technique for organizing large systems, for example - Window system - Simulation (we will do a game with interacting autonomous agents) IDEA: * Decompose your problem into OBJECTS and OPERATIONS on them. (note we did this also with generic operations, but now the objects have local state, and more...) * Have a CLASS HIERARCHY which specifies the relation between types. > CLASS = a kind of object (similar to a type) "Animal", "Bird", "Dinosaur", like that. > INHERITANCE - inherit state and operations > "A duck is a kind of bird" * DINOSAUR = subclass = more specific kind of thing * ANIMAL = superclass = more general kind of thing. > Subclasses may have more or different operations: * ANIMALs might or might not be cold-blooded * DINOSAURs are cold blooded (at least acording to some theories! To heck with Jurassic Park) <thing> | | <animal> | | <dinosaur> MANTRA: An object of a subclass can be used ANYWHERE that an object of a superclass can be used. * A program which can manipulate groups of animals can therefore also manipulate flocks of dinosaurs. ---------------------------------------------------------------- There are two metaphors of OO programming: * Message Passing - send message to the object "Fly south for the winter!" (send big-bird 'fly 'south) * Generic Functions - Functions that handle different types of objects. (fly big-bird 'south) There's still debate on which is "better" We use GENERIC FUNCTIONS because they fit Dylan better, and they support "multimethods", which are useful. ---------------------------------------------------------------------- Some Terminology: CLASS = kind of thing "Dinosaur" INSTANCE = An individual object (entity) of some class. "Dino", "Barney" METHOD = Code that operates on specific classes. A function. "how dinosaurs sing" [Note: the question *why* dinosaurs might sing is reserved for philosophers] You should all be familiar with classes already. To review (define-class <animate> (<object>) (weight type: <number> init-keyword: size: init-value: 10) (hunger type: <number> init-keyword: hunger: init-value: 0)) (define-class <dog> (<animate>) (name type: <symbol> init-keyword: name:)) (define (bismark <dog>) (make <dog> name: 'bismark)) For example, (name bismark) ==> bismark (weight bismark) ==> 10 [why?] We can use set! to change the value of a slot in an instance (set! (weight bismark) 20) ---------------------------------------------------------------------- OPERATIONS: * GENERIC OPERATIONS using generic functions, as we covered earlier in the semester. Collection of functions, or "methods" that together implement some operation * each function is a type-specific "method" that handles specific class(es), given by its parameter list (define-generic-function eat (me food)) (add-method eat (method ((me <animate>) (food <symbol>)) (cond ((member? food '(salad fruit tofu)) (set! (hunger me) (- (hunger me) 1))) ;; CS212 is not a class in nutrition ((member? food '(donut chips)) (set! (hunger me) (- (hunger me) 2)))))) (add-method eat (method ((me <dog>) (food <symbol>)) (bind (((last-hunger <number>) (hunger me))) (next-method me food) (cond ((>= (hunger me) last-hunger) (print (name me)) (print " is hungry. Feed me something good.")))))) Note: the second function here has the access to the instance variables of <dog> (NAME) and of its superclass <animate> (HUNGER in this case). Why? Because of the type of the parameter. Cant generally assume that something of type <animate> has the slots of a <dog>. >> Leave it on board. * This generic function has two methods, one that operates on instance of class <animate>, and one that operates on instances of class <dog>. Now, we can do: (eat bismark 'dry-bone) The generic function eat uses the class hierarchy to find the most specific method that applies There is a method for instances of class <dog>, and bismark is an instance of that class, so that method is applied. (This is the same mechanism that we saw for generic function operating on values in general). If there had been no method for <dog>, we'd try <animate>, which is the direct superclass (and so on up the hierarchy) NOTE: * The most specific method is used * The other ones are generally ignored (except when explicitly invoked, using next-method). So, the second function gets invoked because <dog> is more specific than animate with respect to the given argument, bismark (which is of class <dog>). This function binds a local variable and then calls the function next-method --- which is a special function that means "run whatever method would have run if the method currently running had not been part of the generic function". In this case, that means call the function with parameter of type <animate> (as <animate> is the closest superclass of <dog>). This function checks whether dry-bone relieves hunger, it does not, so it just returns. Then the method for class <dog> continues running (the next-method has returned), and as the hunger value has not decreased, prints out: bismark is hungry. feed me something good. We will cover next-method more in the next few lectures, so if it does not make total sense at the moment, don't worry. At least this simple example should make sense. Thus, note that with classes and methods we can either replace functionality (a <dog> method that is special and does something totally different than the <animate> method) or we can do something slightly different (using next-method to do what would have happened, before or after doing something else). ---------------------------------------------------------------------- OOP and Generic Operations OOP is a technique for organizing "large" systems. (Note: this makes it hard for us to get across in lecture many of the advantages -- we can look at the techniques here, but much of the real learning will come in the problem set which is a large system.) Builds on the notion of generic operations that we covered earlier in the semester. Conceptually a table of procedures, indexed by operations and data types. In Dylan we use a generic functions style of type dispatching. The NEW IDEAS in OOP (beyond generic functions) are: 1) objects have local state variables (called slots), which are only accessible in certain contexts -- based on the type of the parameter/variable that names an object 2) types of objects (classes) are arranged in a hierarchy, from which they inherit their "behavior" (their slots and functions). A key principle in OOP is that a subclass should build on and modify the behavior of its superclass(es). Thus the central design issue in an OOP style of programming is to come up with a hierarchy of classes such that the objects of each class can build on the behavior of their superclasses (the idea is to have an effective way of SHARING code between objects of different classes). ------------------------------------------------------------------- Another example, (define-class <vehicle> (<object>) (location <symbol> init-value: 'here) (speed <number> 0)) (define-class <car> (<vehicle>) (fuel <number> init-value: 0)) (define-class <rocket> (<vehicle>) (fuel <number> init-value: 0) (altitude <number> init-value: 0)) (define-class <bicycle> (<vehicle>)) Note: single inheritance, so class hierarchy is a tree <object> | | <vehicle> | | |------------------- | | | <car> <rocket> <bicycle> (define-generic-function accelerate (v a)) ;; A1 <vehicle> (add-method accelerate (method ((v <vehicle>) (a <number>)) ;; Could also use: (set! (speed v) (+ (speed v) a)) (speed-setter v (+ (speed v) a)))) ;; A2 <rocket> (add-method accelerate (method ((r <rocket>) (a <number>)) (cond ((> (fuel r) 0) (print "Whoosh...") (next-method r a)) (else: (print "You lose. No gas."))))) ;; A3 <bicycle> (add-method accelerate (method ((b <bicycle>) (a <number>)) (print "Dream on."))) Some things to note about this generic function o A method can access only those slots of a class and its superclasses. For instance, the first method (A1) can access the speed slot, of <vehicle>, as can the second method (A2). But the first method cannot access the fuel slot of <rocket>. This is because <vehicle> is a superclass of <rocket>. o The second function uses next-method -- which is valid because there is a next function (the one for <vehicle>). The "next" function is defined solely by the class hierarchy. ------------------- Now we can create some instances of objects of these classes, and call accelerate. (define schwinn (make <bicycle>)) (define saturn-v (make <rocket> fuel: 10 altitude: 100000)) (define chevy (make <car> fuel: 10 location: 'there)) Each instance has all of the slots of the given class and its superclasses. Thus, schwinn has slots: location= here, speed=0 saturn-v has slots: location=here, speed=0,fuel=10,altitude=100000 chevy has slots: location=there, speed=0, fuel=10 [Note: this question is the prelim 2 equivalent of "what is the value of this expression".] If we evaluate (accelerate chevy 10) The most specific applicable function of the generic is the one for <vehicle> (because there is no method for class <car>, and the next most specific class is <vehicle> for which there is a method). This function increments the speed slot by 10. If we evaluate (accelerate schwinn 10) The most specific method is the one for <bicycle> which simply prints out the string "Dream on" If we evaluate (accelerate saturn-v 10) The most specific method is the one for <rocket> which checks if the fuel level is > 0 (which it is for this instance) and if so print "Whoosh" and then calls next-method. Recall, next-method means re-invoke the generic (in this case accelerate) with the specified arguments, but as if the currently running function were *not* part of the generic function(that is run the next most specific function; the one that would have run if the current function had not been part of the generic function). ----------------------------------------------------------------- The above example illustrates three different means of using generic functions and the class hierarchy to extend or modify the behavior of superclasses. o A class can simply inherit the behavior of its superclass (e.g., above an instance of class <car> simply inherits the behavior of a <vehicle>) o A class can replace the behavior of its superclass, by defining a class-specific method. This is sometimes called shadowing the behavior of the superclass (e.g., above an instance of class <bicycle> has a completely different behavior than the superclass <vehicle>) o A class can modify the behavior of its superclass, by defining a class-specific method that uses next-method (e.g., above an instance of class <rocket> has a behavior that modifies that of a general <vehicle>). There are 3 common patterns of such modified behavior: a BEFORE method does some computation and then a next-method call an AFTER method does a next-method call and then some computation an AROUND method does computation, next-method, more computation ------------------------------------------------------------------- Summary: * Object Oriented Programming - Organizing large systems - Operations / Generic Functions - Objects / Classes -- with local state variables (SLOTS) - Inheritance Hierarchy CLASS (similar to a type declaration) - list of slots, each is (type name init-value) - initialization function, called with the new instance - superclasses (if any) INSTANCE: - Created by MAKE - Each one has some local data, stored in SLOTS - In addition to its own slots of given class it has all of the slots of all its superclasses. Methods are type-specific operations (functions) which generic functions call - The generic function 'fly' might have methods for <bird> and <airplane> and <penguin> next-method gives ability to build on/modify behavior of superclasses. ------------------------------------------------------------- CS Joke of the day: [Xerox PARC (Palo Alto Research Center) is the research arm of Xerox Corp, where they invented the pesonal computer, the graphical user interface, the local area network, and the copying machine. ] Q: What's the difference between Jurassic Park and Xerox PARC? A: One's a high-tech theme park for dinosaurs. The other's a movie by Steven Speilberg.