Instance Methods and Inheritance (1/2)
1 c l a s s P r o f e s s o r {
2 p u b l i c v o i d s a y _ h e l l o ( ) {
3 System . o u t . p r i n t l n ( " H e l l o ! " ) ;
4 }
5 }
6 c l a s s CSIEProfessor extends P r o f e s s o r {
7 p u b l i c v o i d play_BBS ( ) {
8 System . o u t . p r i n t l n ( " Fun ! " ) ;
9 }
10 }
• CSIEProfessor: two instance methods;
Professor: one instance method
Instance Methods and Inheritance (2/2)
1 c l a s s P r o f e s s o r {
2 p u b l i c v o i d s a y _ h e l l o ( ) {
3 System . o u t . p r i n t l n ( " H e l l o ! " ) ;
4 }
5 }
6 c l a s s CSIEProfessor extends P r o f e s s o r {
7 p u b l i c v o i d s a y _ h e l l o ( ) {
8 System . o u t . p r i n t l n ( " May t h e OOP course be w i t h you ! " ) ;
9 }
10 }
11 / ∗ a l t e r n a t i v e s
12 CSIEProfessor HTLin = new CSIEProfessor ( ) ;
13 P r o f e s s o r HTLin = new CSIEProfessor ( ) ;
14 P r o f e s s o r HTLin = new P r o f e s s o r ( ) ;
15 ∗ /
16 / ∗ c a l l s
17 HTLin . s a y _ h e l l o ( ) ;
18 ∗ /
• which say_hello() will be called?
Instance Methods and Inheritance: Key Point
instance method binding: dynamic, depending
on run-time instance types
Reference Assignment and Inheritance (1/4)
1 c l a s s S t u d e n t { i n t ID ; S t r i n g name ; }
2 c l a s s GodStudent extends S t u d e n t { Award [ ] p r e s i d e n t _ a w a r d s ; }
3
4 p u b l i c c l a s s StudentDemo {
5 p u b l i c s t a t i c s h o w _ s t u d e n t _ i d ( S t u d e n t s ) {
6 System . o u t . p r i n t l n ( s . ID ) ;
7 }
8 p u b l i c s t a t i c v o i d main ( S t r i n g [ ] argv ) {
9 GodStudent h t l i n = new GodStudent ( ) ;
10 s h o w _ s t u d e n t _ i d ( h t l i n ) ;
11 S t u d e n t C h a r l i e L = new S t u d e n t ( ) ;
12 s h o w _ s t u d e n t _ i d ( C h a r l i e L ) ;
13 }
14 }
• htlin refers to an instance of GodStudent (for sure!)
• htlin refers to an instance of Student as well
• one instance, many coherent types (in argument passing, return
Reference Assignment and Inheritance (2/4)
1 c l a s s S t u d e n t { i n t ID ; S t r i n g name ; }
2 c l a s s GodStudent extends S t u d e n t { Award [ ] p r e s i d e n t _ a w a r d s ; }
3
4 p u b l i c c l a s s StudentDemo {
5 p u b l i c s t a t i c v o i d main ( S t r i n g [ ] argv ) {
6 GodStudent h t l i n = new GodStudent ( ) ;
7 / / I want t o be a u s u a l s t u d e n t
8 S t u d e n t u s u a l s t u d e n t = h t l i n ;
9 S t u d e n t a n o t h e r u s u a l s t u d e n t = new S t u d e n t ( ) ;
10 }
11 }
• if “copying assignment”, a copy of htlin can be a usual student
• but “reference assignment” in Java, how can htlin be usual?
• mechanism?
Reference Assignment and Inheritance (3/4)
1 c l a s s S t u d e n t { i n t ID ; S t r i n g name ; }
2 / / t a k e s 4 + ( 8 ) b y t e s
3 c l a s s GodStudent extends S t u d e n t { Award [ ] p r e s i d e n t _ a w a r d s ; }
4 / / t a k e s 4 + ( 8 ) + ( 8 ) b y t e s
5
6 / ∗ ∗ e x c l u d i n g some o t h e r i n f o r m a t i o n , much l i k e
7 c l a s s GodStudent {
8 / / f i r s t 4 + ( 8 ) b y t e s ( f o r S t u d e n t )
9 i n t ID ;
10 S t r i n g name ;
11 / / l a s t ( 8 ) b y t e s ( f o r GodStudent )
12 Award [ ] p r e s i d e n t _ a w a r d s ;
13 } / / t a k e s 4 + ( 8 ) + ( 8 ) b y t e s
14 ∗ ∗ /
• one possible mechanism for single inheritance (Java!!): shared
prefix (virtually)
Reference Assignment and Inheritance (4/4)
1 c l a s s S t u d e n t { i n t ID ; S t r i n g name ; }
2 / / c l a s s S t u d e n t { i n t 000; r e f e r e n c e 004; }
3 c l a s s GodStudent extends S t u d e n t { Award [ ] p r e s i d e n t _ a w a r d s ; }
4 / / c l a s s GodStudent { i n t 000; r e f e r e n c e 004; r e f e r e n c e 012; }
• one possible mechanism: variable name ⇒ a single number when class loads
• (after instance type check) objects can just safely access memory
contents by numbers
Reference Assignment and Inheritance: Key Point
a simple run-time mechanism (shared prefix):
ancestor first, descendant last
Constructor and Inheritance (1/3)
1 c l a s s S t u d e n t { i n t ID ; S t r i n g name ;
2 S t u d e n t (i n t ID , S t r i n g name ) {t h i s. ID = ID ; t h i s. name = name ; }
3 }
4 c l a s s AwardStudent extends S t u d e n t {
5 Award [ ] awards ;
6 AwardStudent (i n t ID , S t r i n g name , i n t nAward ) {
7 super( ID , name ) ; / / means i n v o k e S t u d e n t ( ID , name ) ;
8 awards = new Award [ nAward ] ;
9 }
10 }
• initialize the ancestor part first
• construct AwardStudent ⇒ (i.e. calls) construct Student
• thus, the “Student” parts of the memory are initialized first, then
the “AwardStudent” part
Constructor and Inheritance (2/3)
1 c l a s s S t u d e n t { i n t ID ; S t r i n g name ;
2 S t u d e n t (i n t ID , S t r i n g name ) {t h i s. ID = ID ; t h i s. name = name ; }
3 }
4 c l a s s AwardStudent extends S t u d e n t {
5 Award [ ] awards ;
6 AwardStudent (i n t ID , S t r i n g name , i n t nAward ) {
7 super( ID , name ) ; / / means i n v o k e S t u d e n t ( ID , name ) ;
8 / / any u t i l i t y f u n c t i o n i n S t u d e n t can be used a t t h i s st age
9 awards = new Award [ nAward ] ;
10 }
11 }
• super goes first so that there is a valid “Student” object in the
very beginning
Constructor and Inheritance (3/3)
1 c l a s s S t u d e n t / ∗ extends O b j e c t ∗ / {
2 i n t ID ; S t r i n g name ;
3 S t u d e n t (i n t ID , S t r i n g name ) {t h i s. ID = ID ; t h i s. name = name ; }
4 / ∗
5 S t u d e n t ( i n t ID , S t r i n g name ) {
6 super ( ) ; / / l i k e O b j e c t ( ) ;
7 t h i s . ID = ID ; t h i s . name = name ;
8 }
9 ∗ /
10 }
11 c l a s s AwardStudent extends S t u d e n t {
12 Award [ ] awards ;
13 AwardStudent (i n t ID , S t r i n g name , i n t nAward ) {
14 / / ?
15 }
16 }
• super() automatically added if no explicit call in the beginning
A Fallback: Constructor Calls
1 c l a s s Record {
2 S t r i n g name ; i n t s co re ;
3 Record (i n t i n i t _ s c o r e ) { sc or e = i n i t _ s c o r e ; }
4 Record ( ) { Record ( 4 0 ) ; }
5 }
6 p u b l i c c l a s s RecordDemo {
7 p u b l i c s t a t i c v o i d main ( S t r i n g [ ] arg ) {
8 Record r 1 = new Record ( 6 0 ) ;
9 Record r 2 = new Record ( ) ;
10 System . o u t . p r i n t l n ( r 1 . sc or e ) ;
11 System . o u t . p r i n t l n ( r 2 . sc or e ) ;
12 }
13 }
• there is a bug above
• one constructor can only call one other constructor (via this or
super)
Constructor and Inheritance: Key Point
calls ancestor constructor first
(and thus ancestor forms first)
Private Variables and Inheritance (1/1)
1 c l a s s P a r e n t {
2 p r i v a t e i n t hidden_money ;
3 p u b l i c v o i d show_hidden_money_amount ( ) { }
4 }
5 c l a s s C h i l d extends P a r e n t {
6 v o i d spend_money ( ) {
7 / / can hidden_money be spe nt here ?
8 / / can show_hidden_money_amount ( ) be c a l l e d here ?
9 }
10 }
• (1) not directly (2) yes
• does Child have a hidden_money slot in the memory?
•
yes, to make show_hidden_money_amount() work!
•
yes, to make the shared prefix mechanism work!
Private Variables and Inheritance: Key Point
private variables are still “inherited” in memory,
but not “visible” to the subclass because of en-
capsulation
Private Methods and Inheritance (1/1)
1 c l a s s P a r e n t {
2 p r i v a t e i n t hidden_money ;
3 p r i v a t e v o i d b u y _ l i q u o r ( ) { }
4 p u b l i c v o i d show_hidden_money_amount ( ) { }
5 }
6 c l a s s C h i l d extends P a r e n t {
7 v o i d buy ( ) {
8 / / can b u y _ l i q u o r ( ) be c a l l e d here ?
9 }
10 }
• no, because cannot see
• private methods effectively not inherited
Private Methods and Inheritance: Key Point
private methods effectively not inherited be-
cause not “visible” to the subclass
More on Access Permissions (1/2)
1 package g e n e r a t i o n . o l d ;
2 c l a s s P a r e n t {
3 p r i v a t e i n t hidden_money ;
4 p u b l i c v o i d show_hidden_money_amount ( ) { }
5 / ∗ d e f a u l t ∗ / v o i d middle_age_issues ( ) ;
6 / ∗ d e f a u l t ∗ / v o i d c r o s s _ g e n _ i s s u e s ( ) ;
7 }
8 / / d i f f e r e n t f i l e , C h i l d . j a v a
9 package g e n e r a t i o n .new;
10 c l a s s C h i l d extends P a r e n t {
11 }
• in Child, can hidden_money be accessed? no.
• can show_hidden_money_amount be accessed? yes.
• can middle_age_issues be accessed? no.
• can cross_gen_issues be accessed? no.
—what if we want “yes”?
More on Access Permissions (2/2)
1 package g e n e r a t i o n . o l d ;
2 p u b l i c c l a s s P a r e n t {
3 p r i v a t e i n t hidden_money ;
4 p u b l i c v o i d show_hidden_money_amount ( ) { }
5 / ∗ d e f a u l t ∗ / v o i d middle_age_issues ( ) ;
6 p r o t e c t e d v o i d c r o s s _ g e n _ i s s u e s ( ) ;
7 }
8 / / d i f f e r e n t f i l e , C h i l d . j a v a
9 package g e n e r a t i o n .new;
10 c l a s s C h i l d extends P a r e n t {
11 }
• can cross_gen_issues be accessed? no.
—what if we want “yes”?
• protected: accessible to Child (sub-classes) and Friend
(same-package-classes)
More on Access Permissions: Key Point
public: accessible to everyone
protected: accessible to sub-classes and same-package-classes
(default): accessible to same-package- classes
private: accessible within my class defini-
tions
Permissions and Method Overriding (1/1)
1 p u b l i c c l a s s P a r e n t {
2 p r o t e c t e d v o i d method ( ) { }
3 }
4 c l a s s C h i l d extends P a r e n t {
5 p u b l i c v o i d method ( ) { } / / ?
6 p r i v a t e v o i d method ( ) { } / / ?
7 }
8
9 / / bottom l i n e
10 P a r e n t v a r = new C h i l d ( ) ;
11 v a r . method ( ) ;