Post on 07-Jun-2022
Java Classes: Intro
• Basic concepts of classes were presented earlier in the Java Reference Types notes
– You should review them prior to continuing
• Up to this point in time, the programs you have written - while using Java libraryclasses - have not been object-oriented
– Rather, they have been imperative, along the lines of a C program
• We now turn our attention to OOP
• A typical Java program consists of several classes, one of which is the ’main’ programwhich contains a main method
– This class is sometimes called the driver
– A Java program that includes such a driver is called runnable
• Here we will look at writing classes that represent program components
• Consider a program that involves bank accounts - specifically a savings account
– Remember: classes are defined in terms of features/characteristics and behav-iors/actions
– Features of a savings account that we might want to represent could be (this isnot meant to be all-inclusive)
1. The account number
2. The balance
3. Interest associated with the account
– Behaviors of a savings account that we might want to represent could be (dittoabove)
1. Making a deposit
2. Making a withdrawal
3. Calculating interest
1
Java Classes: Class Definition Syntax
• Syntax:
• While technically, instance variables and methods are optional, without them a classwouldn’t make much sense
2
Java Classes: Instance Variables
• Remember: A class’s instance variables and methods are referred to as its members
– In the case of instance variables, they are a class’s data members
• They represent the characteristics of objects that belong to a class
• Instance vars represent variables whose values are specific to a particular instance ofthe class (i.e., a specific object)
• Instance variables are declared and initialized just like any other variables we’vediscussed up to this point
– Syntax:
– Modifiers will be discussed later
3
Java Classes: Member Methods
• Methods implement a class’s behaviors
• Everything you already know about methods applies to member methods
• Syntax (repeated from Methods notes):
• One difference between member methods and those we’ve been using to this point:
– Member methods do not use the static modifier (more on this later)
4
Java Classes: A First Example
• This example illustrates the encoding of data and method members for the savingsaccount class outlined previously
class SavingsAccount {
int accountNumber;
double balance;
double interestRate;
void deposit (double amt)
{
balance = balance + amt;
}
void withdraw (double amt)
{
if (amt <= balance)
balance = balance - amt;
}
double calculateInterest ()
{
double interestAccrued;
interestAccrued = interestRate * balance;
balance = balance + interestAccrued;
return interestAccrued;
}
}
• Note that this class does not have a main method
– This means that this class is not runnable
• Note that the methods are not static
• The name of this class should be SavingsAccount.java
5
Java Classes: A First Example (2)
• To compile the class from the command line, simple usejavac SavingsAccount.java
• If you’re using Eclipse, it will be compiled automatically when you save it
• The compiled result will be named SavingsAccount.class
• Since the class is not runnable, you would access it from a runnable class; for example:
class Tst {
public static void main (String[] args) {
SavingsAccount sa1;
SavingsAccount sa2;
sa1 = new SavingsAccount();
sa2 = new SavingsAccount();
sa1.deposit(50.0);
sa2.deposit(75.0);
sa1.withdraw(9.50);
sa2.withdraw(14.32);
System.out.print("Account 1 balance: ");
System.out.println(sa1.balance);
System.out.print("Account 2 balance: ");
System.out.println(sa2.balance);
}
}
• Note that two SavingsAccount instances are created: sa1 and sa2
• Each of these instances has its own copy of the three instance variables (balance,accountNumber, and interestRate)
• Each instance also has its own copy of the member methods
6
Java Classes: A First Example (3)
• To access an instance’s members, we use the dot notation (fully qualified notation)we’ve been using all along for things like Scanner methods
• THIS IS ABOUT AS FAR AS THE TEXT GOES WITH CLASSESBUT THERE IS SO MUCH MORE
7
Java Classes: Access Modifiers
• One of the guiding principles of Java is encapsulation and information hiding
– Encapsulation means that the inner workings of a class are packaged together asa unit (the class itself, and ultimately the individual instances of the class)
∗ We’ve seen this in the above example
– Information hiding means that code that creates objects of a class should onlybe able to access those aspects of the class that enables the code to use instanceseffectively and safely
∗ Code that uses instances of a class is sometimes called a client
∗ This aspect is managed by access (visibility) modifiers
• In the above example, notice how the balance was accessed from within main
– Given this accessibility, if you wanted to arbitrarily add $1,000,000 to sa1’s bal-ance, you could just add the code
sa1.balance = sa1.balance + 1000000.0;
– This isn’t a good situation - it would be better if you could limit what a clientprogram could access
• Access modifiers control which members can be accessed by clients
• Java provides 3 access modifiers:
1. public
– Allows a client free access
2. private
– Allows access only from within the class
3. protected
– This will not be addressed
• Note: If omit visibility modifier, default is public
• What should be private?
– Generally, all instance variables and any methods that are not required by clients
• What should be public?
– Generally, methods that are needed by clients to initiate behaviors
8
Java Classes: Access Modifiers (2)
• The following enhances the above example with access modifiers:
public class SavingsAccount {
private int accountNumber;
private double balance;
private double interestRate;
public void deposit (double amt)
{
balance = balance + amt;
}
public void withdraw (double amt)
{
if (amt <= balance)
balance = balance - amt;
}
public double calculateInterest ()
{
double interestAccrued;
interestAccrued = interestRate * balance;
balance = balance + interestAccrued;
return interestAccrued;
}
}
– If you were to compile the above program now, there would be errors in the driverprogram:
the field SavingsAccount.sa1 is not visible
the field SavingsAccount.sa2 is not visible
9
Java Classes: Accessors and Mutators
• If a class’s instance variables are private, how could a client program ever makechanges to them or determine what their values are?
– The answer is accessor and mutator methods, also known as getters and setters
• Accessor
– Method that returns the value of an object’s instance variable
– Usually named getX, where X is the name of the instance variable
• Mutator
– Method that changes the value of an object’s instance variable
– Often named setX
• Accessors and mutators are public methods, which means a client can call them
• What is the advantage to this approach?
– We only provide accessor methods for those instance variables that we want aclient to be able to see
∗ Others remain invisible to the client
– We only provide mutator methods for those instance variables that we want aclient to be able to change
∗ The client can only change the value of an instance variable if a mutator isprovided for that variable
∗ The mutator method controls how the client is able to make changes - itimposes limitations
∗ Therefore, the client cannot cannot make unrestricted changes to instancevariables
10
Java Classes: Accessors and Mutators (2)
• The following enhances the above example with accessors and mutators:
public class SavingsAccount {
private int accountNumber;
private double balance;
private double interestRate;
public void setAccountNumber (int i)
{
accountNumber = i;
}
public int getAccountNumber ()
{
return accountNumber;
}
public double getBalance ()
{
return balance;
}
public void deposit (double amt)
{
balance = balance + amt;
}
public void withdraw (double amt)
{
if (amt <= balance)
balance = balance - amt;
}
public double calculateInterest ()
{
double interestAccrued;
interestAccrued = interestRate * balance;
balance = balance + interestAccrued;
return interestAccrued;
}
}
11
Java Classes: Accessors and Mutators (3)
class tst {
public static void main (String[] args) {
SavingsAccount sa1;
SavingsAccount sa2;
sa1 = new SavingsAccount();
sa2 = new SavingsAccount();
sa1.setAccountNumber(1003);
sa2.setAccountNumber(1895);
sa1.deposit(50.0);
sa2.deposit(75.0);
sa1.withdraw(9.50);
sa2.withdraw(14.32);
System.out.print("The balance of account " + sa1.getAccountNumber() + " is: ");
System.out.println(sa1.getBalance());
System.out.print("The balance of account " + sa2.getAccountNumber() + " is: ");
System.out.println(sa2.getBalance());
}
}
• In the example,
– getAccountNumber() and getBalance() are accessors
– setAccountNumber(), deposit() and withdraw() are mutators
• Note that the only way a client program can change the value of balance is throughthe two mutator methods
• Note that the code within the class (e.g., the bodies of any of the methods) does notneed to use qualified references to the members; just the member name is sufficient
12
Java Classes: this
• Suppose we were to rewrite the setAccountNumber() method as follows:
public void setAccountNumber (int accountNumber)
{
accountNumber = ???;
}
which is commonly done, since accountNumber is a more meaningful parameter namethan i
• The problem is, we have two different versions of accountNumber:
– The parameter, which is local to the method
– And the instance variable
– Any use of accountNumber from within the method refers to the local parameter
• this is an identifier that refers to an object itself
– So within object sa1, this refers to object sa1, and within object sa2, this refersto object sa2
• If we rewrite setAccountNumber() as
public void setAccountNumber (int accountNumber)
{
this.accountNumber = accountNumber;
}
the instance variable will be assigned the value of the parameter
13
Java Classes: Constructors
• A constructor is a method that creates an instance of a class
– We’ve seen their use many times over; e.g.,
Scanner keyboard = new Scanner(System.in);
sa1 = new SavingsAccount();
• An important task of a constructor is to initialize instance variables
– Could use a mutator, but they allow setting of variables multiple times
– Initialization is usually intended to occur one time only
– By performing initialization from within the constructor, will only happen once- when object created
• Every class must have at least one constructor, but if you look at the above example,there is no code within class SavingsAccount that seems to create new SavingsAccountobjects
• Default constructors
– If your code does not provide a constructor, Java automatically supplies one foryou
– The default constructor takes no parameters
– It will create a new instance when called, and will initialize all instance variablesto ’zero’ values: zero for numerics, false for booleans, null for references
• User-created constructors
– Frequently, you may want to create your own constructors
– Syntax:
14
Java Classes: Constructors (2)
∗ Note that the syntax is the same as for regular methods except
· No return type
· class name must be the name of the class
– An important point to note: If the programmer provides a constructor, Java willNOT create a default
∗ In that case, it is strongly recommended that the programmer explicitly pro-vide a default constructor
– Constructors must be the first method definitions in your class definition
• You may have as many constructors as you wish
– The only restriction is the one that applies to any set of overloaded methods:
They must have different signatures
15
Java Classes: Constructors (3)
• The following enhances the above example with constructors:
public class SavingsAccount {
private int accountNumber;
private double balance;
private double interestRate;
//Default constructor
public SavingsAccount ()
{
accountNumber = 0;
balance = 0.0;
interestRate = 0.03;
}
public SavingsAccount (double balance, double intRate)
{
this.balance = balance;
interestRate = intRate;
accountNumber = 0;
}
public SavingsAccount (double balance)
{
this.balance = balance;
accountNumber = 0;
interestRate = 0.03;
}
public void setAccountNumber (int accountNumber)
{
this.accountNumber = accountNumber;
}
public int getAccountNumber ()
{
return accountNumber;
}
public double getBalance ()
{
return balance;
}
public void deposit (double amt)
{
balance = balance + amt;
}
public void withdraw (double amt)
{
if (amt <= balance)
balance = balance - amt;
}
public double calculateInterest ()
{
double interestAccrued;
interestAccrued = interestRate * balance;
balance = balance + interestAccrued;
return interestAccrued;
}
}
16
Java Classes: Constructors (4)
class tst {
public static void main (String[] args) {
SavingsAccount sa1;
SavingsAccount sa2;
SavingsAccount sa3;
sa1 = new SavingsAccount();
sa2 = new SavingsAccount(500);
sa3 = new SavingsAccount(100, 0.05);
sa2.setAccountNumber(1895);
sa3.setAccountNumber(765);
sa1.deposit(50.0);
sa2.deposit(75.0);
sa3.withdraw(20.0);
System.out.print("The balance of account " + sa1.getAccountNumber() + " is: ");
System.out.println(sa1.getBalance());
System.out.print("The balance of account " + sa2.getAccountNumber() + " is: ");
System.out.println(sa2.getBalance());
System.out.print("The balance of account " + sa3.getAccountNumber() + " is: ");
System.out.println(sa3.getBalance());
}
}
• The above includes three constructors
– Note that they have different signatures
– The first is the default constructor, which must be supplied (if we want a default)since there are other constructor definitions
– The other two initialize various instance variables via parameters
– Other constructors are possible
17
Java Classes: UML Class Diagrams
• UML (Unified Modeling Language) diagrams - also known as class diagrams - are agraphical way of representing a class
• It consists of three sections:
1. Class name
2. Instance variables
– Syntax:
– Note that this isn’t the syntax for a variable declaration in Java
3. Methods
– Syntax for constructors:
– Note that this is essentially the signature of the method, and again isn’t thesyntax for a method declaration in Java
– Method parameter names may be included (not indicated in the diagram)
– Syntax for regular methods:
• The plus and minus represent access modifiers:
– Plus for public
– Minus for private
18
Java Classes: UML Class Diagrams (2)
• The UML for class SavingsAccount is
SavingsAccount
- accountNumber: int- balance: double- interestRate: double
+ SavingsAccount ()+ SavingsAccount (double, double)+ SavingsAccount (double)+ setAccountNumber (int): void+ getAccountNumber (): int+ getBalance (): double+ deposit (double): void+ withdraw (double): void+ calculateInterest (): void
19
Java Classes: Use of Classes
• Methods can take objects as parameters and return them as return values
– For example, we could have a method that accepts SavingsAccount objects asparameters:
void myMethod (SavingsAccount acct)
{
...
}
and in main we might have
SavingsAccount sa1 = new SavingsAccount(500.0);
...
myMethod(sa1);
∗ This would result in the following memory diagram:
∗ Note that both variable sa1 and parameter acct point to the same object
20
Java Classes: Use of Classes (2)
– The following illustrates a method that returns an object
SavingsAccount myMethod2 ()
{
SavingsAccount acct = new SavingsAccount();
...
return acct;
}
and in main we might have
SavingsAccount sa1;
...
sa1 = myMethod2();
∗ On execution, a pointer to the object created in myMethod2() will be assignedto variable sa1
• Arrays of objects
– Arrays of objects can be a bit tricky
– The key thing to remember is that - while an array variable represents a set ofvalues - each element of an array is essentially a single variable
– Suppose we wanted to create an array of SavingsAccount objects
∗ To declare the array:
SavingsAccount acctList[];
21
Java Classes: Use of Classes (3)
∗ To allocate the array:
acctList = new SavingsAccount[4];
· This allocates ten storage locations for the array, but it does not createSavingsAccount objects!
· We must explicitly create them in the normal fashion
· Generally, a loop will be used:
for (int i = 0; i < 4 ;i++)
acctList[i] = new SavingsAccount();
· Note that here, we create SavingsAccount objects
· Above, we create a SavingsAccount array
· The following shows the corresponding memory diagrams
– Each array element refers to an individual object
∗ Accessing members of these objects uses an array reference in the same wayyou would use a variable:
x = acctList[2].getBalance();
22
Java Classes: Designing a Class
• When designing a class, you need to determine the following:
1. What are the instance variables?
– These will be the values that describe/differentiate instances of the class
2. What are the methods?
– These are the behaviors of the class - what actions it can perform
– Provide get methods for retrieving instance variables
– Provide set methods for modifying instance variables
3. What are the values of the visibility modifiers?
– Data members should be private
– Constructors, accessors, and mutators should be public
– Methods that are only used within the class itself should be private
• The principle of least privilege states that a class should provide the minimal ac-cess/methods sufficient to use that class as intended
23