Professional Documents
Culture Documents
Oriented
Programming in Java
Introduction …
• The Java language is (mostly) object-oriented. What exactly does that mean? We will see
shortly. Let’s discuss first how you wrote code last year first.
• Last year, you used Python to write code that embraced what is called a structured-
programming paradigm. Python is capable of OOP, but your learning did not focus on that
aspect of Python. Trying to learn a first programming language and OOP simultaneously
can be overwhelming, and structured programming is where we all begin our journey.
• In structured programming, one uses data structures and program instructions that act on
data.
• Object-oriented languages combine data and program instructions into what are called
objects.
• Instead of having a data structure with fields (attributes) and passing that structure around
to all of the program logic that acts on it (behavior), in an object-oriented language, data
and program logic are combined.
What is it?
Object oriented programming is a model of programing that focuses on objects and the data
associated with the object.
• But what exactly is going on? What does this really do?
• The left side of that equation declares a reference variable named objectVariable of
type ClassName. This is the declaration part of the statement. We are telling the
compiler that we want to create a variable named objectVariable of the Class
ClassName type.
• The right side of the equation is responsible for instantiating an object of type
ClassName. The keyword “new” is used to create a new instance of the class named
ClassName. The Constructor creates an instance of that object.
• Constructors may also be overloaded!
• In some cases, we will declare the object but not instantiate it until “later”. This
approach is like declaring a primitive data type and later assigning a value to it, but NOT
exactly. I did say ”like” didn’t I?
More on Objects
Consider:
• A rectangle is an object and it has a certain state (its dimensions):
Length = 4
Width = 2
• And perhaps that object has a behaviour (the calculation of its area,
or its perimeter):
Area = 8 Perimeter=12
• So, it could be said that all rectangles have a length and a width, and
from that information a rectangles area can be determined.
Classes Are Not Just For School
• Based on that we can create a blueprint of what a rectangle is. You
could say that a rectangle is an individual class of geometric shapes.
• And from that template we can create many different types of
rectangles. 2h=
Lengt = 1
Width
Length =
Rectangle 4
Width = 2
Length
Width
Length = 2
th =2 Width = 4
g 6
Len dth =
Wi
Rectangle Class Creation
• To be able to create this blueprint, or class, that will allow us to create
multiple object we will need some code as follows:
• Pay careful attention to my explanation of the this portion of the
code!!!!
Rectangle
Length
Width
Class Anatomy
If the public or private access modifier is not
• Name the class and open the specified, a field is assumed to be public.
Making fields of a class public as done here
code block. goes against the OOP principle of
• Attributes are variables of the encapsulation. We will fix this shortly.
object when its created.
• A constructor provides
instructions on how an object
is to be created.
Note: Although not seen in this
slide, classes may also contain
methods and more than one
constructor.
Class Instantiation
Now that there is a class for rectangles, we can easily call our class with some
code and create more than one rectangle object with different states:
Obvious, but important to state. Both classes are within the same project, and
only the class TestShape has the main() method. Again, the Rectangle class
does NOT have a main() method!
What now?
• At this point, this is what our project looks like. It doesn’t actually
show any output … yet. Take a moment create these classes and type
the necessary code.
Important Note:
I have fixed the fields length
and width to be deliberately
public. This is not ideal, as
one can access an instance’s
length or width field by using
.length or .width after the
name of the object.
These sort of implementation
details should not be visible to
other methods as it goes
against the OOP principle of
encapsulation!
Lettuce Let us Lettuce J Review
We have learned how to:
• Create a class called Rectangle
• Create instance variables that
serve as the attributes for the
class. For now they are public …
• Create a constructor for the
class, providing instructions on
how an instance of the class
should be instantiated.
• Create an instance of our class.
Running your program at this
point does not produce any
output.
Wait just a second …
• Let’s go back and revisit the signature of methods we wrote when we were
younger back in unit #1. Our methods had the following signature:
• Private means that the method is only available to the class its created in.
• Static means that it can be accessed without creating a separate instance of the
class. Methods that are created within the same class as the main method
MUST be static if they are to be called from the main or other method within
the class containing the main() method.
• Void means that this method does not return a value. If we have a return
value, we must specify its type here instead of void.
A Little More On The Code
So far, our code looks like this:
And if you look at lines 3 and 4
of the Rectangle class, we have
our instance variables length
and width. The variables
belong to the objects we create
and are recreated each time a
new object is instantiated. This
is why they are called INSTANCE
VARIABLES.
rectangleA rectangleB
length=2 length=5
width=4 width=6
A Little More On The Code
Heap
In memory it looks something
like this: Rectangle
length=5
Stack
main() width=6
rectangleB
Rectangle
rectangleA
length=2
width=4
Classes with Methods
Let’s Override the toString() Method
• Every object inherits a toString() method. It provides you with a string
representation of the object as an object name and its hexadecimal
hashcode.
• Usage:
• Using a toString method is automatic behind the scenes so to speak when
applied in a println statement. Assigning an objects String representation to a
string variable requires a toString() method call.
Well that was … useless 🤪
• Don’t fret … we will be overriding the method toString() to make it more
useful.
• Here we have replaced the default toString() that is inherited from the
Object class. This is called overriding. All objects we create will inherit from
the Object class. In fact, we can still call the code from the parent class along
with our new code using the super keyword. This is handy should we also
want the hashcode as well J Usually not.:
Wouldn’t it be fun if we …
• What if we override the default toString() method with the following code:
• Once that happens, they are only accessible from within the object’s
instance.
• How do we permit access to the fields then? Simple. On our own terms!
Quick tangent … but an important one!
• For this demo here, I will go back and set the instance variables to public. Let’s
examine the following code and it’s output.
• Our length field of the first rectangle did not change. Why? Again the
firstRectangle and secondRectangle are reference variables referring to
different locations in memory where their respective field variables are
stored.
• There are after all two different instances of the rectangle object.
Creating Getters (Accessors) and
Setters (Mutators)
• Getters are methods that are written in the class to provide the “outside” world
controlled viewing of private instance variables we wish to expose. Or provide access to
class level variables (more on these in a bit).
• Getters have a return type.
• Setters do not have a return type but must have parameters which are used to set the
values of the private instance variables to.
• This is the OOP principle of encapsulation in action!
What is a setter?
• Setters are methods that are written in the class to provide the
“outside” world access to change private instance or class variables we
choose to expose.
• Keep in mind that the author of the Class may not end up being the
only one that uses the class. Another programmer may use its
functionality.
• This is where the problems begin. What if they inadvertently modify an object’s
fields directly and place it in a bad state.
• They after all may not understand the inner workings of the class (nor do they
need to). It is the job of the original class author to properly encapsulate their
method and protect it from bad data that would put it in an unstable state.
• Here I will place the secondRectangle object which is an instance of the
Rectangle class in a bad state. Any computations performed on the
instance will be invalid, except of course the area.
Setters Continued …
• We can even create more than one setter should we choose.
• The following are the simplest setters for the length and width fields.
• Usage would be within our main method (or other method accessing
the Rectangle class from outside the class):
More Complicated Setters …
• We can also check that the required change to the private variable does not put our
object in an unstable state.
• I will use the throw command which will instantly crash the program.
• One can catch a thrown exception and handle it with other code, but that is another
story which will be told later.
• Not graceful, but it is better that whoever is using your class know immediately that
they have placed an object in an unstable state than to permit program execution to
continue and provide unreliable results.
• This way THEIR code can be fixed to use your class correctly! The code that uses the
class should then be modified so as to not call a setter if it puts the object in an
unstable state.
Thowing things around …
• Main code:
• One implementation:
• Why do they not work? Simple. Remember that the == operator only works
for primitive variable types. Objects are reference types.
• Luckily there is a .equals Method that is inherited from the Object class.
Inherited .equals method
• The inherited .equals method’s usage is shown here:
• These are technically the same rectangle! Let’s adjust the .equals method a wee
bit more to accommodate for this:
• If our metric changes to perimeter, then we will need to change this code so the
respective perimeters are compared.
• For another object say an Employee object, we may choose the employee’s name to
decide on which Employee object is smaller. More on that later.
So far …
Let’s recap.
A class is essentially a blueprint for creating objects.
A class will have attributes, qualities that make it what it is.
These would be the classes instance variables
A class will also have behaviours. Behaviours are the things that it does
These would be the methods that we create within our class.
When we instantiate a new object we create an instance of that class
with its own attributes and behaviours defined by its class.
Diagramming Classes with UML
• Programmers will often draw class
diagrams to illustrate the relationship
among the classes that make up their
program(s).
• The diagram on the right shows four
classes, and the relationship between
those classes.
Diagramming Classes with UML
• Programmers use a diagramming standard called UML, which stands for Unified Modeling Language.
• A UML diagram helps programmers organize the programming design process in a way that clients,
analysts and other programmers can understand and agree on. The following are a list of just some of he
benefits of using UML:
• Your software system is professionally designed and documented before it is coded. You will know exactly what you
are getting, in advance.
• Since system design comes first, reusable code is easily spotted and coded with the highest efficiency. You will have
lower development costs.
• Logic 'holes' can be spotted in the design drawings. Your software will behave as you expect it to. There are fewer
surprises.
• The overall system design will dictate the way the software is developed. The right decisions are made before you are
married to poorly written code. Again, your overall costs will be less.
• UML lets us see the big picture. We can develop more memory and processor efficient systems.
• When we come back to make modifications to your system, it is much easier to work on a system that has UML
documentation. Much less 'relearning' takes place. Your system maintenance costs will be lower.
• If you should find the need to work with another developer, the UML diagrams will allow them to get up to speed
quickly in your custom system. Think of it as a schematic to a radio. How could a tech fix it without it?
• If we need to communicate with outside contractors or even your own programmers, it is much more efficient.
Drawing Classes
• The basic element in a class diagram is a class. In UML, each class is drawn
as a rectangle.
• At the very least, the rectangle must include the class name. It can also be
subdivided into two or three sections that can contain additional information
about the class (i.e. field variables, constructors, methods, etc.). The following
class diagram includes the class name, variables and methods
Drawing Classes Continued …
• In class diagrams, the fields are denoted as:
variableName: variableType
• The constructors are denoted as:
ClassName(parameterName: parameterType)
• The methods are denoted as:
methodName(parameterName: parameterType): returnType
• The idea here is that these are language independent yet provide just enough information to see the general
structure of the class.
• The name of each variable or method can be preceded by a visibility indicator. The following are a list of the
visibility indicators for class variables and methods
- Private Makes methods and data fields accessible only from within its own class.
# Protected Can be accessed by any class in the same package or its subclasses
Practice drawing a UML Class Diagram:
• Draw UML diagrams for the following two classes we have done as a
class:
• Rectangle
• User
Let’s Code it Together
• We have just gone and repeated ourselves! We have just gone and
repeated ourselves! We have just gone and repeated ourselves … Instead
code things like this. Here I have created a
constructor with no
parameters. This could
be handy if you want to
create Rectangle objects
and don’t know the
dimensions just yet. One
can set them later with
appropriate setters.
Things are about
to get …
Compli-mi-kated!
Why oh why?
• Suppose we have a class SomeItem with instance variables:
• username (String), age (int) and accountBalance (double)
• We have implemented a second class called SomeItems which will allow us to store an almost limitless
number of SomeItem instances within an array called itemsArray that resizes as needed.
• Within our Main class with our main method (or other classes for that matter), we cannot and MUST
NOT access the itemsArray directly as this breaks two of the fundamental principles of OOP – abstraction
and encapsulation.
• The internal complexity of that class is not and should not be of concern, nor should we simply allow
another coder to go and monkey around with things. We want controlled access to our Class.
• Put simply, you MUST NOT directly allow for the coding like the following from outside the class
SomeItems as this can cause catastrophic results of epic proportions should those using your class do so
incorrectly. We are talking cosmic level catastrophe here!
• We must instead provide controlled access to our internal data structure that is used.
So how do I do it then? But how ??
• Two solutions that exist. Either we can mirror every getter/setter from our SomeItem class with
an additional parameter as to which target in our SomeItems class like this:
• Then use only using getters and setters like these to control access to the internal workings of
the SomeItems class.
• Easy enough to implement but there are a few drawbacks - first it violate the DRY principle as
you could imagine the mess that would result if the SomeItem class had numerous instance
variables.
• This approach bloats our SomeItems class with repeated logic making code less maintainable.
There is a slicker and more powerful way …
• This method involves the chaining of method calls but we must be
careful here that any link within the chain cannot cause an exception.
• We start by adding a method to our SomeItems class that returns the
instance within the itemsArray we are searching for as shown here:
https://onlinegdb.com/l_16JiJTA
Now the main part …
• Within our Main class, should we want to access accountBalance instance
variable belonging to our good friend Cookie Monster, we use:
• But be careful, you could get into trouble if you chain things that could
cause an exception …
https://onlinegdb.com/6p8bXERhv
Lettuce examine …
• Go back to the current Donut project … the following code should
make more sense …
Persons instance (implements an array of type Person)
Person instance
• Access modifiers (public, private, protected, etc.) still apply to static fields and their
accessor/mutator methods.
• It is a good practice to encapsulate static fields by making them private and
providing public getter and setter methods if needed.
• Using static methods for static fields makes the code more consistent and clearer. It
signals to other developers that the method is associated with the class rather than
with a specific instance.
Using a static field within a class
• Pay careful attention to how the constructors are constructed! Do you see now why they all call one constructor? Why? So that we
have centralized error checking of fields using our setters, and now we have an accurate count of our instances.
• Pay careful attention to lines 28, line 29, line 32and 35 in the SuperHero class!
https://onlinegdb.com/PJMCcSE4i
Inheritance in
Action …
Inheritance …
• Inheritance is a fundamental principle of OOP that allows a class (called a subclass) to inherit the fields and
methods of another class (called the superclass).
• In Java, a subclass can only inherit from one direct superclass (one parent). Class C cannot inherit from
Class A and Class B. Other Object-Oriented Programming languages may permit this, but not Java.
Class B
Class C
Inheritance supported by Java
• Why? Simple. Suppose Class A and Class B both have a field with the exact same name
but different data type? Or identically named methods that operate on different
parameter types or return values and behave differently. Which does Class C use? This is
why Java does not permit this.
Inheritance …
• A subclass can of have multiple subclasses of its own.
• The subclass is created using the class keyword, followed by the name of the subclass and the extends
keyword followed by the name of the superclass. The subclass inherits the fields and methods of the
superclass. The subclass can also have its own additional fields and methods.
• A subclass can only extend ONE superclass.
• The super keyword is used in the subclass to refer to the members of the superclass. This is particularly
useful when the subclass has overridden a method from the superclass and wants to call the overridden
method.
• When a subclass is instantiated, the constructor of the superclass is also called. This ensures that the fields
of the superclass are properly initialized. If the superclass doesn't have a default constructor, the subclass
constructor must explicitly call one of the constructors of the superclass using super()
• Yes, this also applies to Class level variables (static) that apply to the entire class!
Quick Demo of Inheritance
• Remember our Rectangle Class? Let’s extend that class. Let’s create another
class and call it square. 😱
• This is … a thing of beauty. Watch this J I didn’t code any of those methods I
use here. They are inherited!
Inheritance in action …
• Does that mean that any methods I wrote in the parent Rectangle
class, I can call on a square? Yes. But there is a slight problem. Let me
show you.
https://onlinegdb.com/AvBv9yJ6u
Some Practice
• A cylinder can be thought of as a circle with height. Let’s setup the necessary
classes. Let’s setup build an OOP solution to this.
• Create a base class called Circle with private double field radius. Create a constructor
which creates an instance of that object. Create public setters and getters for the field,
an equals method, and a toString() method. Create getters for area, and circumference.
• Create a subclass called cylinder which extends the base class Circle and has a field
height. Ensure that your constructor uses the constructor of the parent class as shown in
previous examples. Create a getter and setter for the height, surface area and a volume
methods. Your surface area and volume methods should use the parent class’s area
method. Override the toString() method and equals method of the parent class as well
within the child class. The metric for equality should be radii and heights are equal.
• Create a subclass called cone which extends the cylinder class. All getters and setters
including the constructors should be from one of the parent classes. The only child
methods are the constructor which uses the parent constructor (cylinder) and the
surface area and volume. These two should also use the parent classes respective
methods.
• Create a new class called Square, a child class called SquareBasedPrism.
Implement the necessary methods for area, volume. Create a child class for
square based prism called SquareBasedPyramid.
S’more Practice
• Create a parent class called Pet. What fields
should we add?
• Create three child classes Dog, Cat and Fish
each with their specific own specific fields for
those animals. J. What fields should they
have? Be creative here.
• Write a method speak() for the parent which
returns a String “this animal does not speak”.
Override the speak method in each of the
child classes to return the string ”Woof woof”
and “Meow … meow!”.
• Write code to test your classes. That includes
creating an array of each of them J
Ready for your mind to be blown?
• In Java, you can create an array of the superclass (Employee) and then
instantiate objects of the subclass (SalariedEmployee and HourlyEmployee) and
store them in the array. This is possible due to polymorphism, where objects of a
subclass can be treated as objects of their superclass.
• This way, you can have an array that can store objects of both the
SalariedEmployee and HourlyEmployee classes, treating them as instances of
their common superclass Employee.
• Look at the following code implemented here: https://onlinegdb.com/-Jjn8bEdl
• There are some drawbacks and a few issues with the employee number but
nothing that can’t be “fixed” if refactored. Perhaps removing the employee
number altogether from the Employee class and creating an Employees class
that manages the Employee objects ?? But the focus here is really that we flex
polymorphism here!
• Problem … how do we know what type of object we have within our array?
Simple. We use the instanceof operator. Let me show you:
https://onlinegdb.com/MVd_ioWeR-
Cookie Stone Returns …
Remember our simulated battle between Cookie Monster and Thanos for the Cookie
stone? Yup. I went there! Let’s examine what I have done …
VS.
https://onlinegdb.com/GC0Bph9Ocd