Lesson 1 Udacity OOP
Lesson 1 Udacity OOP
Fields
The fields of an object are all the data variables that make up that object. They are also
sometimes referred to as attributes or member variables.
These fields are usually made up of primitive types like integers or characters, but they
can also be objects themselves.
For example a book object may contain fields like title , author and numberOfPages .
Then a library object may contain a field named books that will store all book objects
in an array.
Accessing fields:
Accessing a field in an object is done using the dot modifier ‘.’
For example, if we had an object called book that contains these fields:
String title;
String author;
int numberOfPages;
To access the title field you would use
book.title
This expression is just like any other string, which means you can either store it in a
string variable:
String myBookTitle = book.title;
Or use it directly as a string itself and perform operations like printing it:
System.out.println(book.title);
Setting Fields
You can also change a field’s value. Say you want to set the number of pages in a book
to 234 pages:
book.numOfPages = 234;
Methods
You might have also noticed that running actions in objects look very much like calling a
function. That’s because that’s exactly what it is.
Methods in Java are functions that belong to a particular object. When we get to creating
our own object types later in this lesson we will be creating methods the same way we used
to created functions.
Calling a method
To use a method you call it (just like calling a function). This is also done using the dot
modifier .
Methods, just like any function can also take in arguments. For Example: Assume that our
book object has a method called setBookmark that takes the page number as a parameter:
void setBookmark(int pageNum);
If you wanted to set a bookmark at page 12, you can call the method and pass in the page
number as an argument:
book.setBookmark(12);
Summary
Fields and Methods together are what make an object useful, fields store the object's data
while methods perform actions to use or modify those data.
However some objects might have no fields and are just made up of a bunch of methods
that perform various actions.
Other objects might only have fields that act as a way to organize storing data but not
include any methods!
Next Step
Now that we’ve seen how to use objects and access their fields as well as call their
methods, let’s set up your computer so you can start using objects straight away.
Classes and Objects are two different terms and should not be used interchangeably, they
can sometimes seem like they both refer to the same thing but each has a different
meaning.
Here's a comparison that illustrates when to use which:
Class Object
Book lordOfTheRings
Pokemon pikachu
Strings
You've probably already noticed that (unlike all primitive types) Strings start with an upper
case 'S'! That's because a String is in fact a class and not a primitive type
A String variable is made up of an array of characters ( char [] ) as its field, but being an
object means that it also offers some powerful methods like length() that counts and
returns the number of characters in that array, and equals(String s) that compares the
characters in this string with another string.
Everything is an object in Java
Because Java is an OOP language, it includes classes that simply wrap around all the
primitive types themselves to offer some extra functionality through their methods:
Integer int
Long long
Double double
Character char
String char[]
Each of those classes is made up of the corresponding primitive type as its field, but usually
also comes with some powerful methods.
It also allows you to forget about primitive types and treat everything in Java as an object.
However, it is still recommended to use primitive types when writing a simple piece of code.
A good Java program is one that divides the logic appropriately so that each class ends
up containing everything related to that class, and nothing more!
Classes would be calling each other's methods and updating their fields to make up the
logic of the entire program all together!
BUT, where should the program start from exactly? In other words, if a method can call
another method and that method can call another, which method will start this sequence
the very first time?
Inside it you can create objects and call methods to run other parts of your code. And
then when the main method ends the program terminates.
If this main method doesn't exist, or if there's more than one, the Java program won't be
able to run at all!
The main method can belong to any class, or you can create a specific class just for
that main method which is what most people do.
Creating a constructor
Creating a constructor is very much like creating a method, except that:
Default constructor
A Default constructor is one that doesn't take any input parameters at all!
It's optional, which means if you don't create a default constructor, Java will
automatically assume there's one by default that doesn't really do anything.
However, if the class has fields that need to be initialized before the object can be used,
then you should create one that does so.
For example, assume we have a class Game that has an integer member field score ,
we'd like to make sure that any object of type Game will start with the score value set
to 0 . To do so, we need to create a default constructor that will initialize the mScore field
class Game{
int mScore;
// Default constructor
Game(){
// Initialize the score here
mScore = 0;
}
}
Parameterized constructor
As we've mentioned earlier, a constructor can also take input parameters.
Let's assume that some games start with a positive score value and not just 0 , that
means we need another constructor that takes an integer parameter as an input, and
uses that to initialize the score variable.
class Game{
int score;
// Default constructor
Game(){
score = 0;
}
// Constructor by starting score value
Game(int startingScore){
score = startingScore;
}
}
Accessing a constructor
Unlike normal methods, constructors cannot be called using the dot . modifier, instead,
every time you create an object variable of a class type the appropriate constructor is
called. Let's see how:
The new keyword
To create an object of a certain class, you will need to use the new keyword followed by
the constructor you want to use, for example:
Game tetris = new Game();
This will create an object called tetris using the default constructor (i.e. tetris will have
an initial score value of 0)
To create a game that is initialized with a different starting score you can use the
second constructor:
Game darts = new Game(501);
The null keyword
If you do not initialize an object using the new keyword then its value will be set to
something called null . null simply refers to an empty (uninitialized)
object. null objects have no fields or methods, and if you try to access a null object's
field or call its method you will get a runtime error.
In some cases, you might want to explicitly set an object to null to indicate that such
object is invalid or yet to be set. You can do so using the assignment operation:
Game darts = null;
However, this privilege goes away once you create any constructor of your own! Which
means if you create a parameterized constructor and want to also have a default
constructor, you will have to create that default constructor yourself as well.
EXAMPLE
We'll start by creating a class that's responsible for storing all contact information of a single
person, it will look something like this:
class Contact{
String name;
String email;
String phoneNumber;
}
All fields, no methods, since a contact object itself won't be "doing" much actions itself in the
scope of this program, it's merely a slightly more advanced data type that can store a few
strings in 1 variable.
Note: Noticed how we used a String to store the phone number instead of using int ! Can
you think of a reason why?
QUIZ QUESTION
Why is it a good idea to use a String variable to store a phone number than
using an integer:
(There may be more than 1 correct answer)
•
Because you can't compare integers
• Because phone numbers start with 0's and integers can't store leading 0's
• Because the largest integer is smaller than a typical phone number
•
Because a String requires less memory than an integer
SUBMIT
Next, let's create the class that will be in charge of adding and searching for contacts. Since
it will be managing all the contacts, I'll call it ContactsManager :
class ContactsManager {
}
This class will be storing the contacts in an array, which means one of its fields will be an
array of Contacts, another field will be an int representing the number of friends added to
the array, this int will help us know where in the array was the last contact added so we
can continue to add more contacts into the array later as we will see.
This is what the class will look like after adding the fields
class ContactsManager {
// Fields:
Contact [] myFriends;
int friendsCount;
}
Okay, now let's create a default constructor that will initialize those fields.
class ContactsManager {
// Fields:
Contact [] myFriends;
int friendsCount;
// Constructor:
ContactsManager(){
this.friendsCount = 0;
this.myFriends = new Contact[500];
}
}
The friendsCount starts from 0 and will increment every time we add a new contact later.
The Contact array myFriends (just like any array) needs to be initialized using
the new keyword and we chose to reserve enough space in the array to store up to 500
contacts.
Next, let's start adding methods to the ContactsManager class that allows adding and
searching for contacts in the array.
NEXT
// Constructor:
ContactsManager(){
friendsCount = 0;
myFriends = new Contact[500];
}
// Methods:
void addContact(Contact contact){
myFriends[friendsCount] = contact;
friendsCount++;
}
Later on in this course, we will see how to read input from the user to make this
program more powerful.
But sometimes you need to have fields that can be modified by other classes.
For example, if we wanted to keep track of whether a Book is being borrowed or not, you
can add a public boolean field to do so:
public class Book{
private String title;
private String author;
public boolean isBorrowed;
public Book(String title, String author){
this.title = title;
this.author = author;
}
}
This will work, since you will be able to do something like this from anywhere in your project:
book.isBorrowed = true;
However, it's still slightly risky, and you could end up mistakingly setting the boolean to true
when you only meant to check if it was true or false!
A better design would be to declare that field as private and then create public methods that
return the value of such hidden field (known as getters) as well as public methods that
provide a way to set or change its value (known as setters)
public class Book{
private String title;
private String author;
private boolean isBorrowed;
public Book(String title, String author){
this.title = title;
this.author = author;
}
public void borrowBook(){
isBorrowed = true;
}
public void returnBook(){
isBorrowed = false;
}
public boolean isBookBorrowed(){
return isBorrowed;
}
}
Setting the isBorrowed field as private will prevent you from mistakenly changing its value
somewhere in the code, because the only way to change it now is to call
either borrowBook() or returnBook() which is much more explicit.
And to be able to read the value of isBorrowed , we've created a getter method
called isBookBorrowed() that is public and simply returns the value of isBorrowed
Summary
• Always try to declare all fields as private
• Create a constructor that accepts those private fields as inputs
• Create a public method that sets each private field, this way you will know when you are
changing a field. These methods are called setters
• Create a public method that returns each private field, so you can read the value without
mistakingly changing it. These methods are called getters