Lecture 8 - It works!

carenextSoftware and s/w Development

Nov 18, 2013 (3 years and 4 months ago)

58 views

Chapter 8

Objects & Classes

Definition of Object
-
Oriented Programming (OOP)

Object
-
Oriented

Programming

(OOP)

uses

the

analogy

of

real

objects

as

a

template

for

creating

computer

programs

involving

those

objects
.


For

example,

we

all

know

what

a

circle

is
.

A

circle

can

be

defined

by

its

radius

and

the

location

of

its

center
.

A

circle

has

an

area

that

is

strictly

a

function

of

its

radius
.


We

can

create

a

class

that

defines

a

circle
.

For

now

we

will

not

concern

ourselves

with

position
.

















It

is

important

to

note

that

a

class

is

not

a

program
.

There

is

no

main

method
.

A

class

is

used

by

an

executable

program
.

class

Circle

{


double

radius;




Circle(
double

rad)


{


radius = rad;


}




double

getArea
()


{


return

radius*radius*
Math.PI
;


}

}

this is called a
constructor

of

the Circle class. It has the same

name as the class and it must

define all properties of the class

this is a
property

or
attribute

of the Circle class

this is an
action

or
method

of

the Circle class

Constructors

class

Circle

{


double

radius;




Circle(
double

rad)


{


radius = rad;


}




double

getArea
()


{


return

radius*radius*
Math.PI
;


}

}

Constructors are a special kind of method that initialize objects. Constructors have
the following characteristics:



A constructor must have the same name as its class.


Constructors do not have a return type, or void.


Constructors are invoked using the new operator.

Reference Variables and Reference Types

Circle
myCircle
;


myCircle

=
new

Circle();






Circle
myCircle

=
new

Circle();

A
class

is similar to a user
-
defined
type


myCircle

is declared as a
Circle

type. At this point
myCircle

is a
reference to objects of type
Circle
.


We can also create an
instance

of
the
Circle

class by using
new
.

Accessing an Object’s Data and Methods

After an object is created, its data can be accessed and its methods invoked using
the
dot
operator

(
.
),
also known as the
object member access
operator.

myCircle.radius



myCircle.getArea
()

returns the radius of
myCircle

as a
double



c
omputes and returns the
area

of
myCircle

public

class

objtest1

{


public

static

void

main(String[]
args
)


{


Weasel
myWeasel

=
null
;


a
Weasel

=
new
Weasel(1,2,10.4);



if
(
myWeasel

==
null
)


System.out.println
(
"Yes"
);


else


System.out.println
(
"No"
);


}

}


class

Weasel

{


int

color;


int

age;


double

weight;




Weasel(
int

col,
int

a,
double

w)


{


color = col;


age = a;


weight = w;


}

}

Pointing to Nowhere (null)

myWeasel

null

Weasel

c
olor:
int

= 1

age:
int

= 2

weight: double = 10.4

aWeasel

Weasel myWeasel = null;

Weasel myWeasel = new Weasel(1,2,10.4);

class

test

{


public

static

void

main(String[]
args
)


{


Student
a_student

=
new

Student();


System.out.println
(
"name = "

+ a_student.name);


System.out.println
(
"age = "

+
a_student.age
);


System.out.println
(
"gender = "

+
a_student.gender
);


}

}


class

Student

{


String name;


int

age;


boolean

isScienceMajor
;


char

gender;

}

Reference Types can Point to Null

name
= null

age
= 0

gender
=
00

Unified Modeling Language (UML) Diagrams

The

illustration

of

class

templates

and

objects

in

Figure

8
.
2

can

be

standardized

using

UML

(Unified

Modeling

Language)

notations
.

This

notation

is

called

a

UML

class

diagram,

or

simply

a

class

diagram
.















In

the

class

diagram,

the

data

field

is

denoted

a
s

dataFieldName
:

dataFieldType


The
constructor

is denoted as ClassName(parameterName: parameterType)


The
method

is denoted as methodName(parameterName: parameterType): returnType

Instance vs Static Methods

We

have

used

several

of

the

methods

provided

in

the

Math

class

in

our

programs
.

These

methods

are

invoked

by

calling

the

class

name

followed

by

the

method

using

dot

notation
.

For

example
:




Y

=

Math
.
sqrt(X)
;


rnd

=

Math
.
random()
;


maxval

=

Math
.
max(Math
.
max(a,b),Math
.
max(c,d))
;


More

recently

we

have

been

creating

instances

of

classes

and

then

accessing

the

attributes

and

methods

of

the

object

class

using

the

same

