• No results found

Abstraktion och modellering VT 2015

N/A
N/A
Protected

Academic year: 2021

Share "Abstraktion och modellering VT 2015"

Copied!
35
0
0

Loading.... (view fulltext now)

Full text

(1)

TDDC74

Programmering:

Abstraktion och modellering

VT 2015

Johannes Schmidt

Institutionen för datavetenskap

Linköpings universitet

(2)

Lecture 9

Mutable structres, ADTs, OOP

• Abstract data types: queue, stack

• Mutable pairs, lists: singly / doubly linked list

• Object Oriented Programming (OOP) in Racket

• SICP-Book chapter: 3

(3)

An abstract data type: Stack

Think of a stack as a

pile of books

(items):

TOS: Top Of Stack.

(4)

An abstract data type: Stack

ADT Stack

Methods:

•push

: put a given item on the stack. This item is then the new TOS.

•pop

: remove the TOS-item and return it.

Optional methods:

•size

: determine the number of elements currently in the stack.

•empty?

: check whether the stack is empty.

(5)

An abstract data type: Queue

Think of a queue as a

queue of people

(items):

(6)

An abstract data type: Queue

ADT Queue

Methods:

•enqueue

: put a given item into the queue, at the rear.

•dequeue

: remove an item from the queue, at the front.

Optional methods:

•size

: determine the number of elements currently in the queue.

•empty?

: check whether the queue is empty.

(7)

How to implement

a stack, a queue?

Singly linked list

(8)

Doubly linked list

A doubly linked list with insertion and extraction at both

ends can be used to implement both, stack and queue

push

pop

enqueue

dequeue

- insert at front

- extract at front

- insert at rear

- extract at front

(9)

How to implement

singly / doubly linked lists?

Singly linked list

Easy: take on ordinary list

Doubly linked list

Easy: create a triple-object with selectors left, middle, right

E.g.

