6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology 6.001 Notes: Section 14.1 Slide 14.1.1 Elements of ooP Last time we introduced the idea of object oriented systems Today, we want to build on those basics, looking at how we can expand object-oriented systems to deal with hierarchies of objects, to leverage the commonality of methods between different kinds of objects. We are going to see how the same ideas of abstraction allow us to control complexity in object oriented systems, much as they did in procedural systems. We are also going to show a version of a Scheme based object- oriented system. Note that this is not an optimal implementation of an object-oriented system compared to say Java or C++, but the goal is to show how one could create and manipulate an object-oriented system using the tools we have already developed. Our intent is to separate these issues; highlighting the concepts of object-oriented systems, while grounding those concepts in a specific instantiate Elements of ooP lide14.1.2 To start, let me remind you of what we have already seen. we hart data structure are trying to large system around a collection of objects. An object can be thought of as a"smart"data structure; Set of methods for manipulating state variables a set of state variables that describe the object; and an associated set of methods for manipulating those state variables. We expect Specifies the common behavior of entities our systems to have many different versions of the same kind of Instance object. For instance, think of bank system in which we might A particular object or entity of a given class have many different accounts. Each account would have a set of data values: current balance, overdraft protection, pending deposits. Thus there is the notion of an account as an abstract structure, and there is notion of different, specific versions of this abstract structure. Thus, we make a distinction. a class will define the common behavior of a kind of object in our ystem, the collection of things that are going to behave in the manner defined by those commonalities. Instances capture the specific details of an individual version of that class Our goal is to see how to structure computation within this new paradigm, in which the central units are"smart data structures. Thus, when we design a system we will tend to focus on the classes, as those are the basic building blocks of our system. The"programming of these systems will tend to focus on the interactions and behaviors of the classes: how should changes in one instance of an object affect other aspects of that object or other objects in the system? When we want to actually run our system, say to simulate a behavior, we will use the classes to create the instances that are particular versions of things, and then see how those specific instances interact
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. 6.001 Notes: Section 14.1 Slide 14.1.1 Last time we introduced the idea of object oriented systems. Today, we want to build on those basics, looking at how we can expand object-oriented systems to deal with hierarchies of objects, to leverage the commonality of methods between different kinds of objects. We are going to see how the same ideas of abstraction allow us to control complexity in objectoriented systems, much as they did in procedural systems. We are also going to show a version of a Scheme based objectoriented system. Note that this is not an optimal implementation of an object-oriented system compared to say Java or C++, but the goal is to show how one could create and manipulate an object-oriented system using the tools we have already developed. Our intent is to separate these issues; highlighting the concepts of object-oriented systems, while grounding those concepts in a specific instantiation in Scheme. Slide 14.1.2 To start, let me remind you of what we have already seen. We are trying to organize a large system around a collection of objects. An object can be thought of as a “smart” data structure; a set of state variables that describe the object; and an associated set of methods for manipulating those state variables. We expect our systems to have many different versions of the same kind of object. For instance, think of bank system in which we might have many different accounts. Each account would have a set of data values: current balance, overdraft protection, pending deposits. Thus there is the notion of an account as an abstract structure, and there is notion of different, specific versions of this abstract structure. Thus, we make a distinction. A class will define the common behavior of a kind of object in our system, the collection of things that are going to behave in the manner defined by those commonalities. Instances capture the specific details of an individual version of that class. Our goal is to see how to structure computation within this new paradigm, in which the central units are “smart” data structures. Thus, when we design a system we will tend to focus on the classes, as those are the basic building blocks of our system. The “programming” of these systems will tend to focus on the interactions and behaviors of the classes: how should changes in one instance of an object affect other aspects of that object or other objects in the system? When we want to actually run our system, say to simulate a behavior, we will use the classes to create the instances that are particular versions of things, and then see how those specific instances interact
6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology Slide 14.1.3 Recall from last time the example we used to demonstrate object- Space War Class Diagram oriented systems. That example was a system for simulating a simple"star wars"scenario. In that system, we had class ch as those shown here. We had a class for ships TORPEDO class for planets, a class for torpedoes, and some other classes that we have not shown here. recall that for each class. we had two sets of things internal state variables which characterized CLOCK-TICK the state of each instance of the class and a set of methods the things that the class able of doing. Those me were characterized by the instance accepting a message of the same name, then performing some interaction between different 4 objects within the system or changing the status of the internal state variables of an instance Space War Class Diagram Slide 14.1. 4 In order to make a point, I have changed slightly my definition of a torpedo. Last time a torpedo just used a position and a elocity, and it moved until it hit some thing, at which point it ANET exploded. A smarter torpedo might explicitly seek some target. and use a state variable like a proximity fuse, so that when the CLOck-Ic torpedo got close enough to its target it would explode One reason for introducing this is to notice that state variables within our instances could actually point to other instances. So the state variable for a target would point to another class, a ship n this case Slide 14.1.5 Space War class Diagram However, the real point we want to draw attention to in this diagram is the commonality, particularly the commonality fly, they both therefore have state information about positian between ships and torpedoes. Note that both of these objects can ORPEDO velocity, they both have methods that deal with position anand elocity; thus they have a lot of things in common, as well as CK-TICK having a few distinctive properties We know that a common theme in this course is capturing common patterns and abstracting them. so the issue here is Ships and torpedoes have some behavior that is the same whether we can do the same thing in an object-oriented system is there are way to capture this commonality? Can we take advantage of the fact that torpedoes and ships share a lot in common, and use that to build more modular systems?
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. Slide 14.1.3 Recall from last time the example we used to demonstrate objectoriented systems. That example was a system for simulating a simple "star wars" scenario. In that system, we had class diagrams such as those shown here. We had a class for ships, a class for planets, a class for torpedoes, and some other classes that we have not shown here. Recall that for each class, we had two sets of things: internal state variables, which characterized the state of each instance of the class, and a set of methods, the things that the class was capable of doing. Those methods often were characterized by the instance accepting a message of the same name, then performing some interaction between different objects within the system or changing the status of the internal state variables of an instance. Slide 14.1.4 In order to make a point, I have changed slightly my definition of a torpedo. Last time a torpedo just used a position and a velocity, and it moved until it hit some thing, at which point it exploded. A smarter torpedo might explicitly seek some target, and use a state variable like a proximity fuse, so that when the torpedo got close enough to its target it would explode. One reason for introducing this is to notice that state variables within our instances could actually point to other instances. So the state variable for a target would point to another class, a ship in this case. Slide 14.1.5 However, the real point we want to draw attention to in this diagram is the commonality, particularly the commonality between ships and torpedoes. Note that both of these objects can fly, they both therefore have state information about position and velocity, they both have methods that deal with position and velocity; thus they have a lot of things in common, as well as having a few distinctive properties. We know that a common theme in this course is capturing common patterns and abstracting them. So the issue here is whether we can do the same thing in an object-oriented system. Can we take advantage of the fact that torpedoes and ships share a lot in common, and use that to build more modular systems?
6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology Slide 14.1.6 Space War Class Diagram with Inheritance Conceptually we should be able to do this. Without worrying IMOBILE-THING about implementation details, let's first pull out that common pattern in our class diagram. Here is an abstraction of that common pattern, a new class called a mobile-thing. It has two state variables, position and velocity, and it has some common methods for dealing with those variables. These variables and methods will hold for any mobile object. We will, of course, clude a type tag for this new kind of class, as well. And th thus defi Slide 14.1.7 Space War class Diagram with Inheritance Given that new class, we can now create specializations. We can MOBILE-THING create a subclass. a torpedo is a particular kind of mobile thing It has all the properties of mobile things, but it also has characteristics that are particular to torpedoes. Similarly, a ship is a kind of mobile thing; it's a specialization that has, in addition to the properties of mobile things, other characteristics that matter only to ships Space War Class Diagram with Inheritance Slide 14.1.8 SHiP class is a specialization or As we start designing our system, we can begin to put together sub-class of the MOBILE -THING class hierarchies of class diagrams. We have base classes like mobile SHIP inherits the state an things. We also have some specializations or subclasses so that VELOCE havior of MOBILE-THING for example a ship is a mobile thing and should therefore inherit t he 5HTP and o PE o casses the state and behavior of a mobile thing, as well as having its own properties. In the other direction, we say that the mobile thing class is a super-class of the ship and torpedo classes Now we can start building a broader set of designs in which we have hierarchies of information captured in different I specializations of different classes of objects Slide 14. 1.9 Space War Class Diagram with Inheritance And as we fill out our class diagram we will have different IMOBILE-THING relationships between the classes. Torpedoes, for example, can sub-class sa special have a class as a link: targets are always going to be elements of SHIP inherits the state and the ship class behavior of MOBILE-THING Note that one of the advantages of creating super-classes is that we can nicely isolate the code for the methods of the super classes so that if we want to change one of those methods, we TORPEDO only need to worry about the implementation of the super-class, proxim ATTACK not about all of the specializations. If for example we decide to CLOCK-TICK change how things move, we don't have to search for all the move methods in the different subclasses, we need only change the method in the super-class This gives us a nice
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. Slide 14.1.6 Conceptually we should be able to do this. Without worrying about implementation details, let's first pull out that common pattern in our class diagram. Here is an abstraction of that common pattern, a new class called a mobile-thing. It has two state variables, position and velocity, and it has some common methods for dealing with those variables. These variables and methods will hold for any mobile object. We will, of course, include a type tag for this new kind of class, as well. And this thus defines a new class. Slide 14.1.7 Given that new class, we can now create specializations. We can create a subclass. A torpedo is a particular kind of mobile thing. It has all the properties of mobile things, but it also has characteristics that are particular to torpedoes. Similarly, a ship is a kind of mobile thing; it's a specialization that has, in addition to the properties of mobile things, other characteristics that matter only to ships. Slide 14.1.8 As we start designing our system, we can begin to put together hierarchies of class diagrams. We have base classes like mobile things. We also have some specializations or subclasses so that for example a ship is a mobile thing and should therefore inherit the state and behavior of a mobile thing, as well as having its own properties. In the other direction, we say that the mobile thing class is a super-class of the ship and torpedo classes. Now we can start building a broader set of designs, in which we have hierarchies of information captured in different specializations of different classes of objects. Slide 14.1.9 And as we fill out our class diagram, we will have different relationships between the classes. Torpedoes, for example, can have a class as a link: targets are always going to be elements of the ship class. Note that one of the advantages of creating super-classes is that we can nicely isolate the code for the methods of the superclasses so that if we want to change one of those methods, we only need to worry about the implementation of the super-class, not about all of the specializations. If for example we decide to change how things move, we don't have to search for all the move methods in the different subclasses, we need only change the method in the super-class. This gives us a nice
6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology modularization of the system, by isolating the common methods in a single place, for easy maintenance and change 6.001 Notes: Section 14.2 Slide 14.2.1 How to design interactions between objects o our first goal is to examine the paradigm of constructing Focus on classes objects ystems around objects, and for now we are going to ignore the Relationships between classe issue of how to describe these object systems in Scheme, we will f interactions tha instead initially focus on the abstract use of object-based instances of classes systems. Thus, we will primarily consider the classes of objects For now, assume the following interface to an object we might want in a system, and the range of interactions that we lask <object> <method> <arguments>) will need to support between objects. For now, we will simply assume that given an instance of a class, that is an object, we can send that object a message using the form (ask <object> <method> <arguments In other words we can use some Scheme interface(which we will define later)based on the ask procedure, which takes as arguments an object, a name of a method (something we want the object to do), and some set of arguments that specify details of the method, and ask will cause the object to execute the specified method. We will return to details of this shortly An initial class hierarchy lide14.2.2 We start with a class for people, which we call the person class Each instance of a person has two class variables, holding the persons first and last name. Each instance also has two methods. The say method causes the person to say something WHOAREYOU? (ask persom-1 HOAREYoUP) The whoareyou? method causes the person to indicate their first The class diagram for this class is shown in the slide. As well we will assume some constructor for making instances of the class(we will get to details of this shortly), and we can see how asking an instance of this class to say something or to identify au themselves causes actions in the system
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. modularization of the system, by isolating the common methods in a single place, for easy maintenance and change. 6.001 Notes: Section 14.2 Slide 14.2.1 So our first goal is to examine the paradigm of constructing systems around objects, and for now we are going to ignore the issue of how to describe these object systems in Scheme; we will instead initially focus on the abstract use of object-based systems. Thus, we will primarily consider the classes of objects we might want in a system, and the range of interactions that we will need to support between objects. For now, we will simply assume that given an instance of a class, that is an object, we can send that object a message using the form (ask <object> <method> <arguments>). In other words, we can use some Scheme interface (which we will define later) based on the ask procedure, which takes as arguments an object, a name of a method (something we want the object to do), and some set of arguments that specify details of the method, and ask will cause the object to execute the specified method. We will return to details of this shortly. Slide 14.2.2 We start with a class for people, which we call the person class. Each instance of a person has two class variables, holding the person’s first and last name. Each instance also has two methods. The say method causes the person to say something. The whoareyou? method causes the person to indicate their first name. The class diagram for this class is shown in the slide. As well, we will assume some constructor for making instances of the class (we will get to details of this shortly), and we can see how asking an instance of this class to say something or to identify themselves causes actions in the system
6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology Slide 14.2.3 Now we add a sub-class of person, called a professor. An initial class hierarchy Note that this class does not have any specific internal class variables. However, because it is a subclass of a person, it z-1'say '(helle there) should inherit the class variables of its superclass. In other words, professors also have a first and last name, because their person superclass instance has such variables. And professors PROFESSOR have the ability to say things by virtue of being a subclass of LECTURE person. Note that we again assume there is some constructor for making instances of a class(which should will see. take care of creating superclass instances as part of the process). Because of this hierarchy of classes, we should be able to ask the professor to say something, and it will use its inherited method from the person instance to do this An initial class hierarchy Slide 14.2, 4 PERSON (ask professor-1'WHOAREYOU?) In our little world, professors have no class variables of their own(ah, the irony!) but they do have two methods,a whoareyou? method and a lecture method. Notice that a WHOAREYOU? professor has its own whoareyou? method, distinct from the identically named method in person. If we ask a professor whoareyou? it will run its own method to answer the question, LECTURE with a different behavior. when a subclass has a method of the same name as a superclass, the subclass method is said to shadow the inherited method in the superclass instance Slide 14. 2.5 An initial class hierarchy Now in the world we are creating, it is traditional that when a professor lectures he starts every sentence with" Therefore e professor Snith An interesting question to consider when actually implementing the professor class is whether this lecture method is a distinct sk professor -1 LECTURE(the sky is method, or whether it shares structure with the underlying say +Therefore, the sky is blue method of the inherited person class. Conceptually, we would like to think that lecturing is a particular variant on saying Royd」 professor should"delegate"part indeed one simply says the word"Therefore"and then says the of the lecture method to a persons emaining text. This idea of using a superclass method to accomplish part of a method is called" delegation Note that this is an important requirement to place on an object system. The idea is that at a conceptual level, just as classes can be related to one another(e.g. via the subclass hierarchy ), so too can methods be related to one another, by this delegation idea. And at the implementation level, delegation can be seen as a mechanism that allows subclasses to specialize(and use )methods found in superclasses This has two important consequences. The first is that if we design our object system correctly, we will have a clean modularity of code, so that there is only one place to implement saying some thing, and thus only one place to worry about if we decide to change the manner in which this method executes. Secondly, we have an explicit indication (through the act of delegation that the lecture method and the say method are related conceptually. We will return to this point when we consider an explicit implementation of an object-oriented system in Scheme
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. Slide 14.2.3 Now we add a sub-class of person, called a professor. Note that this class does not have any specific internal class variables. However, because it is a subclass of a person, it should inherit the class variables of its superclass. In other words, professors also have a first and last name, because their person superclass instance has such variables. And professors have the ability to say things by virtue of being a subclass of person. Note that we again assume there is some constructor for making instances of a class (which should, as we will see, take care of creating superclass instances as part of the process). Because of this hierarchy of classes, we should be able to ask the professor to say something, and it will use its inherited method from the person instance to do this. Slide 14.2.4 In our little world, professors have no class variables of their own (ah, the irony!) but they do have two methods, a whoareyou? method and a lecture method. Notice that a professor has its own whoareyou? method, distinct from the identically named method in person. If we ask a professor whoareyou? it will run its own method to answer the question, with a different behavior. When a subclass has a method of the same name as a superclass, the subclass method is said to shadow the inherited method in the superclass instance. Slide 14.2.5 Now in the world we are creating, it is traditional that when a professor lectures he starts every sentence with “Therefore”. An interesting question to consider when actually implementing the professor class is whether this lecture method is a distinct method, or whether it shares structure with the underlying say method of the inherited person class. Conceptually, we would like to think that lecturing is a particular variant on saying: indeed one simply says the word “Therefore” and then says the remaining text. This idea of using a superclass’ method to accomplish part of a method is called “delegation”. Note that this is an important requirement to place on an object system. The idea is that at a conceptual level, just as classes can be related to one another (e.g. via the subclass hierarchy), so too can methods be related to one another, by this delegation idea. And at the implementation level, delegation can be seen as a mechanism that allows subclasses to specialize (and use) methods found in superclasses. This has two important consequences. The first is that if we design our object system correctly, we will have a clean modularity of code, so that there is only one place to implement saying some thing, and thus only one place to worry about if we decide to change the manner in which this method executes. Secondly, we have an explicit indication (through the act of delegation) that the lecture method and the say method are related conceptually. We will return to this point when we consider an explicit implementation of an object-oriented system in Scheme