dot

notation
.

For

example
:



Circle

circ

=

new

Circle(
10
.
0
)
;


System
.
out
.
println("A

circle

of

radius

"

+

circ
.
radius

+


"

has

an

area

=

"

+

circ
.
getArea())
;


It

is

important

to

note

that

in

the

first

case

we

cannot

create

an

instance

of

the

Math

class

and

in

the

second

we

access

the

methods

and

attributes

only

through

an

instance

of

the

class
.


The

methods

in

the

Math

class

are

referred

to

as

static

methods

while

those

in

an

instance

class

are

called

instance

methods
.

An Example: The Card Deck

Problem
:

Build

a

model

of

a

deck

of

playing

cards

that

can

be

used

in

a

Java

program
.


We

can

define

a

card

object

in

an

instance

class

as

part

of

a

model

for

a

deck

of

cards
.

While

many

of

the

details

of

the

Card

class

will

depend

on

what

we

want

to

do

with

the

card

deck,

there

are

a

few

important

attributes

common

to

most

card
-
playing

applications
.



suit

-

Hearts,

Clubs,

Diamonds,

Spades



rank

-

Ace,

2
,

3
,

4
,

5
,

6
,

7
,

8
,

9
,

10
,

Jack,

Queen,

King



value

-

1
,

2
,

3
,

4
,

5
,

6
,

7
,

8
,

9
,

10

public

class

Card

{


String suit;


String rank;


int

value;




Card(String s, String r,
int

v)


{


suit = s;


rank = r;


value = v;


}

}

Card constructor

To

create

instances

of

the

52

cards

in

a

deck

of

playing

cards

using

the

Card

class,

we

need

to

specify

the

suit

and

the

rank

of

each

card
.

We

could

do

this

by

simply

writing

52

declarations,

each

one

explicitly

giving

the

string

names

for

suit

and

rank
.






This

would

be

a

lot

of

work

and

we

would

have

52

variables

that

would

be

difficult

to

use

in

a

program
.

Alternatively

we

could

generate

an

indexed

list

of

Card

type

objects
.



This

creates

a

list

of

52

references

to

Card

types

but

it

doesn't

create

instances

of

cards
.

We

will

still

have

to

declare

each

of

them

separately
.

However,

this

time

we

can

use

a

for
-
loop

to

save

ourselves

a

lot

of

typing
.

Card card_1 =
new

Card("Heart","Ace",1);

Card card_2 =
new

Card("Heart","2",2);


:

Card card_51 =
new

Card("Spade","Queen",10);

Card card_52 =
new

Card("Spade","King",10);







Card[] card =
new

Card[52];

Generating the Cards

A Bit of Computer Science

In order to avoid generating 52 separate declarations, we need a way to specify the
suit and rank of each card in a for
-
loop. The loop index will range from 0 to 51. We
can use this value to generate a suit number (0
-
3) and a rank number (1
-
13).


We can generate all the cards of the same suit first or all cards of the same rank first.
In each case we can use integer division and modulo to convert the loop index into a
suit number and a rank number.

int suitnum, ranknum;


for(
int

i = 0; i<52; i++)

{


suitnum = i/13;


ranknum = i%13 + 1;

}

int suitnum, ranknum;


for(
int

i = 0; i<52; i++)

{


ranknum = i/4 + 1;


suitnum = i%4;

}


i suitnum ranknum


0 0 1


1 0 2


2 0 3


:

50 3 12

51 3 13


i suitnum ranknum


0 0 1


1 1 1


2 2 1


:

50 2 13

51 3 13

Converting Numbers to Strings

The constructor for the Card class needs strings for the name of the suit and the rank.
We can use conditional statements that choose the strings based on the values of the
suit number and the rank number.

switch

(suitnum)

{


case

0:


suit =
"Club"
;


break
;


case

1:


suit =
"Spade"
;


break
;


case

2:


suit =
"Heart"
;


break
;


case

3:


suit =
"Diamond"
;


break
;

}

if
(ranknum==1)


rank =
"Ace"
;

if
(ranknum>1 & ranknum<10)


rank = Character.toString((
char
)(ranknum + 48));

if
(ranknum == 10)


rank =
"10"
;

if
(ranknum == 11)


rank =
"Jack"
;

if
(ranknum == 12)


rank =
"Queen"
;

if
(ranknum == 13)


rank =
"King"
;

value = 10;

if
(ranknum<=9)


value = ranknum;

deck[i] =
new

Card(suit,rank,value);

public

class

Deck

