Object Oriented Programming
This activity has the following desired goals:
- Learning about object oriented programming (A, M).
- Going through the process of converting a regular structured program to an object oriented program (A, M).
- Understanding the idea of Objects and Message-passing.
- Understanding Abstraction, Encapsulation, Polymorphism, Inheritance, and Composition (A, M).
- Using the above ideas to create a new class to fit into an existing program (M, T).
Step 1
Type in the following code and run it:
cleari()
drawStage(black)
val pic1 = Picture.rectangle(50, 50)
val pic2 = Picture.rectangle(50, 50)
draw(pic1, pic2)
var vel1 = Vector2D(1, 2)
var vel2 = Vector2D(-1, 2)
animate {
pic1.translate(vel1)
pic2.translate(vel2)
if (pic1.collidesWith(stageBorder)) {
vel1 = bouncePicOffStage(pic1, vel1)
}
if (pic2.collidesWith(stageBorder)) {
vel2 = bouncePicOffStage(pic2, vel2)
}
}
Q1a. What does the above program do? How does it do it?
Q1b. In calls or usages like pic1.translate(vel1)
, what’s on the left of the .
and what’s on the right? Can you guess how this might relate to objects and messages being passed to objects?
Explanation
In the above program, various commands are used, one after the other, to carry out the desired functionality. We see examples of the sequencing of commands, repetition (via animate
), the calling of various picture commands, and the use of one function to do an interesting calculation/computation. The focus is on the flow of control of the program.
Let’s focus on one line in the program – pic1.translate(vel1)
.
Here the thing to the left of the .
is an object (a bundle of data and commands/functions that work with that data). The thing to the right of the .
is a method (a command or function) in the object. Methods in objects work in the context of the data within the object. You can think of the calling of a method in an object as the passing a message to that object.
Step 2
Type in the following code and run it:
cleari()
drawStage(black)
class InstagePic(pic: Picture, vel: Vector2D) {
var currVel = vel
def move() {
pic.translate(currVel)
if (pic.collidesWith(stageBorder)) {
currVel = bouncePicOffStage(pic, currVel)
}
}
def draw() {
pic.draw()
}
}
val pic1 = new InstagePic(Picture.rectangle(50, 50), Vector2D(1, 2))
val pic2 = new InstagePic(Picture.rectangle(50, 50), Vector2D(-1, 2))
pic1.draw()
pic2.draw()
animate {
pic1.move()
pic2.move()
}
Q2a. Does the above program do the same thing as the program in Step 1
? How is it different?
Explanation
In the program in Step 2
, the logic for bouncing off the stage and keeping within the stage area has moved inside the class InstagePic.
So what’s a class, and how does it relate to object oriented programming? Read on:
- A class is a description/definition of a type.
- Given a class
X
, you can create an object of typeX
named, say,x1
by doingval x1 = new X
. x1
is now an object with typeX
.x1
is called an instance ofX
. You can create as many instances ofX
in your program as you want, giving them whatever names you want.- The data and methods available in the object
x1
are as per the definition ofX
(becausex1
is an instance ofX
). - Programming with objects is called object oriented programming.
- The core ideas in object oriented programming are:
- Abstraction - Something useful is created with a given name and a way of interacting with it (called its interface).
- Message Passing - You interact with an abstraction only by passing messages to it (via method calls).
- Encapsulation - The implementation of the interface is hidden behind the walls of the abstraction (within the body of the class/object).
- Polymorphism - Different types of objects with the same interface can be treated in the same fashion. Ploymorphism literally means - many forms, and supports the idea of the same thing (interface) in many forms (implementations). So if an interface has a method
makeSound
, and you have a sequence of objects that implement this interface, you can call themakeSound
method on all these objects, and the exact sound that is made can vary depending on the implementation of this method in the object. - Inheritence and composition - to use the functionality of a given class, a new class can inherit from it or use it (by containing an instance of it).
Note how in object-oriented programming, the focus shifts from the flow of control to the flow of messages.
Q2b. Can you identify the abstraction in the above code?
Q2c. Can you identify the message-passing in the above code?
Q2d. Can you identify the encapsulation in the above code?
Step 3
Type in the following code and run it:
cleari()
clearOutput()
drawStage(black)
trait Shape {
def pic: Picture
var currVel: Vector2D = _
def draw() {
pic.draw()
}
def move() {
pic.translate(currVel)
if (pic.collidesWith(stageBorder)) {
currVel = bouncePicOffStage(pic, currVel)
}
}
def printShape()
}
class Square(size: Int, vel: Vector2D) extends Shape {
val pic = Picture.rectangle(size, size)
currVel = vel
def printShape() {
println("Square")
}
}
class Circle(radius: Int, vel: Vector2D) extends Shape {
val pic = Picture.circle(radius)
currVel = vel
def printShape() {
println("Circle")
}
}
val pic1 = new Square(50, Vector2D(1, 2))
val pic2 = new Circle(25, Vector2D(-1, 2))
val pics = List(pic1, pic2)
repeatFor(pics) { pic =>
pic.draw()
pic.printShape()
}
animate {
repeatFor(pics) { pic =>
pic.move()
}
}
Q3a. Can you identify the abstraction in the above code?
Q3b. Can you identify the interface vs implementation in the above code?
Q3c. Can you identify the message-passing in the above code?
Q3d. Can you identify the inheritance in the above code?
Q3e. Can you identify the composition in the above code?
Q3f. Can you identify the polymorphism in the above code?
Explanation
- The core abstraction above is
Shape
. It is defined using a trait, which is similar to aninterface
in Java. TheShape
abstraction defines the interface via which a user of a Shape can interact with the given shape, by passing messages to it via the methods defined in the interface. Shape
has two different implementations -Square
andCircle
, each of whichextends
or inherits fromShape
.Shape
provides an implementation ofdraw
andmove
, which are inherited (and do not need to be defined again) bySquare
andCircle
.- Every shape has a Picture
pic
within it (via composition) when can be used to draw and move the shape on the stage. - The two
repeatFor
calls show polymorphism in action, as bothSquare
andCircle
(which are poly morphs or different forms ofShape
) are handled in exactly the same way through calls (message-passing) to thedraw
,printShape
, andmove
methods.
Exercise
Add a triangle shape to the above example - so that when you run the program, three different shapes (a square, a circle, and a triangle) move out from the center, bounce off the stage borders, and stay within the stage area.
Copyright © 2010–2024 Kogics Foundation. Licensed as per Terms of Use.