three objects, classes, and hierarchies. this lecture will be long… sorry this is going to be the...

61
three objects, classes, and hierarchies

Upload: gwenda-long

Post on 18-Jan-2016

212 views

Category:

Documents


0 download

TRANSCRIPT

three

objects, classes, and hierarchies

This lecture will be long…

Sorry

This is going to be the big programming lecture of the quarter It’s really about teaching you object-oriented programming But we need a source of examples, so we’ll also teach you about

GUI programming (windows, buttons, sliders, etc.) “Collection classes” Low-level windows graphics calls

Don’t get too hung up on the examples What we really want you to understand is

What classes and subclasses What fields and methods are How to make new classes How to make new methods

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 (or: “classes”) Procedures Numbers (1, -3.5) Strings (“this is a string”, “blue”) Bitmaps Picture objects (lines, groups, boxes, etc.)

NumberValue: 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

BoxWidth: 10Height: 10

EllipseWidth: 15Height: 10

ProcedureName: iterated-groupArguments: proc countBody: [apply group [up-to count proc]]

ColorR: 240G: 220B: 0

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

ObjectList

Picture

Number

Integer Float Array

Box Line Group

Example 1:The Windows Forms class hierarchy

User-interface components (windows, buttons, etc.) are all objects

Individual windows are Form objects

Individual elements of windows are objects of type Button, TextBox, Label, etc.

Form, Button, etc. are all subtypes of the type Control

Controls can have other Controls inside of them

Which is how buttons can be inside forms

All these classes are in the System.Windows.Forms namespace

Control

Form TextBox

Label

Button TrackBar

PictureBox

Greatly simplified version of the winforms class hierarchy

Creating new data objects

[new type arguments …]

Creates a new object of the specified type

The arguments depend on the type For windows forms

classes, they generally don’t take any arguments

Great, but how do we get at the data in the object?

► [define my-form [new Form]]

NumberValue: 10

Member notation

You can ask for a field of a data object using the “.” notation: object.memberName myColor.R [pixel myBitmap 0 0].R iterated-group.Name iterated-group.Arguments mybox.Width

Note: to simplify the presentation, I’ve lied here about what the actual fields of boxes, procedures, etc. are.

You can find out what fields are really in an object using the inspector.

BoxWidth: 10Height: 10

EllipseWidth: 15Height: 10

ProcedureName: iterated-groupArguments: proc countBody: [apply group [up-to count proc]]

ColorR: 240G: 220B: 0

Fields of the Control class These can be used to change the

appearance of any control

There are many more, but these should be enough for you for now.

BackColor, ForeColor Background/foreground color for the

control Font

Font that text appears in (see the slide at the end for how to specify a font)

Text Text that appears in the control (if any)

Height, Width The size of the control

Location The X,Y coordinate of the top-left

corner (as a point) Left, Top

The individual X- and Y- coordinates of the control within its window

Member procedures (aka “methods”)

Some of an object’s members are procedures They act like they’re stored inside the object You call them by saying:

[object.name args …] They are usually called methods

N.B.: “method” is also used to refer to a slightly different kind of procedure we’ll talk about in the next unit

Examples [x.ToString]

Returns a string that represents x [g.DrawLine startx starty endx endy]

Draws a line in a window given its

The Form class

A form is a window that can hold controls

It’s also a special kind of control, so you can set things like its Width, Height, BackColor, etc.

[using System.Windows.Forms] Tells system to use classes in the

Windows Forms namespace [new Form]

Makes a form [form.Controls.Add control]

Adds a control to a form

[Application.Run form] Displays form and lets the user

work with it until they close it. [form.Show]

Used to show a new form after Application.Run has already been invoked

The TextBox control

[new TextBox] Makes a space where the user can type Whatever they type appears in the Text field

of the object (remember the Text field?)

Example: entering text

