Transcript Document

Bölüm 10 –Polimorfizm
Outline
10.1
Polimorfizm
10.2
Miras Hiyerarşisinde Objeler arasındaki İlişki
10.2.1 Altsınıf objelerinin süper sınıf metotlarını çağırması
10.2.2 Süper sınıf referanlarna alt sınıf referans değeri atama
10.2.3 Süper sınıf referanslardan alt sınıf metotları çağırmak
10.3
Soyut Sınıf ve Metodlar
10.4
Arabirimler
10.5
İçiçe Sınıflar
Polimorfizm
• Birçok altsınıf benzer olaylar için farklı metodları
vardır.
• Mesala bir hayvanat bahçesindeki hayvanların
seslerinin simulasyonunu yapacaksınız.
– Fakat her hayvanın ses çıkarması farklıdır.
– Miras konusundaki örneğe yeniden bakalım !!
class Animal {
public void makeNoise ( ) {
System.out.println
(“I am an animal.”);
} // of makeNoise
} // of Animal
class Fish extends Animal {
public void makeNoise( ) {
System.out.println
(“Glug glug gurgle gurgle”);
} // of makeNoise
} // of Fish
class Bird extends Animal {
public void makeNoise( ) {
System.out.println(“Tweet tweet flap flap”);
} // of makeNoise
} // of Bird
class Dog extends Animal
{
public void makeNoise ( )
{
System.out.println(“Sniff sniff woof woof”);
} // of makeNoise
public void bark ( )
{
System.out.println(“Arf Arf”);
} // of bark
}
// of Dog
class Driver {
public static void main (String[ ] argv) {
Animal[ ] animalArray = new Animal[3];
int iIndex;
animalArray[0] = new Bird( );
animalArray[1] = new Dog( );
animalArray[2] = new Fish( );
for (iIndex=0; iIndex < animalArray.length;iIndex++) {
animalArray[iIndex].makeNoise( );
} // of for
} // of main
} // of Driver
Output:
Tweet tweet flap flap
Sniff sniff woof woof
Glug glug gurgle gurgle
All animals can
makeNoise, so any
member of the array
can makeNoise
Polimorfizm
• Miras,genel bir sınıfın ,tüm türevleri için ortak olan
metotlar tanımlamasına ve altsınıfların bunların hepsi yada
bir kısmına özel olarak gerçeklerştirilmesine izin verir.
• Bu işe bindirilmiş metotlar (overriding) denir.
• Bindirilmiş metotlar polimorfizmin “bir arabirim, birden
çok metot” özelliğini gerçekleştirmenin bir başka yoludur.
• Java bunu süper sınıf referansları ile yapar.
– Hatırla!! – alt-sınıf is a süper-sınıf (Fish is a animal)
– Tersi doğru değil
Bellek Durumu
Object
Fish fTemp;
fTemp = new Fish(0);
toString()
Animal
int numLegs = 0
String strType
toString();
move();
Fish
fTemp
move();
Wow.
Object oTemp;
oTemp = new Fish(0);
Object
toString()
Animal
int numLegs = 0
String strType
toString();
move();
Fish
oTemp
move();
A single
Fish instance
Ahh.
So we can just make new reference types and have them point
into our block at a different locations. By ‘twiddling’ the reference
into our block of memory, we can polymorph the object.
Object
Animal aTemp;
aTemp = new Fish(0);
toString()
Animal
int numLegs = 0
String strType
toString();
move();
Fish
aTemp
move();
We adjust where reference points, so
that it reflects its type.
Hey, Cool
Object
toString()
Animal
int numLegs = 3
String strType
toString();
move();
Fish
ref
Fish
move();
That’s a simple example of polymorphism.
Hey, Cool
Object
toString()
Animal
int numLegs = 3
String strType
toString();
move();
Animal
ref
Fish
move();
That’s a simple example of polymorphism.
Hey, Cool
It’s the same object in
memory. We just
change the reference
type pointing to it.
Object
toString()
Animal
int numLegs = 3
String strType
toString();
move();
Object
ref
Fish
move();
That’s a simple example of polymorphism.
Polymorphism
Many forms
Object
toString()
Animal
int numLegs = 3
String strType
toString();
move();
<type>
ref
One object
Fish
move();
Literally, polymorphism means “Many forms” So for
us we take it to imply, "One object; many forms”
Thus
So we have three box groupings that represent
arbitrary instances of Fish, Dog and Bird, pointed to
by any appropriate reference type.
Object
Object
toString()
toString()
toString()
Animal
Animal
Animal
int numLegs = 0
String strType
toString();
move();
int numLegs = 3
String strType
toString();
move();
move();
bark();
move();
dTemp
int numLegs = 2
String strType
toString();
move();
Bird
Dog
Fish
fTemp
Object
bTemp
move();
Fish fTemp = new Fish(0);
Dog dTemp = new Dog(3);
Bird bTemp = new Bird(2);
Polymorphism
class Driver2 {
public static void main(String[ ] argv) {
Animal[ ] = animalArray[3];
Dog d;
int iIndex;
animalArray[0] = new Bird( );
animalArray[1] = new Dog( );
animalArray[2] = new Fish( );
for (1=0; 1 < animalArray.length; iIndex++)
if (animalArray[iIndex] instanceof Dog)
{ d = (Dog) animalArray[iIndex];
d.bark( );
We cast before calling
} // if
bark()
} // main
} // Driver2
because only dogs can
bark. So some array
members cannot execute
the method
Polymorphism
Casting:
• used here to give an object of a superclass the form of the
appropriate subclass, e.g.,
if (animalArray[iIndex] instanceof Dog)
{
animalArray[iIndex].bark();
}
would produce an error because objects of class Animal have no
method called bark. So, we first cast what instanceof tells us is a
Dog as a Dog.
if (animalArray[iIndex] instanceof Dog)
{
d = (Dog) animalArray[iIndex]
d.bark( );
}
Casting … Why?
Keyword instanceof:
Used to interrogate an object to see if it is an instance
of the specified class, e.g.
“Is this particular animal of class Dog?”
Question:
If Java can determine that a given Animal is or is not
a Dog (via instanceof), then:
• Why the need to cast it to a Dog object before Java
can recognize that it can bark?
• Why can’t Java do it for us?
Casting… Why?
Answer:
difference between compile-time and run-time type checking.
Source
code
Byte
code
Compile
JVM
Interpreter
errors
Compile-time Errors:
• Those that are discernable
(seçmek,ayırt etmek)
without the program executing.
• Question of language legality:
“Is this a legal statement?”
e.g.,
iIndex = strName;
Statement is not legal.
Program
runs
errors
Run-time Errors:
• Those that are discernable only when the
program is running with actual data values.
• Question of execution legality:
“Is it legal for this variable to have the
actual value assigned to it?”, e.g.,
animalArray[<badIndex>] = someAnimal
Statement is legal, but particular
index value isn’t.
Casting… Why?
if (animalArray[iIndex]
instanceof Dog){
animalArray[iIndex].bark();
}
if (animalArray[iIndex]
instanceof Dog) {
d = (Dog) animalArray[iIndex];
d.bark( );
}
• 1st line is legal.
• 2nd line isn’t (unless array has Dog).
• We can see that 1st line guarantees
2nd is legal.
• Compiler cannot see inter-statement
dependencies… unless compiler
runs whole program with all possible
data sets!
• Runtime system could tell easily. . .
BUT. . . We want most checking at
compile-time for reasons of both
performance and correctness.
• Here, legality of each line of code
can be evaluated at compile time.
• Legality of each line discernable
without worrying about inter-statement
dependencies, i.e., each line can
stand by itself.
• Can be sure that code is legal
(not sometimes-legal).
A Good Use for Casting:
Resolving polymorphic ambiguities
for the compiler.
10.2 Miras Hiyerarşisi içinde Objeler
arasında İlişki
• Önceki bölümde (Bölüm 9.4),
– Circle sınfı Point sınfından miras almıştı.
– Point ve Circle nesnelerinin referanslarını kullanarak
metodlarını çağırıyorduk.
• İpucu
– Altsınıf nesnesi süper sınıf nesnesi gibi davranabilir.
• “is-a” ilişkisi (Çember noktalardan oluşur.)
• Süpersınıf nesnesi altsınıf nesnesi değildir.
10.2.1 Altsınıf nesnelerinden süper sınıf
referansı ile alt sınıf metodlarını çağırmak
• Süper sınıf ve altsınıf nesnelerinde referanslar
saklamak
– Süpersınıf referansını süpersınıf türünden tanıtılmış
değişkene atamak
• Supers_değişkensupers_referans
– Altsınıf referansını altsınıf türünden tanıtılmış değişkene
atamak
• Alts_değişkenalts_referans
– Altsınıf referansını süpersınıf değişkenine atamak
• Supers_değişkenalts_referans
• “is a” ilişkisi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Fig. 10.1: HierarchyRelationshipTest1.java
// Assigning superclass and subclass references to superclass- and
// subclass-type variables.
import javax.swing.JOptionPane;
HierarchyRelation
shipTest1.java
public class HierarchyRelationshipTest1 {
public static void main( String[] args )
{
// assign superclass reference to superclass-type variable
Assign superclass
Point3 point = new Point3( 30, 50 );
Line 11
Assign superclass
reference to superclassreference
type variable
to superclass-type variable
// assign subclass reference to subclass-type variable
Circle4 circle = new Circle4( 120, 89, 2.7 );
Line 14
Assign subclass reference
to reference
Assign subclass
subclass-type variable
to subclass-type variable
// invoke toString on superclass object using superclass variable
String output = "Call Point3's toString with superclass" +
" reference to superclass object: \n" + point.toString();
// invoke toString on subclass object using subclass variable
output += "\n\nCall Circle4's toString with subclass" +
" reference to subclass object: \n" + circle.toString();
InvokeLine
toString
on
17
Invoke
toString
superclass
object
using on
superclass
object using
superclass
variable
superclass variable
Invoke toString on
subclass
object
Line
22 using
Invoke
toString on
subclass
variable
subclass object using
subclass variable
24
25
26
27
28
29
30
31
32
33
34
35
// invoke toString on subclass objectAssign
using subclass
superclass
variableto
reference
Point3 pointRef = circle;
superclass-type variable
output += "\n\nCall Circle4's toString with superclass" +
" reference to subclass object: \n" + pointRef.toString();
JOptionPane.showMessageDialog( null, output );
// display output
Invoke toString on
subclass
object using
HierarchyRelati
superclass
variable
onshipTest1.jav
a
System.exit( 0 );
} // end main
} // end class HierarchyRelationshipTest1
Line 25
Assign subclass
reference to
superclass-type
variable.
Line 27
Invoke toString on
subclass object using
superclass variable.
10.2.2 Altsınıf değişken tipleri ile süper sınıf
referanslarını kullanmak
• Önceki örnek
– Altsınıf referansını süpersınıf değişkenine atamak
– Circle “is a” Point
• Süpersınıf referanslarını altsınıf tipli değişkenlere atamak
– Derleme hatası
• “is a” türünde ilişki yok
• Point is not a Circle
• Circle sınıfının sahip olup Point sınıfının sahip olmadığı
data/metodlar var.
– setRadius (Circle da tanımlı) Point sınıfında tanımlı
değil.
– Süpersınıf referansını altsınıf referansına dönüştürmek.
• downcasting olarak adlandırılır.
• Altsınıf işlevlerini çağırma
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Fig. 10.2: HierarchyRelationshipTest2.java
// Attempt to assign a superclass reference to a subclass-type variable.
public class HierarchyRelationshipTest2 {
public static void main( String[] args )
{
Point3 point = new Point3( 30, 50 );
Circle4 circle; // subclass-type variable
// assign superclass reference to subclass-type variable
circle = point; // Error: a Point3 is not a Circle4
}
} // end class HierarchyRelationshipTest2
Assigning superclass reference
to subclass-type variable causes
compiler error
HierarchyRelationshipTest2.java:12: incompatible types
found
: Point3
required: Circle4
circle = point; // Error: a Point3 is not a Circle4
^
1 error
HierarchyRelati
onshipTest2.jav
a
Line 12
Assigning superclass
reference to subclasstype variable causes
compiler error.
10.2.3 Süper sınıf değişken tipine göre
altsınıf metodları çağırmak
• Süpersınıf referansı ile altsınıf metodu çağırmak
– Derleme hatası
• Altsınıf metodları süpersınıf metodları değiller.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fig. 10.3: HierarchyRelationshipTest3.java
// Attempting to invoke subclass-only member methods through
// a superclass reference.
public class HierarchyRelationshipTest3 {
public static void main( String[] args )
{
Point3 point;
Circle4 circle = new Circle4( 120, 89, 2.7 );
point = circle;
// aim superclass reference at subclass object
// invoke superclass (Point3) methods on subclass
// (Circle4) object through superclass reference
int x = point.getX();
int y = point.getY();
point.setX( 10 );
point.setY( 20 );
point.toString();
HierarchyRelati
onshipTest3.jav
a
22
23
24
25
26
27
28
29
30
31
32
// attempt to invoke subclass-only (Circle4) methods on
// subclass object through superclass (Point3) reference
double radius = point.getRadius();
point.setRadius( 33.33 );
double diameter = point.getDiameter();
double circumference = point.getCircumference();
double area = point.getArea();
} // end main
} // end class HierarchyRelationshipTest3
Attempt to invoke subclassonly (Circle4) methods on
subclass object through
superclass (Point3)
reference.
HierarchyRelati
onshipTest3.jav
a
Lines 24-28
Attempt to invoke
subclass-only
(Circle4) methods
on subclass object
through superclass
(Point3) reference.
HierarchyRelationshipTest3.java:24: cannot resolve symbol
symbol : method getRadius ()
location: class Point3
double radius = point.getRadius();
^
HierarchyRelationshipTest3.java:25: cannot resolve symbol
symbol : method setRadius (double)
location: class Point3
point.setRadius( 33.33 );
^
HierarchyRelationshipTest3.java:26: cannot resolve symbol
symbol : method getDiameter ()
location: class Point3
double diameter = point.getDiameter();
^
HierarchyRelationshipTest3.java:27: cannot resolve symbol
symbol : method getCircumference ()
location: class Point3
double circumference = point.getCircumference();
^
HierarchyRelationshipTest3.java:28: cannot resolve symbol
symbol : method getArea ()
location: class Point3
double area = point.getArea();
^
5 errors
HierarchyRelati
onshipTest3.jav
a
10.4 Soyut (Abstract) Sınıflar ve Metodlar
• Soyut (abstract) sınıflar
– Süpersınıflar soyut sınıflar olarak adlandırabilir miyiz?
– Nesne oluşturamazlar.
– Tam bir sınıf değildirler.
• Altsınıflar soyut sınıfının boş kısımlarını doldururlar.
• Somut (concrete) sınıflar
– Nesne oluşturabilirler.
– Bütün metodlar tanımlıdır.
– Detaylar vardır.
10.4 Soyut (Abstract) Sınıflar ve Metodlar
(devam)
• Soyut sınıf yapmak için
– Sınıf abstract anahtar sözü ile tanımlanır.
– Bir yada daha fazla soyut metod içerebilir.
public abstract void draw();
– Soyut metodlar
• İçinde herhengi bir kod bulundurmazlar, miras alınan sınıf
tarafından içleri doldurulur.
10.4 Soyut (Abstract) Sınıflar ve Metodlar
(devam)
• Örnek uygulama
– Soyut sınıf: Shape
• draw metodunu soyut olarak tanımlıyor.
– Circle, Triangle, Rectangle sınıfları Shape
sınıfını miras alıyorlar.
• Her bir sınıf draw metodunu tanımlamalı.
10.5 Örnek Uygulama: Soyut Sınıfı Miras
Alma
• Soyut süper sınıf : Shape
– Soyut metodlar
• getName, print
– İptal edilebilir (overridden) metodlar
• getArea, getVolume
– Varsayılan uygulama 0.0 dönderir.
• Eğer iptal edilmezlerse süper sınıfın metodunu kullanırlar.
– Altsınıflar: Point, Circle, Cylinder
10.5 Örnek Uygulama: Soyut Sınıfı Miras
Alma
Shape
Point
Circle
Cylinder
Fig. 10.4 Shape hierarchy class diagram.
10.6 Örnek Uygulama: Soyut Sınıfı Miras
Alma
getArea
getVolume
getName
print
Shape
0.0
0.0
= 0
= 0
Point
0.0
0.0
"Point"
[x,y]
Circle
pr2
0.0
"Circle"
center=[x,y];
radius=r
2pr2 +2prh
pr2h
"Cylinder"
center=[x,y];
radius=r;
height=h
Cylinder
Fig. 10.5 Polimorphic interface for the Shape hierarchy classes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fig. 10.6: Shape.java
// Shape abstract-superclass declaration.
Shape.java
public abstract class Shape extends Object {
// return area of shape; 0.0 by default
public double getArea()
Keyword abstract
{
declares class Shape
return 0.0;
abstract class
}
as
// return volume of shape; 0.0 by default
public double getVolume()
{
return 0.0;
}
// abstract method, overridden by subclasses
public abstract String getName();
} // end abstract class Shape
Keyword abstract declares
method getName as abstract
method
Line 4
Keyword abstract
declares class Shape
as abstract class
Line 19
Keyword abstract
declares method
getName as abstract
method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 10.7: Point.java
// Point class declaration inherits from Shape.
public class Point extends Shape {
private int x; // x part of coordinate pair
private int y; // y part of coordinate pair
// no-argument constructor; x and y default to 0
public Point()
{
// implicit call to Object constructor occurs here
}
// constructor
public Point( int xValue, int yValue )
{
// implicit call to Object constructor occurs here
x = xValue; // no need for validation
y = yValue; // no need for validation
}
// set x in coordinate pair
public void setX( int xValue )
{
x = xValue; // no need for validation
}
Point.java
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// return x from coordinate pair
public int getX()
{
return x;
}
Point.java
// set y in coordinate pair
public void setY( int yValue )
{
y = yValue; // no need for validation
}
// return y from coordinate pair
public int getY()
{
return y;
}
Override
abstract
method getName.
// override abstract method getName to return "Point"
public String getName()
{
return "Point";
}
// override toString to return String representation of Point
public String toString()
{
return "[" + getX() + ", " + getY() + "]";
}
} // end class Point
Lines 47-50
Override abstract
method getName.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 10.8: Circle.java
// Circle class inherits from Point.
public class Circle extends Point {
private double radius; // Circle's radius
// no-argument constructor; radius defaults to 0.0
public Circle()
{
// implicit call to Point constructor occurs here
}
// constructor
public Circle( int x, int y, double radiusValue )
{
super( x, y ); // call Point constructor
setRadius( radiusValue );
}
// set radius
public void setRadius( double radiusValue )
{
radius = ( radiusValue < 0.0 ? 0.0 : radiusValue );
}
Circle.java
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// return radius
public double getRadius()
{
return radius;
}
// calculate and return diameter
public double getDiameter()
{
return 2 * getRadius();
}
// calculate and return circumference
Override method
public double getCircumference()
getArea to
{
return circle area
return Math.PI * getDiameter();
}
// override method getArea to return Circle area
public double getArea()
{
return Math.PI * getRadius() * getRadius();
}
Circle.java
Lines 45-48
Override method
getArea to return
circle area.
50
51
52
53
54
55
56
57
58
59
60
61
62
// override abstract method getName to return "Circle"
public String getName()
Override
{
return "Circle";
abstract
}
method getName
// override toString to return String representation of Circle
public String toString()
{
return "Center = " + super.toString() + "; Radius = " + getRadius();
}
} // end class Circle
Circle.java
Lines 51-54
Override abstract
method getName.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 10.9: Cylinder.java
// Cylinder class inherits from Circle.
public class Cylinder extends Circle {
private double height; // Cylinder's height
// no-argument constructor; height defaults to 0.0
public Cylinder()
{
// implicit call to Circle constructor occurs here
}
// constructor
public Cylinder( int x, int y, double radius, double heightValue )
{
super( x, y, radius ); // call Circle constructor
setHeight( heightValue );
}
// set Cylinder's height
public void setHeight( double heightValue )
{
height = ( heightValue < 0.0 ? 0.0 : heightValue );
}
Cylinder.java
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// get Cylinder's height
public double getHeight()
{
return height;
}
Override method
getArea to
return cylinder
area
// override abstract method getArea to Override
return Cylinder
method area
public double getArea()
getVolume to
{
return cylinder
return 2 * super.getArea() + getCircumference() * getHeight();
volume
}
// override abstract method getVolume to return Cylinder volume
public double getVolume()
{
return super.getArea() * getHeight();
}
// override abstract method getName to return "Cylinder"
public String getName()
Override
{
abstract
return "Cylinder";
method getName
}
Cylinder.java
Lines 33-36
Override method
getArea to return
cylinder area
Lines 39-42
Override method
getVolume to return
cylinder volume
Lines 45-48
Override abstract
method getName
49
50
51
52
53
54
55
56
// override toString to return String representation of Cylinder
public String toString()
{
return super.toString() + "; Height = " + getHeight();
}
} // end class Cylinder
Cylinder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 10.10: AbstractInheritanceTest.java
// Driver for shape, point, circle, cylinder hierarchy.
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
public class AbstractInheritanceTest {
public static void main( String args[] )
{
// set floating-point number format
DecimalFormat twoDigits = new DecimalFormat( "0.00" );
// create Point, Circle and Cylinder objects
Point point = new Point( 7, 11 );
Circle circle = new Circle( 22, 8, 3.5 );
Cylinder cylinder = new Cylinder( 20, 30, 3.3, 10.75 );
// obtain name and string representation of each object
String output = point.getName() + ": " + point + "\n" +
circle.getName() + ": " + circle + "\n" +
cylinder.getName() + ": " + cylinder + "\n";
Shape arrayOfShapes[] = new Shape[ 3 ];
// create Shape array
AbstractInherit
anceTest.java
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// aim arrayOfShapes[ 0 ] at subclass Point object
arrayOfShapes[ 0 ] = point;
// aim arrayOfShapes[ 1 ] at subclass CircleCreate
objectan
arrayOfShapes[ 1 ] = circle;
array of
AbstractInherit
Loop
through
generic Shape objects
anceTest.java
arrayOfShapes to get
// aim arrayOfShapes[ 2 ] at subclass Cylinder object
name, string representation,
Lines 26-32
arrayOfShapes[ 2 ] = cylinder;
area and volume of Create
every an array of
shape in array
// loop through arrayOfShapes to get name, string
generic Shape
// representation, area and volume of every Shape in array
for ( int i = 0; i < arrayOfShapes.length; i++ ) {
output += "\n\n" + arrayOfShapes[ i ].getName() + ": " +
arrayOfShapes[ i ].toString() + "\nArea = " +
twoDigits.format( arrayOfShapes[ i ].getArea() ) +
"\nVolume = " +
twoDigits.format( arrayOfShapes[ i ].getVolume() );
}
JOptionPane.showMessageDialog( null, output );
System.exit( 0 );
} // end main
} // end class AbstractInheritanceTest
// display output
objects
Lines 36-42
Loop through
arrayOfShapes to
get name, string
representation, area
and volume of every
shape in array
10.7 Örnek Uygulama: Polimorfizim
kullanarak Bordro Sistemi
• Bordro programı oluşturalım
– Soyut metodlar ve polimorfizm kullanalım
• Problemimiz:
– 4 tip çalışanımız var, ücretleri haftalık ödeniyor.
• Salaried : sabit maaşlı
• Hourly : saatlik maaş ödeniyor.(eğer 40 saati aşmış ise aşan
saat kadar 1.5 katı ödeme yapılacak)
• Commission: satış yüzdesi kadar maaş ödeniyor.
• Base-plus-commission: sabit maaş + satışın belli miktarda
yüzdesi)
10.9 Case Study: Payroll System Using
Polymorphism
• Süpersınıf: Employee
– Soyut metod : earnings (kazanılanı geri dönderir)
• Soyut olması lazım;çünki çalışan tipini bilmiyoruz.
– Diğer sınıflar Employee sınıfından miras alıyor.
Employee
SalariedEmployee
CommissionEmployee
BasePlusCommissionEmployee
HourlyEmployee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Fig. 10.12: Employee.java
// Employee abstract superclass.
public abstract class Employee {
private String firstName;
private String lastName;
private String socialSecurityNumber;
Declares class Employee
as abstract class.
// constructor
public Employee( String first, String last, String ssn )
{
firstName = first;
lastName = last;
socialSecurityNumber = ssn;
}
// set first name
public void setFirstName( String first )
{
firstName = first;
}
Employee.java
Line 4
Declares class
Employee as
abstract class.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// return first name
public String getFirstName()
{
return firstName;
}
// set last name
public void setLastName( String last )
{
lastName = last;
}
// return last name
public String getLastName()
{
return lastName;
}
// set social security number
public void setSocialSecurityNumber( String number )
{
socialSecurityNumber = number; // should validate
}
Employee.java
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// return social security number
public String getSocialSecurityNumber()
{
return socialSecurityNumber;
}
Employee.java
// return String representation of Employee object
public String toString()
{
return getFirstName() + " " + getLastName() +
"\nsocial security number: " + getSocialSecurityNumber();
}
// abstract method overridden by subclasses
public abstract double earnings();
} // end abstract class Employee
Abstract method
overridden by subclasses
Line 61
Abstract method
overridden by
subclasses.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Fig. 10.13: SalariedEmployee.java
// SalariedEmployee class extends Employee.
public class SalariedEmployee extends Employee {
private double weeklySalary;
// constructor
Use superclass
public SalariedEmployee( String first, String last,
basic fields.
String socialSecurityNumber, double salary )
{
super( first, last, socialSecurityNumber );
setWeeklySalary( salary );
}
// set salaried employee's salary
public void setWeeklySalary( double salary )
{
weeklySalary = salary < 0.0 ? 0.0 : salary;
}
// return salaried employee's salary
public double getWeeklySalary()
{
return weeklySalary;
}
SalariedEmploye
e.java
constructor for
Line 11
Use superclass
constructor for basic
fields.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// calculate salaried employee's pay;
// override abstract method earnings in Employee
public double earnings()
{
return getWeeklySalary();
}
Must implement abstract
method earnings.
// return String representation of SalariedEmployee object
public String toString()
{
return "\nsalaried employee: " + super.toString();
}
} // end class SalariedEmployee
SalariedEmploye
e.java
Lines 29-32
Must implement
abstract method
earnings.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Fig. 10.14: HourlyEmployee.java
// HourlyEmployee class extends Employee.
public class HourlyEmployee extends Employee {
private double wage;
// wage per hour
private double hours; // hours worked for week
// constructor
public HourlyEmployee( String first, String last,
String socialSecurityNumber, double hourlyWage, double hoursWorked )
{
super( first, last, socialSecurityNumber );
setWage( hourlyWage );
setHours( hoursWorked );
}
// set hourly employee's wage
public void setWage( double wageAmount )
{
wage = wageAmount < 0.0 ? 0.0 : wageAmount;
}
// return wage
public double getWage()
{
return wage;
}
HourlyEmployee.
java
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// set hourly employee's hours worked
public void setHours( double hoursWorked )
{
hours = ( hoursWorked >= 0.0 && hoursWorked <= 168.0 ) ?
hoursWorked : 0.0;
}
// return hours worked
public double getHours()
{
return hours;
}
// calculate hourly employee's pay;
// override abstract method earnings in Employee
public double earnings()
Must implement abstract
{
method earnings.
if ( hours <= 40 ) // no overtime
return wage * hours;
else
return 40 * wage + ( hours - 40 ) * wage * 1.5;
}
// return String representation of HourlyEmployee object
public String toString()
{
return "\nhourly employee: " + super.toString();
}
} // end class HourlyEmployee
HourlyEmployee.
java
Lines 44-50
Must implement
abstract method
earnings.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Fig. 10.15: CommissionEmployee.java
// CommissionEmployee class extends Employee.
public class CommissionEmployee extends Employee {
private double grossSales;
// gross weekly sales
private double commissionRate; // commission percentage
// constructor
public CommissionEmployee( String first, String last,
String socialSecurityNumber,
double grossWeeklySales, double percent )
{
super( first, last, socialSecurityNumber );
setGrossSales( grossWeeklySales );
setCommissionRate( percent );
}
// set commission employee's rate
public void setCommissionRate( double rate )
{
commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
}
// return commission employee's rate
public double getCommissionRate()
{
return commissionRate;
}
CommissionEmplo
yee.java
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// set commission employee's weekly base salary
public void setGrossSales( double sales )
{
grossSales = sales < 0.0 ? 0.0 : sales;
}
CommissionEmplo
yee.java
// return commission employee's gross sales amount
public double getGrossSales()
{
return grossSales;
}
Lines 44-47
Must implement
abstract method
earnings.
// calculate commission employee'sMust
pay; implement abstract
// override abstract method earnings
in Employee
method
earnings.
public double earnings()
{
return getCommissionRate() * getGrossSales();
}
// return String representation of CommissionEmployee object
public String toString()
{
return "\ncommission employee: " + super.toString();
}
} // end class CommissionEmployee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 10.16: BasePlusCommissionEmployee.java
// BasePlusCommissionEmployee class extends CommissionEmployee.
public class BasePlusCommissionEmployee extends CommissionEmployee {
private double baseSalary; // base salary per week
// constructor
public BasePlusCommissionEmployee( String first, String last,
String socialSecurityNumber, double grossSalesAmount,
double rate, double baseSalaryAmount )
{
super( first, last, socialSecurityNumber, grossSalesAmount, rate );
setBaseSalary( baseSalaryAmount );
}
// set base-salaried commission employee's base salary
public void setBaseSalary( double salary )
{
baseSalary = salary < 0.0 ? 0.0 : salary;
}
// return base-salaried commission employee's base salary
public double getBaseSalary()
{
return baseSalary;
}
BasePlusCommiss
ionEmployee.jav
a
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// calculate base-salaried commission employee's earnings;
// override method earnings in CommissionEmployee
public double earnings()
Override method earnings
{
in CommissionEmployee
return getBaseSalary() + super.earnings();
}
// return String representation of BasePlusCommissionEmployee
public String toString()
{
return "\nbase-salaried commission employee: " +
super.getFirstName() + " " + super.getLastName() +
"\nsocial security number: " + super.getSocialSecurityNumber();
}
} // end class BasePlusCommissionEmployee
BasePlusCommiss
ionEmployee.jav
a
Lines 30-33
Override method
earnings in
CommissionEmplo
yee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Fig. 10.17: PayrollSystemTest.java
// Employee hierarchy test program.
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
public class PayrollSystemTest {
public static void main( String[] args )
{
DecimalFormat twoDigits = new DecimalFormat( "0.00" );
// create Employee array
Employee employees[] = new Employee[ 4 ];
// initialize array with Employees
employees[ 0 ] = new SalariedEmployee( "John", "Smith",
"111-11-1111", 800.00 );
employees[ 1 ] = new CommissionEmployee( "Sue", "Jones",
"222-22-2222", 10000, .06 );
employees[ 2 ] = new BasePlusCommissionEmployee( "Bob", "Lewis",
"333-33-3333", 5000, .04, 300 );
employees[ 3 ] = new HourlyEmployee( "Karen", "Price",
"444-44-4444", 16.75, 40 );
String output = "";
PayrollSystemTe
st.java
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// generically process each element in array employees
for ( int i = 0; i < employees.length; i++ ) {
output += employees[ i ].toString();
PayrollSystemTe
// determine whether element is a BasePlusCommissionEmployee
st.java
if ( employees[ i ] instanceof BasePlusCommissionEmployee ) {
Determine whether element is a
Line 32
BasePlusCommissionEmpl
// downcast Employee reference to
Determine whether
oyee
// BasePlusCommissionEmployee reference
element is a
BasePlusCommissionEmployee currentEmployee =
BasePlusCommiss
( BasePlusCommissionEmployee ) employees[ i ];
Downcast Employee reference to ionEmployee
BasePlusCommissionEmployee
double oldBaseSalary = currentEmployee.getBaseSalary();
output += "\nold base salary: reference
$" + oldBaseSalary;
Line 37
Downcast Employee
currentEmployee.setBaseSalary( 1.10 * oldBaseSalary );
reference to
output += "\nnew base salary with 10% increase is: $" +
BasePlusCommiss
currentEmployee.getBaseSalary();
ionEmployee
reference
} // end if
output += "\nearned $" + employees[ i ].earnings() + "\n";
} // end for
52
53
54
55
56
57
58
59
60
61
62
// get type name of each object in employees array
for ( int j = 0; j < employees.length; j++ )
output += "\nEmployee " + j + " is a " +
employees[ j ].getClass().getName();
JOptionPane.showMessageDialog( null, output );
System.exit( 0 );
} // end main
} // end class PayrollSystemTest
Get type name of eachPayrollSystemTe
object in employeesst.java
// display output
array
Lines 53-55
Get type name of each
object in employees
array
10.8 Örnek Uygulama: Arabirim (Interface)
Oluşturma ve Kullanma
• Arabirim (interface) : Shape
– Soyut sınıf Shape yerine arayüz yazalım
• Arabirim
– interface anahtar kelimesi ile tanıma başlanır.
– Arabirim yazım olarak sınıflara benzerler ancak örnek
değişkenleri yoktur ve bildirilen metotların da gövdesi
yoktur.
– Sınıflar arabirimi implement anahtar kelimesi ile
kendilerine dahil ederler.
– public abstract metodlar içerirler.
• Sınıflar arabirim metodlarını uygulama zorunlulukları vardır.
1
2
3
4
5
6
7
8
9
// Fig. 10.18: Shape.java
// Shape interface declaration.
public interface
public double
public double
public String
Shape {
getArea();
getVolume();
getName();
} // end interface Shape
Classes that implement Shape
must implement these methods
Shape.java
// calculate area
// calculate volume
// return shape name
Lines 5-7
Classes that
implement Shape
must implement these
methods
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 10.19: Point.java
// Point class declaration implements interface Shape.
public class Point extends Object implements Shape {
private int x; // x part of coordinate pair
private int y; // y part of coordinate pair
// no-argument constructor; x and y default to 0
Point implements
public Point()
{
// implicit call to Object constructor occurs here
}
// constructor
public Point( int xValue, int yValue )
{
// implicit call to Object constructor occurs here
x = xValue; // no need for validation
y = yValue; // no need for validation
}
// set x in coordinate pair
public void setX( int xValue )
{
x = xValue; // no need for validation
}
Point.java
Line 4
Point implements
interface Shape
interface Shape
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// return x from coordinate pair
public int getX()
{
return x;
}
// set y in coordinate pair
public void setY( int yValue )
{
y = yValue; // no need for validation
}
// return y from coordinate pair
public int getY()
{
return y;
}
Point.java
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// declare abstract method getArea
public double getArea()
{
return 0.0;
}
// declare abstract method getVolume
public double getVolume()
{
return 0.0;
}
Point.java
Lines 47-59
Implement methods specified
Implement methods
by interface Shape
specified by interface
Shape
// override abstract method getName to return "Point"
public String getName()
{
return "Point";
}
// override toString to return String representation of Point
public String toString()
{
return "[" + getX() + ", " + getY() + "]";
}
} // end class Point
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 10.20: InterfaceTest.java
// Test Point, Circle, Cylinder hierarchy with interface Shape.
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
InterfaceTest.j
ava
public class InterfaceTest {
public static void main( String args[] )
{
// set floating-point number format
DecimalFormat twoDigits = new DecimalFormat( "0.00" );
// create Point, Circle and Cylinder objects
Point point = new Point( 7, 11 );
Circle circle = new Circle( 22, 8, 3.5 );
Cylinder cylinder = new Cylinder( 20, 30, 3.3, 10.75 );
// obtain name and string representation of each object
String output = point.getName() + ": " + point + "\n" +
Create Shape array
circle.getName() + ": " + circle + "\n" +
cylinder.getName() + ": " + cylinder + "\n";
Shape arrayOfShapes[] = new Shape[ 3 ];
// create Shape array
Line 23
Create Shape array
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// aim arrayOfShapes[ 0 ] at subclass Point object
arrayOfShapes[ 0 ] = point;
// aim arrayOfShapes[ 1 ] at subclass Circle object
arrayOfShapes[ 1 ] = circle;
InterfaceTest.j
ava
Loop through arrayOfShapes to
// aim arrayOfShapes[ 2 ] at subclass Cylinder
get name,object
string representation, area
arrayOfShapes[ 2 ] = cylinder;
and volume of every shape in arrayLines 36-42
Loop through
// loop through arrayOfShapes to get name, string
arrayOfShapes to
// representation, area and volume of every Shape in array
get name, string
for ( int i = 0; i < arrayOfShapes.length; i++ ) {
representation, area
output += "\n\n" + arrayOfShapes[ i ].getName() + ": " +
arrayOfShapes[ i ].toString() + "\nArea = " +
and volume of every
twoDigits.format( arrayOfShapes[ i ].getArea() ) +
shape in array.
"\nVolume = " +
twoDigits.format( arrayOfShapes[ i ].getVolume() );
}
JOptionPane.showMessageDialog( null, output );
System.exit( 0 );
} // end main
} // end class InterfaceTest
// display output
InterfaceTest.j
ava
10.8 Örnek Uygulama: Arayüz (Interface)
Oluşturma ve Kullanma (devam)
• Çoklu arabirim (interface) uygulaması
– implements anahtar sözcüğünden sonra arayüzler virgülle
ayrılarak ard arda yazılabilir.
• Arabirimlerle sabitler tanımlama
– public interface
public static
public static
public static
}
Constants
final int
final int
final int
{
ONE = 1;
TWO = 2;
THREE = 3;
10.9 İçiçe Sınıflar
• Üst düzey sınıflar
– Bir sınıf yada metod içinde tanımlanmazlar.
• İçiçe sınıflar
– Başka sınıfın içinde tanımlanırlar.
– İç sınıflar
• Statik olmayan içiçe sınıflar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 10.21: Time.java
// Time class declaration with set and get methods.
import java.text.DecimalFormat;
public class Time {
private int hour;
private int minute;
private int second;
Time.java
// 0 - 23
// 0 - 59
// 0 - 59
// one formatting object to share in toString and toUniversalString
private static DecimalFormat twoDigits = new DecimalFormat( "00" );
// Time constructor initializes each instance variable to zero;
// ensures that Time object starts in a consistent state
public Time()
{
this( 0, 0, 0 ); // invoke Time constructor with three arguments
}
// Time constructor: hour supplied, minute and second defaulted to 0
public Time( int h )
{
this( h, 0, 0 ); // invoke Time constructor with three arguments
}
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Time constructor: hour and minute supplied, second defaulted to 0
public Time( int h, int m )
{
this( h, m, 0 ); // invoke Time constructor with three arguments
}
// Time constructor: hour, minute and second supplied
public Time( int h, int m, int s )
{
setTime( h, m, s );
}
// Time constructor: another Time3 object supplied
public Time( Time time )
{
// invoke Time constructor with three arguments
this( time.getHour(), time.getMinute(), time.getSecond() );
}
// Set Methods
// set a new time value using universal time; perform
// validity checks on data; set invalid values to zero
public void setTime( int h, int m, int s )
{
setHour( h );
// set the hour
setMinute( m ); // set the minute
setSecond( s ); // set the second
}
Time.java
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// validate and set hour
public void setHour( int h )
{
hour = ( ( h >= 0 && h < 24 ) ? h : 0 );
}
// validate and set minute
public void setMinute( int m )
{
minute = ( ( m >= 0 && m < 60 ) ? m : 0 );
}
// validate and set second
public void setSecond( int s )
{
second = ( ( s >= 0 && s < 60 ) ? s : 0 );
}
// Get Methods
// get hour value
public int getHour()
{
return hour;
}
Time.java
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// get minute value
public int getMinute()
{
return minute;
}
// get second value
public int getSecond()
{
return second;
}
// convert to String in universal-time format
Override method
public String toUniversalString()
{
java.lang.Object.toString
return twoDigits.format( getHour() ) + ":" +
twoDigits.format( getMinute() ) + ":" +
twoDigits.format( getSecond() );
}
// convert to String in standard-time format
public String toString()
{
return ( ( getHour() == 12 || getHour() == 0 ) ?
12 : getHour() % 12 ) + ":" + twoDigits.format( getMinute() ) +
":" + twoDigits.format( getSecond() ) +
( getHour() < 12 ? " AM" : " PM" );
}
} // end class Time
Time.java
Lines 101-107
Override method
java.lang.Objec
t.toString
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Fig. 10.22: TimeTestWindow.java
JFrame
provides
basic window
// Inner class declarations used to create
event
handlers.
attributes and behaviors
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimeTestWindow extends JFrame {
private Time time;
private JLabel hourLabel, minuteLabel, secondLabel;
private JTextField hourField, minuteField, secondField, displayField;
private JButton exitButton;
// set up GUI
public TimeTestWindow()
{
// call JFrame constructor to set
title bar
string
Instantiate
Time
object
super( "Inner Class Demonstration" );
time = new Time();
Line 7
JFrame provides
basic window
attributes and
JFrame (unlike JApplet)
behaviors
has constructor
// create Time object
// use inherited method getContentPane to get window's content pane
Container container = getContentPane();
container.setLayout( new FlowLayout() ); // change layout
// set up hourLabel and hourField
hourLabel = new JLabel( "Set Hour" );
hourField = new JTextField( 10 );
container.add( hourLabel );
container.add( hourField );
TimeTestWindow.
java
Line 17
JFrame (unlike
JApplet) has
constructor
Line 19
Instantiate Time
object
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// set up minuteLabel and minuteField
minuteLabel = new JLabel( "Set Minute" );
minuteField = new JTextField( 10 );
container.add( minuteLabel );
container.add( minuteField );
TimeTestWindow.
java
// set up secondLabel and secondField
secondLabel = new JLabel( "Set Second" );
secondField = new JTextField( 10 );
container.add( secondLabel );
container.add( secondField );
// set up displayField
displayField = new JTextField( 30 );
displayField.setEditable( false );
container.add( displayField );
// set up exitButton
exitButton = new JButton( "Exit" );
container.add( exitButton );
Line 53
Instantiate object of
inner-class that
implements
ActionListener.
Instantiate object of innerclass that implements
ActionListener
// create an instance of inner class ActionEventHandler
ActionEventHandler handler = new ActionEventHandler();
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// register event handlers; the object referenced by handler
// is the ActionListener, which contains method actionPerformed
// that will be called to handle action events generated by
// hourField, minuteField, secondField and exitButton
hourField.addActionListener( handler );
TimeTestWindow.
Register
minuteField.addActionListener( handler );
java
secondField.addActionListener( handler );
ActionEventHandler
exitButton.addActionListener( handler );
with GUI components
} // end constructor
// display time in displayField
public void displayTime()
{
displayField.setText( "The time is: " + time );
}
// launch application: create, size and display TimeTestWindow;
// when main terminates, program continues execution because a
// window is displayed by the statements in main
public static void main( String args[] )
{
TimeTestWindow window = new TimeTestWindow();
window.setSize( 400, 140 );
window.setVisible( true );
} // end main
Lines 59-62
Register
ActionEventHand
ler with GUI
components.
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// inner class declaration for handling JTextField and JButton events
private class ActionEventHandler implements ActionListener {
// method to handle action events
public void actionPerformed( ActionEvent event )
Declare inner class that implements
{
// user pressed exitButton
ActionListener
interface
When user presses JButton
or Enter key,
if ( event.getSource() == exitButton )
method actionPerformed
is invoked
System.exit( 0 );
// terminate the application
TimeTestWindow.
java
Line 85
Declare inner class
Must implement method actionPerformed
// user pressed Enter key in hourField
Line 88
else if ( event.getSource() == hourField ) { of ActionListener
Must implement
time.setHour( Integer.parseInt(
event.getActionCommand() ) );
method
Determine action
depending
hourField.setText( "" );
actionPerformed
on where event
originated
}
// user pressed Enter key in minuteField
else if ( event.getSource() == minuteField ) {
time.setMinute( Integer.parseInt(
event.getActionCommand() ) );
minuteField.setText( "" );
}
Line 88
When user presses
button or key, method
actionPerformed
is invoked
Lines 91-113
Determine action
depending on where
event originated
108
// user pressed Enter key in secondField
109
else if ( event.getSource() == secondField ) {
110
time.setSecond( Integer.parseInt(
111
event.getActionCommand() ) );
112
secondField.setText( "" );
113
}
114
115
displayTime(); // call outer class's method
116
117
} // end method actionPerformed
118
119
} // end inner class ActionEventHandler
120
121 } // end class TimeTestWindow
TimeTestWindow.
java
TimeTestWindow.
java
10.9 İçiçe Sınıflar (devam.)
• İsimsiz içiçe sınıflar
– Bir sınıfın metodu içinde tanımlanırlar.
– İsimleri yoktur.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Fig. 10.23: TimeTestWindow2.java
// Demonstrating the Time class set and get methods
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimeTestWindow2 extends JFrame {
private Time time;
private JLabel hourLabel, minuteLabel, secondLabel;
private JTextField hourField, minuteField, secondField, displayField;
// constructor
public TimeTestWindow2()
{
// call JFrame constructor to set title bar string
super( "Anonymous Inner Class Demonstration" );
time = new Time();
createGUI();
registerEventHandlers();
// create Time object
// set up GUI
// set up event handling
}
// create GUI components and attach to content pane
private void createGUI()
{
Container container = getContentPane();
container.setLayout( new FlowLayout() );
TimeTestWindow.
java
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
hourLabel = new JLabel( "Set Hour" );
hourField = new JTextField( 10 );
container.add( hourLabel );
container.add( hourField );
minuteLabel = new JLabel( "Set minute" );
minuteField = new JTextField( 10 );
container.add( minuteLabel );
container.add( minuteField );
secondLabel = new JLabel( "Set Second" );
secondField = new JTextField( 10 );
container.add( secondLabel );
container.add( secondField );
displayField = new JTextField( 30 );
displayField.setEditable( false );
container.add( displayField );
} // end method createGUI
// register event handlers for hourField, minuteField and secondField
private void registerEventHandlers()
{
TimeTestWindow.
java
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// register hourField event handler
hourField.addActionListener(
new ActionListener() {
//
Define anonymous inner class that
anonymous
inner class
implements
ActionListener
public void actionPerformed( ActionEvent event )
{
time.setHour( Integer.parseInt(
event.getActionCommand() ) );
hourField.setText( "" );
displayTime();
Inner
}
} // end anonymous inner class
); // end call to addActionListener for
// register minuteField event handler
minuteField.addActionListener(
new ActionListener() {
TimeTestWindow.
java
Line 54
Pass Actionclass implements method
Listener to GUI
actionPerformedcomponent’s
of
method
ActionListeneraddActionListener
hourField Pass ActionListener as
argument to GUI component’s
Line 56
method addActionListener
Define anonymous
inner class
// anonymous inner class
public void actionPerformed( ActionEvent event )
{
Repeat process for JTextField
time.setMinute( Integer.parseInt(
minuteField
event.getActionCommand() ) );
minuteField.setText( "" );
displayTime();
}
Lines 58-64
Inner class
implements method
actionPerformed
Lines 71-85
Repeat process for
minuteField
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
} // end anonymous inner class
); // end call to addActionListener for minuteField
secondField.addActionListener(
new ActionListener() {
TimeTestWindow.
java
Repeat process for JTextField
secondField
// anonymous inner class
public void actionPerformed( ActionEvent event )
{
time.setSecond( Integer.parseInt(
event.getActionCommand() ) );
secondField.setText( "" );
displayTime();
}
} // end anonymous inner class
); // end call to addActionListener for secondField
} // end method registerEventHandlers
// display time in displayField
public void displayTime()
{
displayField.setText( "The time is: " + time );
}
Line 87-101
Repeat process for
JTextField
secondField
110
111
// create TimeTestWindow2 object, register for its window events
112
// and display it to begin application's execution
113
public static void main( String args[] )
114
{
TimeTestWindow.
115
TimeTestWindow2 window = new TimeTestWindow2();
java
116
117
// register listener for windowClosing event
Line 121-129
118
window.addWindowListener(
Declare
Declare anonymous inner
classanonymous
119
inner class that
that extends WindowsAdapter
120
// anonymous inner class for windowClosing event
extends
to enable closing of JFrame
121
new WindowAdapter() {
WindowsAdapter
122
to enable closing of
123
// terminate application when user closes window
124
public void windowClosing( WindowEvent event )
JFrame
125
{
126
System.exit( 0 );
127
}
128
129
} // end anonymous inner class
130
131
); // end call to addWindowListener for window
132
133
window.setSize( 400, 105 );
134
window.setVisible( true );
135
136
} // end main
137
138 } // end class TimeTestWindow2
TimeTestWindow.
java
10.9 İçiçe Sınıflar (devam)
• İçiçe sınıflara için notlar:
– İçiçe sınıf içeren sınıfın derlenmesi
• Ayrı .class uzantılı dosyalarda derleme sonuçlanır.
– İç sınıf aşağıdaki gibi tanımlanır;
• public, protected, private or package access
– Access outer class’s this reference
OuterClassName.this
– Outer class is responsible for creating inner class objects
– Nested classes can be declared static
10.10 Type-Wrapper Classes for Primitive
Types
• Type-wrapper class
– Each primitive type has one
• Character, Byte, Integer, Boolean, etc.
– Enable to represent primitive as Object
• Primitive types can be processed polymorphically
– Declared as final
– Many methods are declared static