23
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 library classes - 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’ program which 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 is not 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 (ditto above) 1. Making a deposit 2. Making a withdrawal 3. Calculating interest 1

main driver runnable

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: main driver runnable

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

Page 2: main driver runnable

Java Classes: Class Definition Syntax

• Syntax:

• While technically, instance variables and methods are optional, without them a classwouldn’t make much sense

2

Page 3: main driver runnable

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

Page 4: main driver runnable

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

Page 5: main driver runnable

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

Page 6: main driver runnable

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

Page 7: main driver runnable

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

Page 8: main driver runnable

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

Page 9: main driver runnable

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

Page 10: main driver runnable

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

Page 11: main driver runnable

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

Page 12: main driver runnable

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

Page 13: main driver runnable

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

Page 14: main driver runnable

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

Page 15: main driver runnable

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

Page 16: main driver runnable

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

Page 17: main driver runnable

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

Page 18: main driver runnable

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

Page 19: main driver runnable

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

Page 20: main driver runnable

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

Page 21: main driver runnable

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

Page 22: main driver runnable

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

Page 23: main driver runnable

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