{


String suit =
""
;


String rank =
""
;


int

suitnum, ranknum, value;


Card[] card =
new

Card[52];


int

topcard;




Deck()


{


topcard = 0;


for
(
int

i = 0;i<card.length;i++)


{


suitnum = i%4;


ranknum = i/4 + 1;




value = 10;


if
(ranknum<=9)


value = ranknum;




switch

(suitnum)


{


case

0:


suit =
"Club"
;


break
;


case

1:


suit =
"Spade"
;


break
;


case

2:


suit =
"Heart"
;


break
;


case

3:


suit =
"Diamond"
;


break
;


}


if
(ranknum==1)


rank =
"Ace"
;


if
(ranknum>1 & ranknum<10)


rank = Character.toString((
char
)(ranknum + 48));


if
(ranknum == 10)


rank =
"10"
;


if
(ranknum == 11)


rank =
"Jack"
;


if
(ranknum == 12)


rank =
"Queen"
;


if
(ranknum == 13)


rank =
"King"
;



card[i] =
new

Card(suit,rank,value);


}


}




public

void

shuffle()


{


Card tmpcard;


topcard = 0;


for
(
int

i=0;i<1000;i++)


{


int

k,m;


k = (
int
)(Math.random()*52.0);


m = (
int
)(Math.random()*52.0);


tmpcard = card[k];


card[k] = card[m];


card[m] = tmpcard;


}


}




public

Card dealCard()


{


Card the_card;


the_card = card[topcard];


if
(topcard<51)


topcard += 1;


return

the_card;


}

}

We

have

written

several

programs

using

classes,

most

of

which

leave

the

data

value

types

as

public
.



There

are

times

which

we

do

not

want

to

allow

direct

access

to

the

data

values

inside

a

class
.

In

these

cases

we

can

simply

declare

them

a

private
.


If

we

wish

to

permit

limited

access

to

them

we

can

include

accessors

in

the

class
.


If

we

wish

to

allow

the

user

of

the

class

to

see

the

value

we

create

a

get

accessor
.

If

we

also

want

to

allow

the

class

user

to

change

the

value

we

create

a

set

accessor
.

public

class

Circle3

{


private

double

radius = 1;


private

static

int

numberOfObjects = 0;



public

Circle3()


{


numberOfObjects++;


}


public

Circle3(
double

newRadius)


{


radius = newRadius;


numberOfObjects++;


}



public

double

getRadius(
double

newRadius)


{


return

radius;


}


public

void

setRadius(
double

newRadius)


{


if
(radius>=0)


radius = newRadius;


else


radius = 0.0;


}



public

static

int

getNumberOfObjects()


{


return

numberOfObjects;


}


public

double

getArea()


{


return

radius * radius * Math.PI;


}

}

Data Encapsulation

public

class

TestCircle3

{


public

static

void

main(String[] args)


{


Circle3 Circ =
new

Circle3(5.0);


System.out.println(
"The area of the circle of radius "

+ Circ.getRadius() +
" is "

+ Circ.getArea());



Circ.setRadius(myCircle.getRadius() * 1.1);


System.out.println(
"The area of the circle of radius "

+ Circ.getRadius() +
" is "

+ Circ.getArea());



System.out.println(
"The number of objects created is "

+ Circle3.getNumberOfObjects());


}

}

Testing the Circle3 Class

The

data

field

radius

is

declared

private
.

Private

data

can

be

accessed

only

within

their

defining

class
.

You

cannot

use

Circ
.
radius

in

the

client

program
.

A

compile

error

would

occur

if

you

attempted

to

access

private

data

from

a

client
.


Since

numberOfObjects

is

private,

it

cannot

be

modified
.

This

prevents

tampering
.

For

example,

the

user

cannot

set

numberOfObjects

to

100
.

The

only

way

to

make

it

100

is

to

create

100

objects

of

the

Circle
3

class
.

public

class

Deck

{


String suit =
""
;


String rank =
""
;


int

suitnum, ranknum, value;



Card[] card =
new

Card[52];



int

topcard;


:


:


Deck()


{


topcard = 0;


for
(
int

i = 0;i<card.length;i++)


{


suitnum = i%4;


ranknum = i/4 + 1;


:


:


card[i] =
new

Card(suit,rank,value);

}

Array of Objects

Declaration of an array of objects











Initialization of the array of objects

Sometimes

it

is

convenient

to

create

an

array

of

objects
.

The

declaration

of

the

array

creates

an

array

of

reference

types

but

does

not

instantiate

any

of

the

objects
.

This

is

done

in

a

separate

statement

calling

the

class

constructor
.