Luet oppimateriaalin englanninkielistä versiota. Mainitsit kuitenkin taustakyselyssä
osaavasi suomea. Siksi suosittelemme, että käytät suomenkielistä versiota, joka on
testatumpi ja hieman laajempi ja muutenkin mukava.
Suomenkielinen materiaali kyllä esittelee englanninkielisetkin termit. Myös
suomenkielisessä materiaalissa käytetään ohjelmaprojektien koodissa englanninkielisiä
nimiä kurssin alkupään johdantoesimerkkejä lukuunottamatta.
Voit vaihtaa kieltä A+:n valikon yläreunassa olevasta painikkeesta. Tai tästä:
About This Page
Questions Answered: How can I represent my program’s “world” to
the computer? How can a larger program be built up from components —
objects — that work together? How do I command an object in Scala?
Topics: Programming as conceptual modeling. Object-oriented
programming: objects and methods, communication between objects.
Singleton objects in Scala: calling a method, referring to an object.
What Will I Do? First, there’s some very important reading to do.
Then you’ll practice commanding objects in code.
Rough Estimate of Workload:? Two hours or so, if you go
through each example carefully, as you should. The chapter may be
challenging: the fundamental concepts of object-oriented programming
may seem abstract or alien at first.
Points Available: A25.
Related Projects: IntroOOP (new).
So far, we’ve covered an assortment of programming constructs: expressions, references,
functions, data types, and so on.
Let’s put them all to the side for a moment.
In this chapter, we’ll adopt a new perspective as we discuss our chosen approach to creating
larger programs: object-oriented programming.
In a sense, all the preceding chapters have been an overture for the work that begins in
this chapter and continues throughout O1. At first, it may not be clear how what you
learned earlier connects with this chapter, but by the time you finish the chapter, you
should already have a fair inkling. As it happens, the overture was composed out of
those elements precisely because they’ll soon come in handy as you learn to program in an
Programs manipulate diverse forms of data. Just adding numbers, concatenating strings,
or drawing circles won’t get us far. We want our program to “store a file”, “enroll a
student in a course”, “react to a button click”, “withdraw money from an account”, or
“pick the enemy’s next move”.
We face a problem: human thought and language are conceptual, but the computer doesn’t
understand real-world concepts. What is a “course”, a “student”, a “hotel”, or a “bank
A programming language cannot unambiguously define all the countless concepts that we
might want to use in programs. Nevertheless, the computer needs unambiguous instructions
if it is to execute programs that operate on the “world”, or domain, of the program.
Defining concepts in program code.
Let’s take our human needs as our point of departure. Let’s create programs that a machine
can process but that reflect people’s ways of making sense of the world. Let’s specify the
concepts and terms that we need for the computer!
As programmers, our task will be to model the program’s domain: we’ll create a conceptual
model of the relevant information and the behavior that is associated with each concept.
Since the programming language itself doesn’t define all the concepts we want, we need the
language to help us express definitions of our own.
Over the years, people have come up with a number of different ways to program, so-called
programming paradigms (ohjelmointiparadigma). Different programming paradigms have
their own recommendations about how to think about programs, how to represent a program’s
domain, and how to structure program code.
In O1, we’ll focus on a particular paradigm: object-oriented programming or
OOP (olio-ohjelmointi). OOP is a popular and interesting way to program. The
Scala language is well suited to OOP.
Paradigms in O1
It’s possible to draw from several paradigms at once. The Scala
language, for instance, has been deliberately designed to support
multiple approaches to programming and to combine approaches. In
O1, we’ll combine OOP especially with what is known as imperative
programming (imperatiivinen ohjelmointi) and also with functional
programming (funktionaalinen ohjelmointi). No need to worry about
that now, though; we’ll discuss paradigms in some more detail in
OOP has a number of attractive characteristics. In O1, we’ll embrace
objects rather unquestioningly. Even so, you may wish to make a mental
note of the fact that OOP is not a silver bullet that always works
for any and all programming needs. Chapter 10.2 and O1’s follow-on
courses will introduce you to alternative approaches.
Object-oriented programming emphasizes conceptual modeling. Each individual course,
student, back account, GUI window, or button can be represented as an “object”.
object: something mental or physical toward which
thought, feeling, or action is directed
Raindrops on roses and whiskers on kittens,
bright copper kettles and warm woolen mittens,
brown paper packages tied up with strings;
these are a few of my favorite things!
—from The Sound of Music by Rodgers and Hammerstein
—from The Sound of Music by Rodgers and Hammerstein
An diagram illustrating an object and its methods.
An object (olio) is an abstraction of an entity or “thing” in an object-oriented
program. Typically, an object will have a number of behaviors, known as methods (metodi),
that define how you can use the object. For instance, you might represent a car as an
object that has methods such as “drive”, “add passenger”, “refuel”, “determine remaining
fuel”, and so on.
Many objects also have attributes that describe the object’s permanent or variable
characteristics. For instance, a car object might have attributes such as manufacturer,
current location, the amount of fuel in the car’s tank, or the passengers currently inside
It’s up to the programmer to choose which attributes and methods they want to associate
with each object. That decision depends on which aspects of the domain (the “world”) are
relevant to the problem at hand. For instance, a car’s manufacturer might be relevant in
some programs but not in others. As a computer runs an object-oriented program, it stores
objects in its memory as dictated by the programmer.
Pretty much anything can be represented as an object. Here are some examples in visual form:
As the image shows, an object can be associated with data (e.g., the ID number of a student
object, the text of a button object) as well as actions (e.g., enrolling a student, removing
a file). Notice, too, that objects may resemble each other — in other words, they may have
the same type — as is the case for the two animal objects above.
We’ll usually use a combination of objects to model a program’s domain. Here’s one simplified
example as a diagram:
Objects associated with an imaginary course-enrollment system
(cf. the Oodi system used at Aalto). Notice that the objects
refer to each other and combine to form a whole.
Each object has specific responsibilities in making a program work. For instance, a
course object might be charged with keeping track of which students have enrolled: it
records new enrollments while adhering to restrictions on how many students can sign
up. By combining the functionality of different objects, we can define the whole
We can also use objects to represent a user interface. Consider the following GUI
window, for example:
In a Scala program, that window can be represented as a combination of objects as shown
in this diagram:
There’s a common metaphor that may help you wrap your brain around OOP.
You can think of objects as human-like actors. Each object is, if not sentient, at least
capable in a narrow speciality.
An object is self-aware in the sense that it “knows” its own attributes. For instance, a
car object knows the amount of gas left, and a course object knows the students who have
An object is capable of receiving messages (“commands”, “requests”) that match its
methods. You can command a course object to enroll a student, a car object to refuel, or
a file object to delete the corresponding data from the hard drive. An object can’t
act on a message unless it has a method available for that sort of message.
An object has a specific way of behaving, that is, a specific way of reacting to the
messages it receives. The programmer defines the objects’ behavior using the tools
of the programming language: for example, we can define objects that compute with
numbers, record information in the computer’s memory, send messages to other objects,
create new objects, and so forth.
An object is unfailingly obedient and complies with the programmer’s instructions to the
letter. Object-oriented programming, too, requires diligence, precision, and unambiguosity
A single object may not be able to do much, but multiple objects in organized co-operation
can accomplish a great deal. Let’s take a look at two examples.
How does Chapter 1.2’s GoodStuff application operate, as a whole, when you use it through
its GUI? For instance: what happens when the user clicks the Add experience
button? At that point, the program is supposed to record a new experience and, if
appropriate, move the happy face that marks the user’s favorite experience.
The objects of the GoodStuff program make use of each other’s methods: they “command each
other”. The program’s execution happens as the objects message each other and react to
those messages. The presentation below should give you an idea of how this works. Even
though this depiction is visual, it’s consistent with the actual technical implementation
within the GoodStuff project.
Above, object communication was shown as speech bubbles, but it’s possible to express the
same messages as Scala code; see below. Even though these commands aren’t familiar yet,
perhaps you’ll hazard a guess as to which bubble each Scala command matches.
new Experience(name, description, price, rating)
this.experiences += newExperience
if (this.isBetterThan(another)) this else another
this.favorite = newExperience
You’ll learn each command’s precise meaning later.
(The second example of communicating objects, below, is essentially similar to the previous
one. You would do well to study this example, too. However, you may skip it if you’re in a
dreadful hurry or if everything seems crystal clear. It’s forbidden to skip the example
just because you’re lazy.)
Let’s consider an imaginary application program where a student can enroll in courses by
clicking a GUI button associated with the desired course. At this point, the program should
confirm whether the student can be successfully enrolled. Enrollment is successful if there’s
enough space in the lecture hall and if the same student hasn’t already enrolled. Upon
enrollment, the program should record the student in the course’s list of enrollees and update
the student’s list of courses they’re personally enrolled in.
Here’s a sketch of an object-oriented solution:
The states of individual objects form the state of the object-oriented program. In
GoodStuff, the program’s state encompasses the state of a category object (its name,
favorite, and list of recorded experiences) as well as the data associated with each
experience object (descriptions, ratings, and prices).
As an object acts on the messages that it receives, its state sometimes changes, as
does the state of the whole program. Examples: a new experience is added in a category,
a new student is enrolled in a course, a user’s personal information is edited, etc.
The objects of an object-oriented program form a conceptual model that structures the
program so that it makes sense to a human. Each object has a particular role in the
interplay that unfolds within this structure as the program is run. Ultimately, though,
a program run is just a sequence of commands being executed one after the other by the
computer. The programmer defines these commands and attaches them to objects as methods.
Some of the methods cause objects to issue further commands to each other: it’s as if
one object passes the turn to act to another object and waits for the other object to
finish; only a single object is active at a time.
The methods on objects implement small algorithms, which combine to produce the overall
algorithm that accomplishes what the program is meant to do.
Well, to be more exact...
What was just said is a simplification. It’s possible to create
programs where multiple objects work (genuinely or at least
virtually) simultaneously. However, we won’t be covering
concurrency or parallel computing in O1.
If this chapter still seems to be disconnected from the earlier ones, that’s about to
Sending a message to an object activates one of the object’s methods. Sending such a
message is known as calling a method (or invoking a method; metodikutsu). Here,
we call a method named “drive” on a car object:
Some method calls simply request the object to report something about its state, such
as the amount of fuel in the tank. Other calls are more elaborate:
Methods can receive parameters that convey additional information about what the
object is supposed to do. In this example, the amount of fuel is provided as a method
parameter (which is highlighted in yellow):
Different kinds of values can be passed as parameters: numbers, references to other
objects, and so forth.
A method may receive one or more parameters. Or zero, if the message itself says it all,
Often, an object will answer a method call in some way, sending a message to the caller
as a response. We say that the method returns a value. One use for a return value
is to acknowledge an operation’s success or failure:
A method’s return value may also report something about the object’s state:
Assess the following claims based on what this chapter has told you about
object-oriented programming. The answer to every item isn’t directly available
in the text above, but it’s possible to work out each answer from what has been
said. Tick each correct claim.
Think carefully, then take your best guess and read the feedback you receive. It’s
not necessary to get everything right on the first try. This assignment, too, is
intended to be a part of the learning process, not just a test to see what you’ve
What was said above about calling methods, passing parameters to method, and receiving
return values is very similar to what you learned about functions in Week 1. This is of
course not a coincidence. Methods are functions that are associated with objects. They
have access to the object’s data and they take care of things that fall within the
object’s purview. They define what the object can do.
What we’ve called communication between objects is essentially one object’s functions
calling other objects’ functions.
We’re now ready to place the fundamental concepts of object-oriented programming in our
The Scala language gives us the means to define singleton objects (yksittäisolio):
we can write a piece of code that specifies the characteristics of one individual object.
Once we’ve so defined an object, we can issue Scala commands to it.
In the rest of this chapter, you’ll continue to learn object-oriented programming by
commanding some singleton objects that have been already defined for you. In the next
chapter, you’ll get to define objects and methods of your own. (This is much as in Chapters
1.6 to 1.8 where you first used given functions before implementing your own.)
In order to command an object, we need to tell the computer which object we wish to
address and which of its methods we wish to call. That’s precisely what we’ll do in
the next example as we experiment with a particular object:
Let’s use a virtual “parrot”. This parrot object has a particular repertoire of phrases
(strings) that it has learned to “say” and that it recites whenever it “hears” a
familiar-sounding word. We can command the parrot to speak by calling a method named
respond and passing in a phrase that the parrot hears.
Calling the parrot’s respond method. The method’s name is in red,
the parameter in yellow, and the return value in green.
Before we begin using the object, let’s import the contents of o1.objects; we’ll need
them for the rest of this chapter. Our virtual parrot is one of the things defined in
that package, which comes within the IntroOOP project.
import o1.objects._import o1.objects._
Let’s call respond and pass in a string parameter:
parrot.respond("Would you like a cracker?")res0: String = Polly wants a cracker!
Here are four more examples of calling respond on different parameter values:
parrot.respond("Would you like some crackers?")res1: String = Polly wants a cracker!
parrot.respond("So you're called Polly?")res2: String = Polly wants a cracker!
parrot.respond("How are you?")res3: String = How!
parrot.respond("Bye then, I guess.")res4: String = Bye!
What’s important here is for you to see how to command an object, which just happens
to be a particular sort of parrot object. How the parrot has been programmed to pick
its responses is not significant in itself, but it may be easier for you to follow
the rest of the example if you know this much:
Go ahead and experiment with the parrot object. Choose IntroOOP as you launch the REPL
and remember to import.
Our example parrot’s repertoire contains two phrases. One, as you’ve seen, is “Polly
wants a cracker”. Call the parrot’s respond method to find out what the other phrase
is. Hint: mention “rum”.
So far, nothing about our example suggests that an object is anything more than a bunch
of functions that can be accessed via a particular name such as parrot. But there’s
more to an object than that.
In the earlier examples, you saw that an object has data that defines the object’s state.
That state may influence how the object reacts to method calls.
Some of an object’s data can be immutable (e.g., the manufacturer recorded for a car
object) and indeed some objects’ state never changes. However, many objects have methods
that have effects on state. For instance, a method might change a car object’s location
or a bank-account object’s balance.)
Our parrot, too, has a method that affects the parrot’s state by expanding its repertoire:
parrot.respond("Time flies like an arrow")res5: String = Time!
parrot.learnPhrase("Fruit flies like a banana")parrot.respond("Time flies like an arrow")res6: String = Fruit flies like a banana!
The object of the next exercise is a radio. Once again, we recommend that you work along
in the REPL, trying the commands shown below and your own variations of them.
Our radio object represents the tuning interface of an FM radio (for an imaginary,
simplified device). It has four “presets” for quickly accessing particular (virtual)
radio channels. We can switch the radio to a preset station by calling the select
method and passing in a parameter between 1 and 4. Let’s pick preset number two, for
radio.select(2)res7: String = 94,0 MHz: Radio Suomi
As it happens, the radio object has been pre-programmed so that preset number 2 is
94.0 megahertz. The select method returns a string that informs us of the
frequency and the corresponding channel. Other presets produce other frequencies:
radio.select(4)res8: String = 98,5 MHz: Radio Helsinki
The method tune “turns the hertz knob”. That is, it adjusts the frequency from the
current value by a given amount:
radio.tune(2)res9: String = 98,7 MHz: just static
An adjustment’s size is measured in “notches”. For this radio, one notch equals
100 KHz, so the command above increases the frequency by 2 * 100 kHz from what it was.
(There’s no channel at that frequency.)
Notice that the radio object clearly is capable of keeping track of the frequency that
it’s tuned to: it computes a new state for itself from its old state and the parameter
value it receives. This object, too, has a memory.
Our radio object stores information that we can request from it simply by writing
the desired attribute’s name after the dot. Below, we ask for the currently selected
frequency and the radio’s notch size, both of which are integers:
radio.frequencyKHzres10: Int = 98700
radio.notchKHzres11: Int = 100
You don’t need parameters or brackets when accessing these attributes.
The way our radio object has been programmed, we can assign values to some of its attributes.
Instead of calling the methods tune or select, we can set the frequency directly:
radio.frequencyKHz = 92200radio.frequencyKHz: Int = 92200
This is, in effect, a different-looking way to send a message to the object: “Set
your frequencyKHz attribute to the value 92200.”
At the end of Chapter 1.6, we identified functions and variables as abstractions that
make your work as a programmer easier.
Abstraction is also central to objects, in two different ways.
First, each object is an abstraction of some entity that it represents. The programmer
has chosen to represent, in the object, certain aspects of the problem domain, while
leaving out aspects that are less salient.
Second, each object has both an internal implementation and an external “façade” or
interface through which programmers communicate with the object. The interface is an
abstraction of the actual object: it includes the names of methods, the types of
parameters and return values, and any other information that you need to use the object.
The algorithms that implement each method aren’t part of the interface, nor are the
details of how an object keeps track of its state. We’ll return to this important notion
in Chapter 3.1.
This chapter is central our programming efforts in future chapters. With that in mind,
please take the time to view the short presentation below. It frames this chapter’s topic
in a broader context and sets the scene for the chapters to come.
In this chapter, you’ve seen examples of objects defined in Scala, and should now have
a fair idea of how you can command an object whose interface you know. So what next?
Here’s the plan:
someObject.attributeName = newValue
Please note that this section must be completed individually.
Even if you worked on this chapter with a pair, each of you should submit the form separately.
Time spent: (*) Required
Please estimate the total number of minutes you spent on this chapter (reading, assignments,
etc.). You don’t have to be exact, but if you can produce an estimate to within 15 minutes or
half an hour, that would be great.
Written comment or question:
You aren’t required to give written feedback. Nevertheless, please
do ask something, give feedback, or reflect on your learning!
(However, the right place to ask urgent questions about programs
that you’re currently working on isn’t this form but Piazza or the
lab sessions. We can’t guarantee that anyone will even see anything
you type here before the weekly deadline.)
Thousands of students have given feedback that has contributed to this ebook’s design.
Weeks 1 to 13 of the ebook, including the assignments and weekly bulletins, have been
written in Finnish and translated into English by Juha Sorva.
Weeks 14 to 20 are by Otto Seppälä. That part of the ebook isn’t available during the
fall term, but we’ll publish it when it’s time.
The appendices (glossary, Scala reference,
FAQ, etc.) are by Juha Sorva unless otherwise specified on the page.
The automatic assessment of the assignments has been programmed by Riku Autio, Jaakko
Kantojärvi, Teemu Lehtinen, Timi Seppälä, Teemu Sirkiä, and Aleksi Vartiainen.
The illustrations at the top of each chapter, and the similar drawings elsewhere in the
ebook, are the work of Christina Lassheikki.
The animations that detail the execution Scala programs have been designed by Juha Sorva and
Teemu Sirkiä. Teemu Sirkiä and Riku Autio have done the technical implementation, relying on
Teemu’s Jsvee and Kelmu
The other diagrams and interactive presentations in the ebook are by Juha Sorva.
The O1Library software
has been developed by Aleksi Lukkarinen and Juha Sorva. Several of its key components
are built upon Aleksi’s SMCL
The pedagogy of using tools from O1Library (such as Pic) for simple graphical programming
is inspired by the textbooks How to Design Programs by Flatt, Felleisen, Findler, and
Krishnamurthi and Picturing Programs by Stephen Bloch.
The course platform A+ has been created by
Aalto’s LeTech research group and is largely
developed by students. The current lead developer is Jaakko Kantojärvi; many other
students of computer science and information networks are also active on the project.
For O1’s current teaching staff, please see Chapter 1.1.
Additional credits appear at the ends of some chapters.