(define (make-triple left middle right)

(10)

Is a programming paradigm.

Idea: every problem can be described by objects and their

interactions / relations. This helps creating abstractions

and achieving encapsulation.

Therefore: in order to solve a problem, break it down into

subproblems, by identifying objects and how they interact

with and relate to each other.

(11)

Game Pac-Man

Scenario: Pac-Man goes through a

labyrinth, eats pellets and has to avoid

being eaten/attacked by enemies.

Identify Objects:

• Pac-Man

• Pellet

• Enemy

• Power pellet

• …

OOP Example

Source: http://en.wikipedia.org/wiki/Pac-Man
(12)

Relations between Objects:

• Pac-Man eats Pellets

• Enemy eats/attacks Pac-Man

• Pac-Man eats Power pellet

• Pac-Man eats Enemy if eaten

recently Power pellet

• …

OOP Example

(13)

Is a programming paradigm.

Idea: every problem can be described by objects and their

interactions / relations.

Relations between objects indicate what different

properties the different objects should have.

These properties are realized via

fields

(variables/data)

and

methods

(procedures):

Every object has its own fields and methods!

(14)

Some fields of some Objects:

Pac-Man:

Lifes (0-3)

Score (0-1000000)

State: recently Power pellet eaten?

Enemy:

Color

State: currently eatable or not?

Direction

Speed

OOP Example

(15)

Some methods of some Objects:

Pac-Man:

(eat-enemy enemy)

(reduce-life amount)

(eat-pellet pellet)

(die)

Enemy:

(eat-Pac-Man)

(change-eatable-state value)

(speed-up)

(die)

OOP Example

Source: http://en.wikipedia.org/wiki/Pac-Man
(16)

Game Pac-Man

Observation

:

some objects will occur just once, others several

times

Occurrences of Objects:

1x Pac-Man

Nx Pellet

4x Enemy

4x Power pellet

OOP Example

Source: http://en.wikipedia.org/wiki/Pac-Man
(17)

Game Pac-Man

Observation

:

some objects will occur just once, others several

times

Occurrences of Objects:

1x Pac-Man

Nx Pellet

4x Enemy

4x Power pellet

Solution:

Classes

!

OOP Example

Source: http://en.wikipedia.org/wiki/Pac-Man
(18)

A

Class

can be considered as a model for objects that

share the

same properties

, but are still

different

individuals

.

If we have a

class definition

, we can then create an

object from that class.

This process is called

instantiating

.

For this purpose every class provides a

constructor

.

(19)

Game Pac-Man

Classes for Pac-Man:

Pac-Man

Pellet

Enemy

Power-pellet

Then

instantiate

One object of Pac-Man

Many objects of Pellet

Four objects of Enemy

Four objects of Power-pellet

OOP Example

(20)

A

Class

can be considered as a model for objects that share the

same properties

, but are still

different individuals

.

What if we have similar classes that share a lot of common

properties but are not exactly the same?

Solution

: We can

derive

or

inherit

a class from another.

Via

Inheritance

we obtain a

derived class

, or a

subclass

.

Think of this as taking a copy of a class, and then modifying this

copy according to our needs.

(21)

Game Pac-Man

Similar classes for Pac-Man:

Pellet

Power-pellet

For instance make Power-pellet a subclass of

Pellet, i.e. treat a Power-pellet as a special case

of a Pellet.

Alternatively: Have a common superclass, call it

General-pellet

. Then derive once an

Ordinary-pellet

and once a

Power-pellet

.

OOP Example

(22)

(define (make-pac-man lifes score pp-eaten) ; three fields

(define (dispatch message . args) ; define different methods (cond ((eq? message 'eat-enemy)

(if pp-eaten

(void) ; details to be implemented 'not-possible))

((eq? message 'reduce-life)

(set! lifes (- lifes (car args)))) ((eq? message 'eat-pellet)

(set! score (+ score 1))) ((eq? message 'die)

(void)) ; details to be implemented ((eq? message 'say-hello)

(printf "Hi I am a happy pac-man with ~a lifes\n" lifes))

(else '(unkown message))))

dispatch)

(23)

OOP in Racket - simple

(define (make-pac-man lifes score pp-eaten) ; three fields

(define (dispatch message . args) ; define different methods (cond ((eq? message 'eat-enemy)

(if pp-eaten

(void) ; details to be implemented 'not-possible))

((eq? message 'reduce-life)

(set! lifes (- lifes (car args)))) ((eq? message 'eat-pellet)

(set! score (+ score 1))) ((eq? message 'die)

(void)) ; details to be implemented ((eq? message 'say-hello)

(printf "Hi I am a happy pac-man with ~a lifes\n" lifes))

(else '(unkown message))))

dispatch)

; create a Pac-Man: instantiate

(define my-pac-man (make-pac-man 3 0 #f))

; call some methods

(my-pac-man 'say-hello)

(my-pac-man 'reduce-life 1) (my-pac-man 'say-hello)

Output:

Hi I am a happy pac-man with 3 lifes Hi I am a happy pac-man with 2 lifes

(24)

(define Pac-Man% (class object%

; fields (variables/data)

(init-field lifes score pp-eaten)

(super-new) ; superclass initialization (define/public (eat-enemy enemy) ; method

(if pp-eaten

(void) ; details to be implemented 'not-possible))

(define/public (reduce-life amount) ; method (set! lifes (- lifes amount)))

(define/public (eat-pellet pellet) ; method (set! score (+ score 1)))

(define/public (die) ; method (void)) ; details to be implemented (define/public (say-hello)

(printf "Hi I am a happy pac-man with ~a lifes\n" lifes))))

(25)

(define Pac-Man% (class object%

; fields (variables/data)

(init-field lifes score pp-eaten)

(super-new) ; superclass initialization (define/public (eat-enemy enemy) ; method

(if pp-eaten

(void) ; details to be implemented 'not-possible))

(define/public (reduce-life amount) ; method (set! lifes (- lifes amount)))

(define/public (eat-pellet pellet) ; method (set! score (+ score 1)))

(define/public (die) ; method (void)) ; details to be implemented (define/public (say-hello)

(printf "Hi I am a happy pac-man with ~a lifes\n" lifes))))

OOP in Racket

; create a Pac-Man: instantiate

(define my-pac-man (make-object Pac-Man% 3 0 #f))

; call some methods

(send my-pac-man say-hello)

(send my-pac-man reduce-life 1) (send my-pac-man say-hello)

Output:

Hi I am a happy pac-man with 3 lifes Hi I am a happy pac-man with 2 lifes

(26)

(define General-pellet% (class object%

; fields (variables/data) (init-field color position)

(super-new) ; superclass initialization (define/public (get-type) ; method

'general)))

(define Ordinary-pellet% (class General-pellet%

(super-new) ; superclass initialization (define/override (get-type) ; method

'ordinary)))

(define Power-pellet%

(class General-pellet%

(super-new) ; superclass initialization (define/override (get-type) ; method

'power)))

(27)

(define General-pellet% (class object%

; fields (variables/data) (init-field color position)

(super-new) ; superclass initialization (define/public (get-type) ; method

'general)))

(define Ordinary-pellet% (class General-pellet%

(super-new) ; superclass initialization (define/override (get-type) ; method

'ordinary)))

(define Power-pellet%

(class General-pellet%

(super-new) ; superclass initialization (define/override (get-type) ; method

'power)))

OOP in Racket - Inheritance

We inherit from object%

This is a special inbuilt base class

We inherit from General-pellet%

(28)

(define General-pellet% (class object%

; fields (variables/data) (init-field color position)

(super-new) ; superclass initialization (define/public (get-type) ; method

'general)))

(define Ordinary-pellet% (class General-pellet%

(super-new) ; superclass initialization (define/override (get-type) ; method

'ordinary)))

(define Power-pellet%

(class General-pellet%

(super-new) ; superclass initialization (define/override (get-type) ; method

'power)))

OOP in Racket - Overriding

We inherit ALL fields and methods.

That is:

- no need to redefine fields or methods - if we want to change a method, we need

(29)

(make-object <Class> <list of init-values>)

(define my-pac-man

(make-object Pac-Man% 3 0 #f))

; Alternatively:

(new <Class> [varname1 value1] [varname2 value2] ...)

(define my-pac-man

(new Pac-Man%

[lifes 3]

[score 0]

[pp-eaten #f]))

(30)

From inside the class definition you call methods as usual.

From outside special syntax is provided:

(send <object> <method-name> <list of parameters>)

; e.g.:

(send my-pac-man say-hello)

(send my-pac-man reduce-life 1)

(send my-pac-man say-hello)

(31)

(define Pac-Man%

(class object%

; init-fields, i.e. values MUST

; be provided during instantiation

(init-field lifes score pp-eaten)

; ordinary fields, i.e. values must be provided

; right here

(field [color 'red] [more-stuff 'hmblhmbl])

...

(32)

From inside the class definition you access fields as usual variables.

From outside special syntax is provided:

(get-field <field-name> <object-name>)

(set-field! <field-name> <object-name> value)

E.g.

(define my-pac-man (make-object Pac-Man% 3 0 #f))

(get-field color my-pac-man)

(set-field! color my-pac-man 'green)

But

: avoid setting fields this way. Better provide your own

methods to change the values of fields.

(33)

(define Pac-Man%

(class object%

; public

fields (visible/accessible from outside)

(init-field lifes score pp-eaten)

(field [color 'red] [more-stuff 'hmblhmbl])

; private

fields (not visible from outside)

(define internal-value 11439)

; public

method (visible/accessible from outside)

(define/public (eat-enemy enemy) ; method

(if pp-eaten

(void) ; details to be implemented

'not-possible))

; private

method (not visible from outside)

(define (do-some-stuff parameter1)

...)

OOP in Racket – Visibility

(34)

object, class

field, method

inherit, derive, extend

subclass, superclass

override

(35)

Remember: use OOP in order to create abstractions and to

achieve encapsulation (hide implementation details).

Therefore: keep as much as possible private, so it is not

visible to the outside.

Expose to the outside only what is absolutely necessary.

Provide public methods to manipulate variables/fields, do not

set them directly.

References

Related documents