Prof. Dr. A. Poetzsch-Heffter Dipl.-Inform. Kathrin Geilmann
University of Kaiserslautern Department of Computer Science Software Technology Group
Advanced Aspects of Object-Oriented Programming (SS 2011) Practice Sheet 2 Date of Issue: 19.04.11
Deadline: 26.04.11 (until 10 a.m. as PDF via E-Mail)
Exercise 1 Happy Birthday
In a software project, the classes Person, AgePerson und AgeManager were implemented; their source is given in Figure 1.
a) For testing purposes, the following code is used.
. . .
AgeManager a g e M a n a g e r=new AgeManager ( ) ;
A g e P e r s o n a g e P e r s o n =new A g e P e r s o n ( " J a n e " , " Doe " , 2 8 ) ; a g e M a n a g e r . add ( " 0 2 . 0 2 . 1 9 8 0 " , a g e P e r s o n ) ;
w h i l e(t r u e) {
S y s t e m . o u t . p r i n t l n ( " I s"+a g e P e r s o n+"managed :"+a g e M a n a g e r . i s M a n a g e d ( a g e P e r s o n ) ) ; T h r e a d . s l e e p ( 5 0 0 0 ) ;
} . . .
Explain the following output:
Is Jane Doe managed: true Jane Doe: Age updated.
Is Jane Doe managed: false Jane Doe: Age updated.
Is Jane Doe managed: false Jane Doe: Age updated.
Jane Doe: Age updated.
Is Jane Doe managed: false ...
Hint: Look into the documentation for Object.hashCode and Map b) Give a general programming guideline that helps to avoid theses problems.
c) Explain why the parameter birthday in AgeManager.add has to be final.
Exercise 2 Source Compatibility of Java-Packages
The packages of a software implementation usually evolves is di ff erent ways. A package may be exchanged by another one, classes, fields and methods can be added or removed, and so on. For the developer of the package it is important to know, wether his changes are source compatible or not. A change breaks source compatibility, if a program exists that compiles with the unchange package version but does not compile with the changed one.
Look at the following packages. Is it safe to make the given modifications? If not, give counter examples.
/ / u n m o d i f i e d v e r s i o n package u t i l ;
p u b l i c i n t e r f a c e L i s t { p u b l i c a b s t r a c t L i s t n ( ) ; }
/ / m o d i f i e d v e r s i o n package u t i l ;
p u b l i c i n t e r f a c e L i s t { p u b l i c a b s t r a c t L i s t n ( ) ; p u b l i c a b s t r a c t L i s t m( ) ; }
/ / u n m o d i f i e d v e r s i o n
package p ;
p u b l i c f i n a l c l a s s C { p r o t e c t e d C m( O b j e c t v ) {}
}}
/ / m o d i f i e d v e r s i o n
package p ;
p u b l i c c l a s s C { p u b l i c C m( C v ) {}
}}
p u b l i c c l a s s P e r s o n { p r o t e c t e d S t r i n g f i r s t n a m e ; p r o t e c t e d S t r i n g l a s t n a m e ; p u b l i c P e r s o n ( S t r i n g f i r s t n a m e ,
S t r i n g l a s t n a m e ) { t h i s. f i r s t n a m e=f i r s t n a m e ; t h i s. l a s t n a m e =l a s t n a m e ; }
p u b l i c b o o l e a n e q u a l s ( O b j e c t s e c o n d ) { i f ( s e c o n d . g e t C l a s s ( )==g e t C l a s s ( ) ) {
P e r s o n p e r s o n=( P e r s o n ) s e c o n d ;
r e t u r n( p e r s o n . f i r s t n a m e . e q u a l s ( f i r s t n a m e ) &&
p e r s o n . l a s t n a m e . e q u a l s ( l a s t n a m e ) ) ; }
r e t u r n(f a l s e) ; }
p u b l i c i n t h a s h C o d e ( ) { r e t u r n( f i r s t n a m e . h a s h C o d e ( ) ^
l a s t n a m e . h a s h C o d e ( ) ) ; }
p u b l i c S t r i n g t o S t r i n g ( ) { r e t u r n( f i r s t n a m e+""+l a s t n a m e ) ; }
}
p u b l i c c l a s s A g e P e r s o n e x t e n d s P e r s o n { p r i v a t e i n t a g e ;
p u b l i c A g e P e r s o n ( S t r i n g f i r s t n a m e , S t r i n g l a s t n a m e , i n t a g e ) { s u p e r( f i r s t n a m e , l a s t n a m e ) ; t h i s. a g e=a g e ;
}
p u b l i c v o i d u p d a t e A g e ( ) { a g e++;
S y s t e m . o u t . p r i n t l n (t h i s+" :Ageu p d a t e d . " ) ; }
p u b l i c b o o l e a n e q u a l s ( O b j e c t s e c o n d ) { i f ( s e c o n d . g e t C l a s s ( )==g e t C l a s s ( ) ) {
A g e P e r s o n a g e P e r s o n=( A g e P e r s o n ) s e c o n d ;
r e t u r n( a g e P e r s o n . f i r s t n a m e . e q u a l s ( f i r s t n a m e ) &&
a g e P e r s o n . l a s t n a m e . e q u a l s ( l a s t n a m e ) &&
a g e P e r s o n . a g e==a g e ) ; }
r e t u r n(f a l s e) ; }
p u b l i c i n t h a s h C o d e ( ) { r e t u r n(s u p e r. h a s h C o d e ( ) ^ a g e ) ; }
}
i m p o r t j a v a . u t i l .∗; i m p o r t j a v a . u t i l . Map .∗; i m p o r t j a v a . t e x t .∗; p u b l i c c l a s s AgeManager {
p r i v a t e Map<A g e P e r s o n , C a l e n d a r>
p e r s o n s=new HashMap<A g e P e r s o n , C a l e n d a r>( ) ; p r i v a t e C a l e n d a r
c u r r e n t D a t e=new G r e g o r i a n C a l e n d a r ( ) ; p u b l i c AgeManager ( ) {
new T i m e r ( ) . s c h e d u l e (new T i m e r T a s k ( ) { p u b l i c v o i d r u n ( ) {
c u r r e n t D a t e . add ( C a l e n d a r . DAY_OF_MONTH, 1 ) ; u p d a t e A g e s ( c u r r e n t D a t e ) ;
}
} ,new D a t e ( ) , 1 0 ) ; }
p r o t e c t e d s y n c h r o n i z e d v o i d u p d a t e A g e s ( C a l e n d a r d a t e ) { i n t month=d a t e . g e t ( C a l e n d a r .MONTH) ;
i n t day =d a t e . g e t ( C a l e n d a r . DAY_OF_MONTH ) ;
f o r( E n t r y<A g e P e r s o n , C a l e n d a r> e n t r y : p e r s o n s . e n t r y S e t ( ) ) i f ( ( e n t r y . g e t V a l u e ( ) . g e t ( C a l e n d a r .MONTH)==month ) &&
( e n t r y . g e t V a l u e ( ) . g e t ( C a l e n d a r . DAY_OF_MONTH)==day ) ) e n t r y . g e t K e y ( ) . u p d a t e A g e ( ) ;
}
p u b l i c s y n c h r o n i z e d v o i d add (f i n a l S t r i n g b i r t h d a y , A g e P e r s o n p e r s o n ) t h r o w s P a r s e E x c e p t i o n { p e r s o n s . p u t ( p e r s o n ,new G r e g o r i a n C a l e n d a r ( ) {{
s e t T i m e ( D a t e F o r m a t . g e t D a t e I n s t a n c e ( ) . p a r s e ( b i r t h d a y ) ) ; } } ) ;
}
p u b l i c s y n c h r o n i z e d b o o l e a n i s M a n a g e d ( A g e P e r s o n p e r s o n ) { r e t u r n( p e r s o n s . c o n t a i n s K e y ( p e r s o n ) ) ;
} }