Download presentation
Presentation is loading. Please wait.
Published byFrancisco Kneebone Modified over 9 years ago
1
three types, subtypes, and inheritance
2
The story up until now Everything in your computer is data Including programs Data is divided into objects Objects can be “inside” of other objects Boxes inside groups Colors inside bitmaps Objects have types Procedures Numbers (1, -3.5) Strings (“this is a string”, “blue”) Bitmaps Picture objects (lines, groups, boxes, etc.)
3
Number Value: 10 Looking inside data objects Data objects are like forms They have fields (aka members) Filled in by values The fields Have names (Width, Height) The fields are filled in by other data objects The object’s type (Box, Color) determines what fields it has Box Width: 10 Height: 10 Ellipse Width: 15 Height: 10 Procedure Name: iterated-group Arguments: proc count Body: [apply group [up-to count proc]] Color R: 240 G: 220 B: 0
4
Object types and type objects [type-of object] Asks an object what its type is The answer is a piece of data So it’s an object A type object [is? object type] Asks if object is of type type Answer is a Boolean (true or false) Meta has a bunch of types already named Number (any number) Integer (integers) Float (floating-point numbers) Boolean Color Bitmap List Type By convention type names are captialized
5
Defining new data types [class-type [name fields …] Object] Creates a new data type Called name With fields fields … We’ll explain the Object part later Returns an object representing that type So you then need to defining it to have a name Yes, I know you’ve already given it a name, but trust me [define Note [class-type [Note pitch duration volume] Object]] Says: Make a new type Note, objects of which contain within them: A pitch to play A duration for which to play it And a volume at which to play it
6
Creating new data objects [new type arguments …] Creates a new object of the specified type The arguments depend on the type For types created using class-type, they’ll be the values of the object’s fields, in order ► [define Note [class-type [Note pitch duration volume ] Object]] ► [define note [new Note 60 1 1]] ► note.pitch 60 ► note.duration 1 ► [note.duration ← 2] ► note.duration 2
7
Creating new data objects [new type arguments …] Creates a new object of the specified type The arguments depend on the type For types created using class-type, they’ll be the values of the object’s fields, in order [define my-chord [list [new Note 60 1 1] [new Note 64 1 1] [new Note 67 1 1]] Or to show off: [define my-chord [map [pitch → [new Note pitch 1 1]] [list 60 64 67]]]
8
Types and subtypes Types often have subtypes Integers are a subtype of numbers Boxes are a subtype of Pictures All types are subtypes of the magic type Object Subtyping means objects can have many types All Integers are also Numbers All Boxes are also Pictures And all objects are Objects Object List Picture Number Integer Float Array BoxLineGroup
9
Defining new data types [class-type [name fields …] parent-type] The parent-type field specifies what the new type is a subtype of In the past, we’ve just make this object But you can use any of the types you define [define Picture [class-type [Picture] Object]] [define Box [class-type [Box width height] Picture]] [define Line [class-type [Line start end] Picture]] [define Group [class-type [Group objects] Picture]]
10
Class-based inheritance (Danger Will Robinson! This slide lies!) Types automatically “inherit” the fields of their parent types “Class” is effectively a synonym for type that means “type with inheritance” In this example Pictures have no fields Groups have one field (objects) TranslatedGroups have two (objects and point) RotatedGroup also have two (objects and angle) Etc. [define Picture [class-type [Picture] Object]] … [define Group [class-type [Group objects] Picture]] [define TranslatedGroup [class-type [TranslatedGroup point] Group]] [define RotatedGroup [class-type [RotatedGroup angle] Group]] [define InkedGroup [class-type [InkedGroup pen] Group]] [define PaintedGroup [class-type [PaintedGroup color] Group]]
11
Class hierarchy (partial) Object No fields Picture No fields Box width, height Group objects Line start, end TranslatedGroup objects, point PaintedGroup objects, color RotatedGroup objects, angle InkedGroup objects, pen
12
Some wrapper code [define box [width height → [new Box width height]]] [define line [start end → [new Line start end]]] [define group [objects … → [new Group objects]]] [define translate [point objects … → [new TranslatedGroup objects point]]] [define rotate [angle objects … → [new RotatedGroup objects angle]]] …
13
Reimplementing last quarter Okay, so we’ve been slowing reimplementing the graphics library from last quarter We’ve got data types (classes) to represent the different flavors of Picture We’ve got wrapper procedures to make the Picture objects for us There’s just one thing missing … Um, uh, how to we actually draw the stupid things?
14
From last time: Drawing in MS Windows [with-window “test” [g → [g.DrawLine [pen “black” 1] [point 0 0] [point 100 100]] [g.DrawLine [pen “blue” 3] [point 50 0] [point 50 100]] [g.DrawEllipse [pen “red” 40] 0 0 100 100]]]
15
Drawing pictures How do we draw a picture object in a window? It depends on the type of object Boxes Call g.DrawBox Lines Call g.DrawLine Groups Draw all the objects in the group’s objects field. So we need some way of basing the action to take on the type of the argument
16
Generic procedures and methods [define name [generic-procedure]] [define-method [name [type arg] …] body …] A generic procedure is a procedure that bases its behavior on the type(s) of its argument(s) A method is a specification of how to perform the procedure for a given argument type
17
Drawing lines [define draw [generic-procedure]] [define-method [draw [Line l] g] [g.DrawLine l.start l.end] ] draw is a procedure that behaves differently depending on its argument types This method defines how draw behaves when called with a Line (named l) and some other argument named g (no special type is specified for g) In this case, the system calls the DrawLine member of g with l.start and l.end as arguments
18
Drawing pictures [define draw [generic-procedure]] [define-method [draw [Line l] g] [g.DrawLine l.start l.end]] [define-method [draw [Box b] g] [with half-height = [/ b.height 2] half-width = [/ b.width 2] [g.DrawBox [- half-width] [- half-height] half-width half-height]]] … «For-each is like map but it doesn’t return any results» [define-method [draw [Group x] g] [for-each [p → [draw p g]] x.objects]] «Without using for-each» [define-method [draw [Group x] g] [with position = 0 [while [< position [length x.objects]] [draw [get x.objects position] g] [position ← [+ position 1]]]]]
19
Okay, that doesn’t actually work … [define draw [generic-procedure]] [define-method [draw [Line l] g] [g.DrawLine pen l.start l.end]] [define-method [draw [Box b] g] [with half-height = [/ b.height 2] half-width = [/ b.width 2] [g.DrawBox pen [- half-width] [- half-height] half-width half-height]]] … «For-each is like map but it doesn’t return any results» [define-method [draw [Group x] g] [for-each [p → [draw p g]] x.objects]] «Without using for-each» [define-method [draw [Group x] g] [with position = 0 [while [< position [length x.objects]] [draw [get x.objects position] g] [position ← [+ position 1]]]]]
20
Fixing it … [define draw [generic-procedure]] [define-method [draw [Line l] g pen] [g.DrawLine pen l.start l.end]] [define-method [draw [Box b] g pen] [with half-height = [/ b.height 2] half-width = [/ b.width 2] [g.DrawBox pen [- half-width] [- half-height] half-width half-height]]] [define-method [draw [Group x] g pen] [for-each [p → [draw p g pen]] x.objects]] «Cool; now we know how to do inked groups» [define-method [draw [InkedGroup x] g pen] [for-each [p → [draw p g x.pen]] x.objects]] «And now…» [define really-draw-the-stupid-picture [p → [with-window [g → [draw p g [pen “black” 1]]]]]]
21
Uninitialized fields Most imperative languages don’t require you to specify values for all an object’s fields when you create it This is generally considered a bad idea, by the way Such fields are called “uninitialized” If you don’t give a value for a field, it’s usually set to the magic value null null isn’t a data object null has no type
22
How class-type really works [class-type [name initialized-fields …] parent-type other-fields …] This makes a type called name That has all the fields Of parent-type That appear in other-fields And/or that appear in initialized-fields When you call new, only the ones in initialized-fields will be initialized from the arguments
23
Class-based inheritance (Corrected version of the code) Types automatically “inherit” the fields of their parent types But inherited fields still need to be specified in the constructor args if you want them initialized [define Picture [class-type [Picture] Object]] … [define Group [class-type [Group objects] Picture]] [define TranslatedGroup [class-type [TranslatedGroup objects point] Group]] [define RotatedGroup [class-type [RotatedGroup objects angle] Group]] [define InkedGroup [class-type [InkedGroup objects pen] Group]] [define PaintedGroup [class-type [PaintedGroup objects color] Group]]
24
Generic procedures vs. member procedures You may have noticed we’ve called two different things “methods” Things you add to generic procedures using define-method Things you call by saying [x.y bla bla bla …] Why are we using both? In systems like Java and.NET (on which Meta is built) You have to specify all the x.y methods when you make the class So the code has to be inside of class-type Which makes it big and hard to read And to change something, you have to completely redo the class So this quarter, we’re making life simpler (in some ways) by using generic procedures Next quarter, we’ll focus on the Java/C++ style methods
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.