1 / 51100%
Object Orientation
L E T S TA L K A B O U T T H AT
Where you are
Since you’re in CSE205, you are probably at least familiar with the basic
idea of Object Orientation
Object Orientation is a method by which we model concepts into classes
If there’s one word you probably remember about Object Orientation it’s the
word:
Classes
But this is just the tip of the iceburg
Where are we going?
Our goal is to explore OOP in much more depth
We’re going to establish and understand code, syntax and principles of
good OOP
We’ll be examining
The 4 pillars of OOP
Abstraction
Encapsulation
Inheritance
Polymorphism
OOP Design and Analysis
Whats the point?
Aren’t we just going to spend our careers looking up code on Google?
I mean that’s how I passed CSE110
Surely all we have to do is make something work and get a paycheck!
Let me ask answer your question … with another question …
Question An anecdote from Justin
Selgrad
So … I was programming a game … well I should say I was leading a team to program
a game
My particular expertise at the time was more geared towards AI and our project
needed some
So … when the time came, I coded the A* algorithm myself that would be used in
several parts of the game project
A* is an informed search that is often used for path-finding to find a really-really good
solution but not necessarily the best
My lead programmer came back the next day and told me that the game was tanking
performance… and he thinks it’s the AI code …
I of course decided, “NO! It can’t be, after all, I coded it myself”
After re-testing it … sure enough … it was the AI…
OK – so Google lookup coder …
… What went wrong?!
The answer
In the A* algorithm we use something called a priority queue
A data structure which lines things up according a priority value, in the case of A*
the move that “costs the least”
C# didn’t have a built in priority queue, so I figured I’d use the next best
thing… a Sorted List
A Sorted List does what it says on the box, you can provide criteria for a sort
function that will sort the list
I chose to use the priority value, that is the ‘cost of the move’
C#’s Sorted List uses a Quicksort algorithm
QuickSort is very fast, but has one incredible Achilles’ Heel … sorted data
Since I was sorting nearly sorted data with every single decision point, it was
KILLING the performance of the algorithm
I had to code an entirely new data structure (a Min-Heap) to solve the problem
The answer
So, you might think that question is unfair … and it probably is … sort of …
But it should serve to highlight the core of what I’m trying to get at:
YOU CAN’T ASK GOOGLE ABOUT SOMETHING YOU DON’T KNOW OR
UNDERSTAND IN THE FIRST PLACE
Particularly skilled Google-fu individuals in the room might have been able
to pick apart my anecdote and stumble on the answer or at least a possible
answer, but would they have been able to fix it?
That was a problem that you couldn’t just copy-paste yourself out of
You need to know the algorithms, you need to know the data structures,
you need to know what can go wrong with them
The goal
Our goal is to build up your skills and to make you better problem solvers
CSE110 probably felt like it was a constant fight about syntax, but I’m here to tell
you syntax is just that … syntax
The real core of programming is problem solving
Syntax issues are fixed by repetition – the more you code in a language the more the
language itself will become automatic
But can you use it effectively!?
And the more tools you come to understand the better your problem solving
capabilities become
In my example … if I didn’t understand the Quicksort algorithm, my ability to debug
and fix the problem would have ended right then and there
If I didn’t have the data structures knowledge and understanding, I wouldn’t have been
able to learn a new data structure to fix the problem either
Pillar #1 -
Abstraction
Abstraction
Abstraction is a concept that flows throughout Computer Science
The idea as a whole is “How do I represent something in code?”
This enables the user to think about the software from a higher level
We can also use this to decompose a problem into bite-size chunks
Different programming paradigms talk about abstraction in different contexts:
Procedural Programming
Thinks about abstraction in terms of Functional Decomposition
Our abstraction unit is the reusable module called a function, which is just a segmented part of an
algorithm
We decompose the overarching problem into functions allowing us to solve smaller problems to
solve the larger problem
Functional Programming
Also uses Functions, but wants to raise the ideal to the point of math
Functions become first-class and are reduced to the smallest units possible
Input-Processing-Output
More about that in CSE240
Abstraction and the Real World
Think about a car…
Most of you don’t know how it works
You have ideas like: Engine, Transmission, Gas Tank, Steering Wheel, Gas Pedal,
Breaks, etc.
All of these idea are abstractions
When we think about the car as a collection of abstracts, we can also picture
different configurations of those abstracts that make a different car
Swap the engine
Change the controls
Etc.
OOP and abstraction
Object Orientation allows us to design our code at a different level
OOP can sometimes give us a much more “big picture” view of the
problems we are trying to solve
Kind of like the car – we can think in terms of components and configurations (so
to speak)
As a paradigm, OOP is focused much more on the “what” of programming
over the “how”
That is to say we focus on the data more than on the individual steps
That’s not to say we throw the idea of algorithms out the window, far from it!
OOP just lets us identify the movers and shakers, then figure out how to make
them dance together to solve a problem
The difference
Let’s talk about horses
In a non object oriented system, how would I code a farm with horses on it?
Our simulation would become very state driven
I would probably have variables like:
Number of Horses
Pounds of grain
Bales of hay
Pounds of manure
Etc.
The code would update the farm every cycle and “do stuff” to those variables
based on the number of horses
The difference
Have I actually modelled a horse
though?
Not really … I’ve more modeled
the affects of a horse
I’ve coded something that
simulates a farm and what the
horses might do to it
The horses themselves have no
identity, no agency, etc.
The object oriented approach
In OOP we would look at the problem we are trying to solve and then begin modeling
the concepts of data into individual modules
These modules are called Classes
A class tries to fully describe a concept in the context of our software and provide
means for objects to interact and communicate with eachother
A class is built of two things:
Properties – What describes that thing?
What does it mean to be that thing?
How big is it?
What’s its name?
Etc.
Methods – What can that thing do?
What are the behaviors of the class?
Can it eat?
Can it speak?
Etc.
Horses
Once I’ve described my Horse as a class, I can begin to make Objects
Objects are instances of a class
Each object is unique and has its own set of the properties and methods that the
class describes
Each individual horse is now an object
Each horse can and will perform the behaviors of a horse
Now, I can move my software beyond a simple simulation of the affects of a
horse and into simulating the horse itself
Each horse does its actions, each horse has its own level of agency and if I
want to, I can provide new functionality and make the simulation grow!
OR I can take that horse class and add it to my Farmer Simulator game and
expand on it
Abstraction
In OOP abstraction allows me to think about our software in terms of the
interplay of the classes involved
I can think is terms like:
To make this game, I need:
Player
Enemy
Collision Boxes
A factory to provide collision boxes
Something to manage collision boxes
And more…
Each of those ideas can then become a class which has a role in my
software
Proper Isolation of Responsibility & Knowledge
A class should be self-governing and rely on other classes a little as possible
In OOP we have a principle called Coupling
Loose Coupling – Two classes are not reliant on each-other to exist & function
Tight Coupling – Two classes ARE reliant on each-other to exist & function
Generally we strive for Loose Coupling because that gives us more of the
“ables” we like in OOP
Extensible – we can grow our software while minimizing impact on existing code
Maintainable – Isolated classes are easier to fix and refactor
Reusable – A loosely coupled class can be brought into other projects easily
Tight coupling gives us some advantages sometimes as well
Game Infrastructure – can be very tightly coupled … but when the “machine” runs
well it can be powerful!
BUT all gamers know how hard it can be for developers to patch/fix game code
Proper Isolation of Responsibility & Knowledge
Another idea here is that a class should have a Single Responsibility
AKA the Single Responsibility Principle
AKA “A function should do one thing well … classes edition
I like to refer to this as “Proper Isolation of Responsibility/Knowledge”
I tend to anthropomorphize my code a little and talk about what a class “knows”
The idea here is that a class should be responsible for itself and its small part of the
overall whole in the software and should not take on responsibilities that exist
elsewhere
Does a Deck of Cards know what game its being used in?
Does an individual card know it’s in a deck?
Does an Ace Know it’s worth 1 or 11 in Black Jack?
The answer to all of these is NO!
I can take a deck of cards and play any number of games and even invent new ones
The Ace should not have rules for Blackjack embedded in it
Ace & Blackjack
If the Ace doesn’t know the rules of Blackjack … then … who does?
Classes of Blackjack (classes with ? might not be needed):
Card
Deck
Hand?
Player
Dealer?
Game
The Game class!
The Game class would have the rules of blackjack
Lets talk about
how we talk
about OOP
Part 1 -
Abstraction
T I M E T O S T A R T T H I N K I N G L I K E P R O G R A M M E R S
UML - Unified Modeling Language
It has been said, “A picture is worth a
thousand words”
So to make our communication better,
programmers/software engineers have
embraced several visual methods of
communicating about or programs
One of the major ways we communicate
about OOP and software design is
through UML (Unified Modeling
Language)
UML makes use of specifically design
charts to illustrate the parts of the
program being coded
Once you master the technique, you can
get a LOT of information very quickly from
UML documentation
UML - Unified Modeling Language
UML is a standardized form of communication about software
Consequentially, there is a LOT of different types of diagrams in the full
specification
We’re going to focus on a smaller subset
Basic Class Diagram
WHAT IT IS
Our first important diagram is the
basic Class Diagram
The Class Diagram tells us all
about a single class
It gives information about
properties and methods
SIMPLE EXAMPLE
Basic Class Diagram
C name – a at the top,
bolded
P :
S up as pairs of
data types
M :
E has a name, the parameters a then the r type (if
is listed, it’s void). P , lik pr are
: name a data type
Basic Class Diagram
Understanding the UML allows us
to translate it into code
Even if we don’t know what the
code specifically needs to do, we
can at least build the class
structure from the information:
What are Dollars?
Who knows at the moment, but
we do know we need them
class BankAccount
{
private String owner;
private Dollars balance;
public void deposit(Dollars amount)
{
}
public void withdrawal(Dollars amount)
{
}
}
Basic Class Diagram
There’s a few assumptions in my
class code here aren’t there?
All my properties are private
Why? Because “Data Hiding”
All my methods are public
Why? Because “Interface”
So let’s move on to the next
pillar…
class BankAccount
{
private String owner;
private Dollars balance;
public void deposit(Dollars amount)
{
}
public void withdrawal(Dollars amount)
{
}
}
Pillar #2 -
Encapsulation
W H E R E W E T A L K A B O U T T H E 3 P S
Cars … again…
Most people who drive have no real knowledge of how a car actually works
However, everyone who knows how to drive a car can, generally speaking, sit
down and drive just about any car
Truck, SUV, Go-Kart, etc.
Why is that?
It’s because of the idea of an Interface
Each automobile tends to have the same interface:
Steering wheel
Shifter
Make go fast pedal
Make go slow pedal
Emergency break
These pieces might not be in the same place, but ultimately drivers understand
what they do and can use them
Encapsulation
The idea of encapsulation is often tied to the idea of Black Box
Programming”
You might have heard of that in previous experiences
The idea of a black box is that the user of a module has a strong
understanding of what the black box can do for us
If I put this kind of input in
I get this kind of thing out
The user doesn’t need to know the details of how things work to make use
of them if they are well coded
Thought exercise
I have created a most wondrous of inventions!
If you put a piece of paper on this glass tray and close the lid
Then you push that green button
You can get a nearly perfect duplicate of the piece of paper!
How does it work?!
Well you see, I paid a person of short stature with high artistic skills to get into
the box.
When you put the piece of paper on the glass and press the button a bell is rung
The person in the box shines a light so they can see the document and then
draws a perfect replica as fast as they can!
Then they put the copy in output tray!
Thought exercise
Well … paying the person of small stature got too expensive
And mass production was met with union demands, so I’ve automated the
process!
The person has been replaced with several pieces of equipment that
automate the art making process!
Does the user of this copy machine have to change any of their behaviors?
NO!
The INTERFACE hasn’t changed… the guts of the machine did
The back-end was completely gutted and replaced, but the user making use
of this copy-machine didn’t have to change their process one bit!
Encapsulation
One of the key properties of an object-oriented programming language.
Two views of an object
internal - the details of the variables and methods of the class that defines it
external - the services that an object provides and how the object interacts
with the rest of the system
From the external view, an object is an encapsulated entity, providing a set
of specific services
These services define the interface to the object
1-33
Goals of Encapsulation
That becomes the primary goal of
encapsulation
A class is broken into two major
components:
The Public Interface
The part of the object that a user can
interact with
A series of commands that allows another
programmer to code with and around
objects of the class
The Back-End
The parts of the class that are HIDDEN
from other programmers
When done correctly, the back-end of a
class could theoretically be completely
recoded without introducing errors into
any code making use of the Interface
Encapsulation
One object (called the client) may use another object for the services it
provides
We communicate via the Front End / Public Interface methods
Those methods will return meaningful data/results
The client of an object may request its services (call its methods), but it
should not have to be aware of how those services are accomplished
Classes/methods as “black boxes”
Any changes to the object's state (its variables) should be made by that
object's methods
We should make it difficult, if not impossible, for a client to access an
object’s variables directly
Data hiding
That is, an object should be self-governing
Proper isolation of responsibility and Knowledge 1-35
Visibility
We control all of this with 3 visibility modifiers
Public
Private
Protected
Each of these change how a method or property can be accessed
Sometimes these modifiers have slightly different meanings in different
languages
Technically Java has a 4th visibility modifier, but we’re going to ignore it for
now … it muddles the conversation
Public
When something is public that means it is accessible directly whenever you
have an object of that class
For properties, this means that a property can be directly changed via
outside code (as long as you have access to that object)
For methods, this means that with/through an object you can call that
method and make things happen
The public methods of a class define the Public Interface of that class which
determines how a program can interact with an object
Most of the time we don’t want properties to be accessible, more on that
later
Private
Private means that a property or method is accessible ONLY in the class that
DEFINES the property or method
The emphasis is because this intersects with Pillar #3 – Inheritance
In inheritance – if something is private in a parent class, then it will exist in the
child, but it will not be directly accessible
More on this later…
Private properties and methods are not part of the Public Interface and
therefore cannot be directly invoked or interacted with by the ‘outside’ even
with an object
Information/Data hiding
Sometimes this is put with the abstraction pillar
Data hiding is the base assumption that every piece of data in the class is
to be protected/hidden from the outside
A programmer should rarely just make a property public
Public properties (like global variables) can become unreliable in code.
Since anything can access them
Sometimes the idea of Data Hiding is taken to another extreme in
programming languages that support it by hiding even the data type of a
variable through things like void-pointers and such, leaving the idea of
Information Hiding as described above
Seriously, but why though?
Public properties are
soOoooOoooooo much easier …
why bother with all this
information hiding business?
The short answer:
Because you won’t be coding by
yourself for the rest of your life
and you have to take other
programmers into account
Because it’s GOOD code, not just
working code
This Photo by Unknown Author is licensed under CC BY-NC-ND
The long answer an anecdote
Imagine I want you to sort a deck of cards
You can only handle and sort “size” number of cards though
When you start the process “size” is set to 52 … that is the size of a
standard playing card deck
As you go to process the cards and sort them – I suddenly announce that
“size” is now 30!
How does this affect your ability to sort the 52 card deck?
Wooops, now Size is -2!!
So you can’t sort at all now!
But we’re humans, we can ignore someone at the front of the room
shouting random deck sizes … a computer can’t!
If you make your properties public, this is a scenario that can literally occur!
Protected
Protected offers the same level of protection as Private, but is friendlier for
Inheritance
We will talk more about Protected when we talk about Pillar #3
Chart
This chart helps break down how Public and Private intersect our Properties
and Method
Public variables are unreliable and open ourselves to errors
Public methods are part of the Interface
Private methods allow us to modularize work inside the class
Object Oriented
Coding
Techniques
M A K I N G U S E O F P I L L A R # 1 A N D P I L L A R # 2
Classes
Classes are made of two things
Properties
Methods
They are also structured by two
things
Front End
Public interface
Back End
Private/protected methods that
help functionality
Constructors
One of the more important methods to understand is Constructors
Constructors are the instructions for how to build an object of a class
Constructors are invoked when the new command is issued
Item myItem = new Item();
This calls the constructor
The constructor is usually public and always has no return type
The constructor is always named the same as the class
What does it do for us?
It lets the programmer specify the initial conditions of that particular object
We can set up the properties, call methods, etc. to get the object ready for use!
Constructors Default Constructor
The Default Constructor does not have any parameters
Generally this constructor is programmed to build the object with very
simple default values
If this is not provided, then Java will do a “barebones” default constructor
which sets up the basics of the class and sets properties to the defaults for
those properties
0 for numbers, null/undefined for object references, etc
It’s generally not good to rely on the Java Default Constructor
NOTE: Not every language will do this
C++ will throw errors if a default constructor is not defined
Constructors Parameterized
Constructors
Basically this is what it says on
the box: it’s a constructor with
parameters
These are powerful tools that let
us customize an individual object
on creation!
Constructors in Java can be
overloaded … so feel free to
make as many as needed to
provide a programmer with all the
options they might want to create
an object!
Beware – if you name your
parameters the same as your
properties the “this” reference is
required
Overloading
Overloading is when we provide
alternate definitions for a method
This is accomplished by using the
same method name but providing
different parameterization
Each of the methods can have a
different method body
The parameters is what lets the
compiler know the difference
between them
NOTE – You can only use a particular
set of parameters once
Otherwise the compiler can’t tell
them apart
Overloading in Java
Overloading in Java can be a bit confusing because it allows for quite a bit of overloading
Rules:
Both methods have the same name
Both methods have different parameters
Valid:
If both methods have the same name and different parameters, they may also have different return types
However, return type alone is not enough for overloading.
If they have the same name and same parameters, but different return types… this is an error
If both methods have the same name and different parameters, they may also have different visibility modifiers
However, difference in visibility modifier alone is not sufficient for overloading
Nor is different visibility modifier and return type
They must have different parameters
If both methods have the same name and different parameters, they may also have different throws statements
for unchecked exceptions
But like before … differing throws alone is not sufficient for overload
Nor is any combination of “different throw”, “different visibility” and “different return type”
Boils down to:
The parameterization must be different to “unlock” the other features of Java overloading
Getters and Setters / Accessors and Mutators
Students also viewed