[define get-text[starting-text → [with* f = [new Form] make the Form

tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]

Example: entering text

[define get-text[starting-text → [with* f = [new Form]

tbox = [new TextBox] make the TextBox [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]

Example: entering text

[define get-text[starting-text → [with* f = [new Form]

tbox = [new TextBox] [f.Controls.Add tbox] add the TextBox to the Form [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]

Example: entering text

[define get-text[starting-text → [with* f = [new Form]

tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] set Text to the default [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]

Example: entering text

[define get-text[starting-text → [with* f = [new Form]

tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] make it 150 pixels wide [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]

Example: entering text

[define get-text[starting-text → [with* f = [new Form]

tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] put tbox at (10, 10) [Application.Run f] tbox.Text]]]

Example: entering text

[define get-text[starting-text → [with* f = [new Form]

tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] let the user play with it tbox.Text]]]

Example: entering text

[define get-text[starting-text → [with* f = [new Form]

tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]] return the text they typed

The make command

You will find that you spend a lot of time calling new and then setting fields of the resulting object This can be tedious And hard to read

The make command simplifies this by letting you simultaneously Make the object, and Set its fields

[make [Type args …] field: value …] Runs [new Type args …] Then sets each field of the new

object to its corresponding value N.B.: the colons are mandatory

Rewriting using make

[define get-text[starting-text → [with* f = [new Form] tbox = [make [TextBox] Text: starting-text Width: 150 Location: [point 10 10]]

[f.Controls.Add tbox] [Application.Run f] tbox.Text]]]

Aside: macros and syntactic sugar

Make is an example of a macro Macros are convenient shorthands for

more complicated expressions Meta translates make into a call to new

and a bunch of assignment statements (well, almost)

Why are we telling you this? Because it means that if you use make

incorrectly You probably won’t see make

anywhere in the debugger You’ll see a call to new instead

So we just don’t want you to be confused

If you want to learn to write your own macros, talk to Ian

Some macros you may have been using [when test expressions …]

[unless test expressions …] Gets translated to:

[if test [begin expressions …]], or [if [not test] [begin expressions …]], respctvly

[cond [test1 expressions …] [test2 expressions …] …etc…]

Gets translated to:[if test1 [begin expressions …] [if test2 [begin expressions …] …etc…]]

[define [name args …] expressions …]

Gets translated to:[define name [args … → expressions …]]

Three problems

This is okay, but it has some definite problems:

You click the close box to finish (rather than an OK box)

It doesn’t actually work because Application.Run turns out to clear the Text of tbox

We’ll ignore this for the moment and pretend it works

The window is outrageously tall We’ll leave fixing this as an

exercise for the reader The window has no name

You can fix this by setting its Text or Name field

Adding a button

[define get-text[starting-text → [with* f = [new Form] b = [make [Button] Text: “OK” Location: [point 170 10]]

tbox = [make [TextBox] Text: starting-text Width: 150 Location: [point 10 10]]

[f.Controls.Add tbox] [f.Controls.Add b]

[Application.Run f] tbox.Text]]]

Trying it out

Hey! We have a button!

Hey! It doesn’t do anything!

Hey! The window is still too tall and has no name! Oh, shut up…

Event handling

You need some way of specifying what to do when the button is pressed This is done by specifying a procedure called

an “event handler” or a “callback” When the even happens, the system calls the

procedure

Event handling in Meta

Events look like lists of procedures to call when the event happens To add a handler for an event, add it to the list:

[object.event.Add handler-procedure] Or specify it as part of the make arguments

Windows Forms always passes two parameters to the handler procedure The control that generated the event An extra data object that we’ll ignore for the moment

Adding a Click handler

[define get-text[starting-text → [with* f = [new Form] b = [make [Button] Text: “OK” Location: [point 170 10] Click: [ignore ignore → [f.Close]]]

tbox = [make [TextBox] Text: starting-text Width: 150 Location: [point 10 10]]

[f.Controls.Add tbox] [f.Controls.Add b]

[Application.Run f] tbox.Text]]]

Shortening the form

[define get-text[starting-text → [with* f = [make [Form] Height: 75] b = [make [Button] Text: “OK” Location: [point 170 10] Click: [ignore ignore → [f.Close]]]

tbox = [make [TextBox] Text: starting-text Width: 150 Location: [point 10 10]]

[f.Controls.Add tbox] [f.Controls.Add b]

[Application.Run f] tbox.Text]]]

Naming the form

[define get-text[starting-text → [with* f = [make [Form] Height: 75 Text: “Please enter some text”] b = [make [Button] Text: “OK” Location: [point 170 10] Click: [ignore ignore → [f.Close]]]

tbox = [make [TextBox] Text: starting-text Width: 150 Location: [point 10 10]]

[f.Controls.Add tbox] [f.Controls.Add b]

[Application.Run f] tbox.Text]]]

It works!

In particular, clicking the OK box Closes the form as if

the user had click the close box

Which causes Application.Run to finish

Which causes get-text to finish and return the text

The TrackBar control

[new TrackBar] Makes a slider control

Useful fields (plus Control’s fields) Value

The current numeric value the user has chosen Minimum, Maximum

The numeric values for the ends of the range of the slider TickFrequency

How often to draw tick marks Orientation

Whether it should be a horizontal or vertical control.Set it to either Orientation.Horizontal or Orientation.Vertical.

Useful events ValueChanged (called when the user moves the slider)

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] make a form r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top:10] make three sliders to go with it g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → run this procedure on r, g, and b [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] add it to the form [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] make it 255 pixels wide [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] set its limits to 0 and 255

[slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add add the following handler for when the slider changes

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

ignore arguments … and change the background color of the form [ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]] start the form up

Running it

Fixing a bug

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

This what it looks like when you start it up. What’s wrong with this?

Fixing a bug

[with f = [new Form] r = [make [TrackBar] Top: 10] g = [make [TrackBar] Top: 60] b = [make [TrackBar] Top: 110]

[f.BackColor ← [color 0 0 0]] [for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add

[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]

[list r g b]] [Application.Run f]]]

What does this do?

[define slider-text [→ [with* f = [new Form] s = [make [TrackBar]

Top: 10 ValueChanged: [i i → [t.Text ← [s.Value.ToString]]]]

t = [make [TextBox] Top:60 TextChanged: [i i → [s.Value ← [System.Int32.Parse t.Text]]]]

[f.Controls.Add s] [f.Controls.Add t] [Application.Run f]]]]

Hints: [System.Int32.Parse string] returns the number represented by string.

Example: [System.Int32.Parse “10”] returns 10 (the integer, not a string)

Fixing a bug

[define slider-text [→ [with* f = [new Form] s = [make [TrackBar]

Top: 10 ValueChanged: [i i → [t.Text ← [s.Value.ToString]]]]

t = [make [TextBox] Top:60 TextChanged: [i i → [ignore-errors [→ [s.Value ← [System.Int32.Parse t.Text]] ]]]

[f.Controls.Add s] [f.Controls.Add t] [Application.Run f]]]]

Ignore-errors runs its argument procedure and ignores any errors that occur

It works!

Some other useful Controls

[new Label] Like a textbox but the user can’t change it

[new CheckBox] Makes a box Useful fields

Checked (whether the box has been checked (true or false))

Example 2:The container class hierarchy

An important area of computer science is the study of data structures

Roughly: how we put data objects together to make them useful

A very important kind of data structure is the container

A kind of object that “holds” a collection of other objects

There are many kinds of containers

Most of the container classes we’ll be using are subtypes of List

All the collection classes in .NET (and so in Meta) are in the namespace System.Collections

Collection

List Dictionary

Array ArrayList Stack Hashtable

Object[] String[] …

Lists

Have a bunch of elements Have them in a definite order

You can ask them how many elements they have

You can ask for an element at a specific position You can change the element at a specific

position

Basic list operations

[length list] or: list.CountTells you how many items are in the list

[get list position]Returns the element of list at position

[[get list position] ← new-value]Changes the element of list at position

The simplest list type: the array

An array is a fixed-length list Very fast and efficient Can’t add/remove element after creation Although you can change elements

The [list args …] procedure returns an array Technically, the type Object[] Which means an array of arbitrary objects There are other kinds of specialized arrays too

The ArrayList: a more powerful list type

ArrayLists can change size, but are less efficient

[using System.Collections]Access collection classes

[new ArrayList]Makes an ArrayList

[x.Add object] Add object to end of ArrayList x

[x.Insert position object] Adds element at the specified position

[x.Remove object] Removes all occurrences of object

[x.RemoveAt position] Remove element at position

[x.Clear]Removes all elements from x

«Some results omitted to save space»

►[using System.Collections] ►[define mylist

[new ArrayList]][ ]► [mylist.Add 98]► [mylist.Add 38]► [mylist.Add 4]► mylist[98 38 4]► [mylist.Remove 38]► mylist[98 4]► [mylist.Insert 1 “test”]► mylist[98 “test” 4]►

The stack: a simpler collection class

Stacks can only be changes at their “top” or beginning

[new Stack]Makes a new stack

[s.Push object]Adds a new object to the “top” of the stack s

[s.Pop]Removes the item at the top of s and returns it

[s.Peek]Returns the item at the top of s without removing it

[s.Clear]Removes all data from s

► [define s [new Stack]]‹System.Collections.Stack›► [s.Push 1]► [s.Push 2]► [s.Push 3]► [s.Peek]3► [s.Peek]3► [s.Pop]3► [s.Pop]2► [s.Pop]1► [s.Pop]Error: Stack empty.

Dictionary classes

Dictionaries are objects that store associations between pairs of objects One object is called the key The other the value

The most common dictionary class is the Hashtable

The Hashtable class

[new Hashtable]Makes a new hashtable

[lookup dict key] Returns the object listed in dict under key Or null if key doesn’t appear in dict

[store-dictionary dict key value]or: [[lookup dict key] ← value]

Adds or changes the entry for key in dict to value

[dict.Clear]Removes all entries from dict

[dict.Contains key]Checks whether dict contains an entry for key

► [define h [new Hashtable]]► [lookup h “test”]null► [[lookup h “test”] ← “got it”]"got it"► [[lookup h “test2”] ←

“something different”]"something different" ► [lookup h “test”]"got it"► [[lookup h “test”] ←

“changed it”]"changed it"► [lookup h “test”]"changed it"

appendix

picky little details I ignored

How do I specify a font?

Just type:

[new Font fontfamily [System.Convert.ToSingle size] style]

where:

Fontfamily is a string, like “Times New Roman” Size is a number (the size of the font in points), e.g. 10 or 12 Style is one of:

FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Strikeout, FontStyle.Underline

How do we fix get-text to return the stupid text?

Change:[with* f = [new Form] b = [new Button] tbox = [new TextBox]

… bla bla bla …

[Application.Run f] tbox.Text]

To:[with* f = [new Form] b = [new Button] tbox = [new TextBox] remember = starting-text

… bla bla bla …

[tbox.TextChanged.Add [ignore ignore → [remember ← tbox.Text]]]

[Application.Run f] remember]

We add a new event handler that runswhenever the user changes the text