CS-202 Introduction to Object Oriented Programming California State University, Los Angeles Computer Science Department
Lecture I: Objects and Classes
Procedural Programming vs. Object Oriented Programming
Procedural Programming ❂
A series of computational steps to be carried out.
❂
Any method might be called at any point during a program's execution (even by other methods)
❂
A list or set of instructions telling a computer what to do step-by-step and how to perform from the first code to the second
❂
Generally has a top-down, chronological ordering
Object Oriented Programming ❂
❂
OOP is VERY different from Procedural −
requires a shift in thinking
−
requires a different way to look at programming problems
Instead of thinking in "steps" to a solution, you need to think about and identify the objects involved in the problem −
what objects should I use?
−
what information do I need to know about the objects?
−
how do I want the objects to behave?
−
how should the objects interact with one another?
Objects and Classes
Objects ❂
An object is an instance of a class, and represents a "real world" entity. −
Tangible Objects: ✦ ✦
−
objects you can physically touch Examples: house, car, fan, etc...
Non-tangible Objects: ✦ ✦ ✦
objects you can't physically touch can be harder to identify Examples: BankAccount, Insurance, Loan, Vacation, etc...
States and Behaviors ❂
state(s) of an object: −
a.k.a. properties, attributes, data fields, member variables, instance variables
−
all the information you want to store about the object.
−
characteristics of the object
−
Example: A Circle object with a data field radius
−
Example: A Rectangle object with data fields width and height.
States and Behaviors ❂
behavior(s) of an object: −
a.k.a the actions of an object
−
all actions defined by the methods of the object
−
whenever you invoke (call) an object's method, you are asking the object to perform some action
−
Example: Circle objects could have methods getArea(), getPerimeter(), setRadius(radius)
Examples Object Person
Customer
BankAccount
States Behaviors name, age, gender, get the address, phone number change the phone number, get the name, etc. name, address, make purchase, purchase history list items bought, return item owner, balance, withdraw, deposit, account number transfer, get balances
Classes ❂
❂
❂
Objects of the same type are all defined using a common class. −
All Circle objects would be defined using a Circle class.
−
All Dvd objects would be defined using a Dvd class.
Think of a class like a template, blueprint, or contract. −
defines what an object's data fields and methods will be.
−
The data fields (variables) define the state of the objects.
−
The methods define the behavior of the objects
Classes also provide special methods called constructors which are called to construct or create instances of objects from the class template.
Relationship Between Objects and Classes ❂
An object is an instance of a class.
❂
A class is defined once (in the source code file) −
You can create many objects or instances of that class.
−
The terms object and instance are interchangeable.
−
Example: I can have five Circles in my program each created using the Circle Class or template.
❂
Creating an instance of a class is called instantiation.
❂
A good analogy is the relationship between food and its recipe: −
the recipe to make a cheesecake (yummy!) defines how to create the cheesecake.
−
each cheesecake you make using that recipe is an "instance" of that recipe.
An Object Oriented Example
Object Oriented Example ❂
See Code: −
Circle.java
−
CircleTester.java
❂
This program constructs three circle objects with radius 1, 25, and 125.
❂
The program then displays the radius and area of each of the three circles.
❂
The radius of the second object is changed to 100 and then the new radius and area are displayed.
CircleTester.java ❂
Things to notice: −
The main class (CircleTester.java) whose only purpose is to test the second class (Circle.java)
−
Can also be referred to as the client. ✦
−
Example: Since CircleTester.java uses the Circle class, we say that CircleTester is a client of Circle
This main class has the main method which is required to execute the program.
Circle.java ❂
Things to notice: −
It does not have a main method and will not run (execute)
−
It is simply a definition for any Circle objects created using the class.
−
This class can now be used by another other number of programs which want to use a circle and its properties.
Putting it All Together ❂
Program has two classes now instead of one: −
Circle.java defines the object we want to use.
−
CircleTester.java contains the main method and is tests our Circle class. ✦
These classes are sometimes called drivers, testers, or main.
❂
Object oriented programs are generally made up of multiple objects and one main / driver / tester which starts the program execution.
❂
NOTE: You can put both classes in the same file, but only one class can be a public class. The public class must also be the same name as the file name. However, it is better to keep each class in a separate file.
Putting it All Together ❂
Each class in the source code is compiled into a .class file
❂
When you compile CircleTester.java, two class files (CircleTester.class and Circle.class) are generated.
Putting it All Together ❂
Each instance (object) of the class retains its own data. −
Each Circle object is independent of the other
−
Changing the data in one object will not affect the data in another. ✦
❂
An exception to this rule will be discussed later on.
You can access the data fields in one of two ways: −
Directly (only if the data is public) i.e. circle1.radius;
−
Through the getRadius() method i.e. circle1.getRadius();
−
The second way is the preferred method since all of your data should generally be private (as we will see later on).
Another Example – The TV Class
❂
See Examples: TV.java and TestTV.java
Constructors
Constructors ❂
❂
special kinds of methods with three properties: −
same name as the class
−
NO return type – not even void
−
they are invoked using the new operator
Used to create an instance of a class and initialize the data fields of the object. −
Syntax: ClassName variableName = new ClassName(arguments);
−
Example: Circle circle1 = new Circle(25);
Constructors ❂
Constructors can be overloaded just like regular methods.
❂
Should generally be public (private constructors do exists, but it's rare and usually they are just used by another constructor to help initialize the data fields.
❂
It is very common to do something like the following: public void Circle() { } −
this would not be correct since constructors cannot have a return type.
−
adding a return type turns this into a method not a constructor
Private Constructors ❂
Most of the time constructors should be public.
❂
In rare cases, you may want to prevent a user from creating an instance of a class.
❂
This can be accomplished using a private constructor
❂
Example: there is no reason to create an instance of the Math class since all of its data fields and methods are static. The Math class has the following constructor to prevent instantiating the class: private Math() { }
No-Arg Constructor ❂
Every class should provide a constructor without any arguments.
❂
e.g. Circle()
❂
Usually used to create instances of the class with default values for each of the data fields.
The Default Constructor ❂
Under certain conditions, the compiler automatically provides a no-arg constructor called the Default Constructor.
❂
Rules:
❂
−
if you define a class without any constructors, the compiler will automatically provide a public no-arg constructor with an empty body.
−
if your class defines even one other constructor, the compiler will NOT provide the default constructor even if the no-arg constructor was not defined.
NOTE: The Default Constructor IS a no-arg constructor, the only difference is if the compiler provides a no-arg constructor it is called the default constructor.
Reference Variables
Reference Variables ❂
objects in memory are accessed via reference variables. −
contain a reference to the object (memory location of the object)
−
declared using the following syntax: ClassName objectRefVar;
❂
classes are reference types −
a variable of the class type can reference an instance of the class. Circle myCircle; myCircle = new Circle(arguments);
❂
Can also be defined all on one line: ClassName objectRefVar = new ClassName(arguments); Circle myCircle = new Circle();
Accessing an Object's Data and Methods ❂
Data can be accessed using the dot operator . (a.k.a. the object member access operator)
❂
objectRefVar.dataField references a (public) data field in the object. −
❂
e.g. myCircle.radius
objectRefVar.method(arguments) invokes a method on the object −
e.g. myCircle.getArea()
❂
radius is known as an instance variable since it is dependent on a specific instance of the class
❂
getArea() is an instance method because you invoke it only on a specific instance −
object on which an instance method is invoked is the calling object
A Word of Caution ❂
❂
Recall that you use: −
Math.methodName(arguments)
−
e.g., Math.pow(3, 2)
−
to invoke a method in the Math class.
Can you invoke getArea() using Circle.getArea()? −
The answer is no.
−
Some methods you saw before were static methods, which are defined using the static keyword.
−
getArea() is non-static and must be invoked through an object ✦ objectRefVar.methodName(arguments) ✦ e.g. myCircle.getArea()
Primitive Types vs Reference Types ❂
Remember primitive types: −
byte, short, int, long, float, double, boolean, char
❂
Every variable represents a memory location that holds a value
❂
When you declare a variable, you are telling the compiler the type of value the variable can hold
❂
For a variable of a primitive type, the value is of the primitive type
❂
For a variable of a reference type, the value is a reference to where an object is located. −
NOTE: NOT a value but a reference (technically a memory address) to where the object is located.
Primitive Types vs Reference Types
Primitive Type Assignment Statements ❂
When you assign one primitive type variable to another primitive type variable, the other variable is set to the same value.
❂
The value is copied from one to the other.
❂
Note: Changes to the value of i will NOT change the value of j and vice versa.
Reference Type Assignment Statements ❂
For a variable of the reference type, the reference of one variable is assigned to the other variable.
❂
Note: Changes to the object c1 will also change the object c2
Garbage Collection ❂
As shown in the previous figure, after the assignment statement c1 = c2, c1 points to the same object referenced by c2.
❂
The object previously referenced by c1 is no longer referenced.
❂
This object is now known as garbage.
garbage is something that is taking up memory, but has no reference pointing to it. − the object is useless and cannot be used at all ❂ Garbage is automatically collected by JVM and the memory that the garbage object was occupying is freed up. −
−
this is known as garbage collection
Data Fields
Data Fields ❂
All the data related to an object is stored in its data fields
❂
Data fields are listed at the top of the class file
❂
Data fields can be any type:
❂
−
primitive data types
−
array data types
−
even other Object data types
Data fields have an access modifier: −
public
−
private (generally all data fields should be private)
−
protected
❂
Data fields can be static or non static
❂
Data fields usually have default values: −
defaults can be set where the data field is declared
−
defaults can also be set in the Constructors of the object.
Scope of Data Fields ❂
Reminder: the scope of a variable is where a variable is visible / can be used in a program. scope always starts from where a variable is declared and ends at the closing curly brace } of the block which contains the variable − a block could be a method, if / else, loop, or even a class block. −
❂
The scope of instance and static data fields is the entire class. −
They can be declared anywhere inside a class.
−
normally they are declared at the top of the class
−
The exception is when a data field is initialized based on a reference to another data field ✦
In this case, the other data field must be declared first
Scope Example public class Circle{ public double getArea(){ return radius*radius*Math.PI; } private double radius=1; } public class Foo { private int i; private int j=i+1; }
Data Field Examples ❂
Circle.java −
❂
double radius
TV.java −
int channel
−
int volumeLevel
−
boolean on
Reference Data Fields and null Values ❂
Data fields can be reference types
❂
Example: the following Student class contains a data field name of the String type public class Student { String name; //default value null int age; //default value 0 boolean scienceMajor; //default value false char gender; //default value '\u0000' }
❂
If a reference type data field is not initialized its value is a special literal value, null.
Data Field Default Values ❂
The default value of a data field is: −
null for a reference types
−
0 or 0.0 for numeric types
−
false for a boolean types
−
'\u0000' for a char type
public class Test { public static void main(String[] args) { Student student = new Student(); System.out.println("name? " + student.name); System.out.println("age? " + student.age); System.out.println("isScienceMajor? " + student.isScienceMajor); System.out.println("gender? " + student.gender); } }
Local Variables and Default Values ❂
❂
Reminder: local variables are variables defined inside of a method and are local to that method. −
NOT NOT NOT the same as data fields.
−
they only exist as long as the method is executing
Unlike data fields, Java DOES NOT assign default values to local variables.
public class Test { public static void main(String[] args) { int x; //no default value String y; //no default value System.out.println("x is " + x); System.out.println("y is " + y); } } Compilation error: variables not initialized
Class Methods
Class Methods ❂
Classes can have all sorts of other methods which perform operations on the data fields of the class.
❂
If a method doesn't do ANYTHING to or with the data fields of a class, it more than likely doesn't belong there.
❂
Methods can return any types, or be void
❂
Methods will be made up of all the techniques you have used so far: −
variables and calculations
−
if / else statements
−
loops
−
maybe call other methods
−
use other Classes or even instances of the same class.
Static Variables, Constants, and Methods
Static Variables ❂
❂
Instance variables −
An instance variable is a data field which is tied to a specific instance of the class.
−
It is NOT shared among objects of the same class
Example: the data field radius in the Circle class Circle c1 = new Circle(); Circle c2 = new Circle(); c1.radius; c2.radius;
❂
The value of radius in c1 is independent of the value of radius in c2
Static Variables ❂
❂
Static variables −
Also called class variables
−
Store values for the variables in a common memory location
−
Shared by all objects of the same class
−
All objects of the same class are affected if one object changes the value of a static variable
Accessing static variables: −
Syntax: ClassName.staticVariable
−
Example: Math.PI
Class Constants ❂
Constants in a class are shared by all objects.
❂
Thus, constants should be declared final static
❂
Eg: the constant PI in the Math class is defined as: final static double PI = 3.14159265358979323846
Static Methods ❂
❂
Static methods −
are not tied to a specific instance of object.
−
are NOT allowed to access instance data fields or instance methods
−
can ONLY access static data fields or static methods
Declaration of static variables and methods −
❂
Use the modifier static
Calling static methods −
Syntax: ClassName.methodName(arguments)
−
Example: Math.abs(-7)
−
Non static variables CANNOT be used in Static methods.
Example: Circle with Static
❂
static variables and methods are indicated in a UML diagram by underlining them
❂
Code Examples: −
Circle.java
−
CircleTester.java
Static Tip ❂
To improve the readability of your program Use ClassName.methodName(arguments) to invoke a static method − Use ClassName.staticVariable to access a static variable −
❂
Another programmer can easily recognize the static method and data in the class
Static vs. Instance Method Data Access ❂
The following tables summarizes what static and instance methods can access invoke instance methods static methods instance methods
invoke access static instance methods data fields
access static data fields
Static Method Imports ❂
Static variables and methods can be directly imported from a class
❂
The imported data and methods can be referenced or called without specifying a class
❂
For example: import static java.lan.Math.* −
You can use PI instead of Math.PI and random() instead of Math.random()
Deciding on Static or Instance ❂
❂
How does on decide to use a static or an instance method or variable? −
a variable or method that depends on a specific instance of a class should be an instance variable or method
−
a variable or method that does not depend on a specific instance of a class should be a static variable or method
Example: −
every circle has its own radius, so radius should be an instance variable.
−
every circle has its own area so the getArea() method should be an instance method.
−
None of the methods in the Math class depend on a specific instance of that class, so all of these methods are static
−
The main method never depends on a specific instance of a class and it is also static.
Packages and Access (Visibility) Modifiers
Packages ❂
Packages are used to organize classes
❂
To include a class in a package, add the following line as the first non-comment and non-blank statement in the program – package packageName;
❂
If a class is declared without the package statement, the class is placed in the default package
Access (Visibility) Modifiers ❂
access modifiers a.k.a. visibility modifiers specify how data fields and methods in a class can be accessed from outside of the class −
public ✦
−
private ✦
−
The class, data fields, or methods are accessible only from within their own class
protected ✦
✦
−
The class, data fields, or method is accessible from any class in any package
The class, data fields, or methods are accessible by anything in the same package. This is the default option if no access modifier is specified
no visibility modifier: ✦
this is also called package-private or package-access, and classes methods and data fields are accessible by any class in the same package.
Packages
Packages
Packages
Data Field Encapsulation
Data Field Encapsulation ❂
Data fields in a class could be declared public.
❂
If the data fields are public, then you can directly access the data fields through a reference variable.
❂
Example 1: If radius was public we could do the following Circle c1 = new Circle(); c1.radius = 5;
❂
Example 2: If numberOfObjects was public Circle.numberOfObjects = 10;
Data Field Encapsulation ❂
This is very bad practice: –
data can be tampered with ●
–
numberOfObjects is supposed to count the total number of objects created, but if the data field is public, then the user could directly modify the value, mistakenly or otherwise which could throw the correct object count off.
the class is also more difficult to maintain and vulnerable to bugs. ●
●
suppose you want to modify Circle to make sure the radius is nonnegative after other programs have already used the class. not only do you have to change Circle, but you would also have to change any programs which have used the class because the clients may have directly modified the radius.
Data Field Encapsulation ❂
❂
To prevent direct modification of data fields, you should declare them to be private. –
this is called data field encapsulation
–
if a data field is private, then it can only be accessed directly within its own class
How do you modify / retrieve the information stored in a private data field? –
you provide getter and setter methods.
Getter / Accessor Methods ❂
getter methods a.k.a. accessor methods −
methods created specifically to retrieve the data in private data fields data fields.
−
the convention is to have the following method header: public returnType getPropertyName()
−
getters with a boolean return type should have the following method header: public boolean isPropertyName()
−
generally you will have one getter per data field whose data you want to make "visible".
Setter / Mutator Methods ❂
private data fields −
❂
Cannot (and should not) be accessed directly by instances of the class
setter methods a.k.a. mutator methods −
methods created specifically to allow data fields to be altered in a way that is defined in the method.
−
gives you control over how the data of an object can be altered
−
the convention is to have the following method header: public void setPropertyName(datatype propertyValue)
setters should normally not return any values generally have one setter per data field you want to allow to be changed ✦
−
Example ❂
Here is a new Circle class with proper encapsulation
Objects and Methods
Passing Objects to Methods ❂
Objects can be passed to methods in the same way that primitive types can be passed to methods.
❂
Primitive types are passed using pass-by-value
❂
❂
−
the value of the argument is copied into the parameter
−
changes to the value inside the method do not change the value outside the method
Object / Reference types are passed using pass-by-reference −
the reference that the object argument are passed into the parameter
−
changes to the object inside the method WILL change the object outside the method as well
Code Examples: −
TestPassObject.java
Passing Objects to Methods – Stack and Heap
❂
Remember the stack is used to allocate memory for methods and local variables.
❂
Objects are created in an area of memory called the heap
The this Reference
The this Reference ❂
this is a built in keyword which always refers to the (calling object) object itself
❂
it can only be used inside of a Class definition.
Using this To Access Hidden Data Fields ❂
Sometimes the parameter of a setter (or constructor) is the same name as the data field whose value it is trying to replace.
❂
In this case we say the data field is "hidden" within the scope of the method or constructor.
❂
The only way to refer to this data field is using the this keyword
❂
"hidden" static data fields can be accessed by using Classname.staticVariableName
❂
Best coding practice dictates that you should ALWAYS use this in your class when you are referring to any data fields or methods.
Using this To Access Hidden Data Fields
Using this to Invoke a Constructor
Using this To Invoke a Constructor
The toString() Method
toString() ❂
Suppose to want to display a textual representation of your object. –
❂
Suppose you want to be able to print out the reference variables of your objects much like you would normal variables –
❂
usually contains the values of its member data formatted in a way to look good on the console or GUI output
using System.out.print() or System.out.println()
Every Class has a toString() method by default. –
Every class is a sub class of the Object class
–
Every class inherits a simple toString() method from its parent Object class (inheritance which we will cover later)
–
However, this version of toString() tends to print meaningless information about our object.
toString() ❂
❂
We can implement our own version of toString() by replacing the implementation of the original version –
this is called overriding a method
–
this is different from overloading a method
The method header of toString() should ALWAYS be: public String toString()
❂
–
method header must exactly match the above
–
cannot have any parameters
–
must always return a String
Once this has been implemented, you can now use normal Java print statements to print out a textual representation of your object. –
toString() is automatically called whenever you print a reference variable of your object.