You are on page 1of 47

1

C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK


VIK
UNIT- 4 OBJECT- ORIENTED PROGRAMMING WITH C#
Understanding the C# Cass T!"e
The power of object-oriented languages is that by grouping data and functionality
in a single UDT (User Define Type), you are able to model your software types
after real-world entities.
For eample, a generic employee for a payroll system!
o " class that maintains the name, current pay, and employee #D for each
wor$er.
o The %mployee class defines one method, named Gi#eB$n%s&'( which
increases an indi&idual's current pay by some amount, and method
Dis"a!)tats&'( which prints out the state data for this indi&idual.
%&ery () class is initially pro&ided with a default constructor, which by definition
ne&er ta$es arguments. "nd e&en we can create the own constructor.
** The initia E+"$!ee ,ass de-initi$n.
na+es"a,e E+"$!ees
/
"%0i, ,ass E+"$!ee
/
** 1ied data.
2
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"ri#ate string -%Na+e2
"ri#ate int e+"ID2
"ri#ate -$at ,%rrPa!2
** C$nstr%,t$rs.
"%0i, E+"$!ee&'/ 3
"%0i, E+"$!ee&string -%Na+e( int e+"ID( -$at ,%rrPa!'
/
this.-%Na+e 4 -%Na+e2
this.e+"ID 4 e+"ID2
this.,%rrPa! 4 ,%rrPa!2
3
** B%+" the "a! -$r this e+"$!ee.
"%0i, #$id Gi#eB$n%s&-$at a+$%nt'
/ ,%rrPa! 54 a+$%nt2 3
** )h$6 ,%rrent state $- this $07e,t.
"%0i, #$id Dis"a!)tats&'
/
C$ns$e.Write8ine&9Na+e: /;3 9( -%Na+e'2
C$ns$e.Write8ine&9Pa!: /;3 9( ,%rrPa!'2
C$ns$e.Write8ine&9ID: /;3 9( e+"ID'2
3
3
3
#n c), *ere is empty implementation of the default constructor for the %mployee
class.
public class %mployee
/
...
"%0i, E+"$!ee&'/ 3
...
3
3
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
#n (++ and ,a&a, if you choose to define custom constructors in a class definition, the
default constructor is silently remo&ed.
To allow the object user to create an instance of your class as follows!
stati, #$id Main&string<= args'
/
** Cas the de-a%t ,$nstr%,t$r.
E+"$!ee e 4 ne6 E+"$!ee&'2
3
#f you not create an instance of class you will recei&e a compiler error when
creating an instance of your class type using the default constructor.
The following -ain() method creates a few %mployee objects using our custom three-
argument constructor!
** Ma>e s$+e E+"$!ee $07e,ts.
stati, #$id Main&string<= args'
/
E+"$!ee e 4 ne6 E+"$!ee&9J$e9( ?;( @;;;;'2
E+"$!ee eA2
eA 4 ne6 E+"$!ee&9Beth9( ?B( C;;;;'2
C$ns$e.Read8ine&'2
3
Understanding Meth$d O#er$ading
() allows a type to o&erload &arious methods. .hen a class has a set of
identically named members that differ by the number (or type) of parameters,
then the member is said to be o&erloaded.
For eample, the %mployee class
"%0i, ,ass E+"$!ee
4
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
/
...** O#er$aded ,$nstr%,t$rs.
"%0i, E+"$!ee&'/ 3
"%0i, E+"$!ee&string -%Na+e( int e+"ID( -$at ,%rrPa!'/...3
...3
.hen you are o&erloading a member, the return type alone is not uni/ue enough.
Thus, the following is illegal!
"%0i, ,ass Triange
/
...
** Err$rD Cann$t $#er$ad +eth$ds 0ased s$e! $n ret%rn
#a%esD
"%0i, -$at GetE&' /...3
"%0i, int GetE&' /...3
3
)e--Re-eren,e in C# Using this
The custom constructor of the %mployee class ma$es use of the () this
$eyword!
** EF"i,it! %se 9this9 t$ res$#e na+e-,ash.
"%0i, E+"$!ee&string -%Na+e( int e+"ID( -$at ,%rrPa!'
/
** Assign the in,$+ing "ara+s t$ +! state data.
this.-%Na+e 4 -%Na+e2
this.e+"ID 4 e+"ID2
this.,%rrPa! 4 ,%rrPa!2
3
The reason to use of this in custom constructor was to a#$id ,ashes 0et6een
the "ara+eter na+es and na+es $- !$%r interna state #aria0es.
"nother approach would be to change the names for each parameter and a&oid
the name clash altogether!
5
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
** When there is n$ na+e ,ash( 9this9 is ass%+ed.
"%0i, E+"$!ee&string na+e( int id( -$at "a!'
/
-%Na+e 4 na+e2
e+"ID 4 id2
,%rrPa! 4 "a!2
3
#n this case, we ha&e no need to eplicitly prefi this $eyword to the %mployee's
member &ariables, because we ha&e remo&ed the name clash. The compiler can
resol&e the scope of these member &ariables using what is $nown as an i+"i,t
this.
.hen your class references its own field data and member &ariables (in an
unambiguous manner), this is assumed.
"%0i, E+"$!ee&string na+e( int id( -$at "a!'
/
this.-%Na+e 4 na+e2
this.e+"ID 4 id2
this.,%rrPa! 4 "a!2
3
1$r6arding C$nstr%,t$r Cas Using this
"nother use of this $eyword is to force one constructor to call another in order to
a&oid redundant member initiali0ation logic. (onsider the following update to the
%mployee class!
"%0i, ,ass E+"$!ee
/
...
"%0i, E+"$!ee&string -%Na+e( int e+"ID( -$at ,%rrPa!'
/
this.-%Na+e 4 -%Na+e2
this.e+"ID 4 e+"ID2
this.,%rrPa! 4 ,%rrPa!2
6
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
3
** I- the %ser ,as this ,t$r( -$r6ard t$ the @-arg #ersi$n.
"%0i, E+"$!ee&string -%Na+e'
: this&-%Na+e( IDGenerat$r.GetNe6E+"ID&'( ;.;1' / 3
...
3
This iteration of the %mployee class defines two custom constructors, the second
of which re/uires a single parameter (the indi&idual's name). *owe&er, to fully
construct a new %mployee, you want to ensure you ha&e a proper #D and rate of
pay.
"ssume you ha&e created a custom class (#D1enerator) that defines a static
method named GetNe6E+"ID&'( which generates a new employee #D (in some
way or another). 2nce you gather the correct set of startup parameters, you
forward the creation re/uest to the alternate three-argument constructor.
#f you did not forward the call, you would need to add redundant code to each
constructor!
** ,%rrPa! a%t$+ati,a! set t$ ;.;1 #ia de-a%t #a%es.
"%0i, E+"$!ee&string -%Na+e'
/
this.-%Na+e 4 -%Na+e2
this.e+"ID 4 IDGenerat$r.GetNe6E+"ID&'2
3
Understand that using the this $eyword to forward constructor calls is not
mandatory. *owe&er, when you ma$e use of this techni/ue, you do tend to end
up with a more maintainable and concise class definition.
De-ining the P%0i, Inter-a,e $- a Cass
The term refers to the set of members that are directly accessible from an object
&ariable &ia the dot operator.
7
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
The "%0i, inter-a,e is any item declared in a class using the "%0i, >e!6$rd.
3eyond field data and constructors, the public interface of a class may be
implemented by numerous members, including the following!
o -ethods! 4amed units of wor$ that model some beha&ior of a class
o 5roperties! Traditional accessor and mutator functions in disguise
o (onstants67ead-only fields! Field data that cannot be changed after
assignment
1i&en that our %mployee currently defines two public methods (1i&e3onus() and
Display8tats()), we are able to interact with the public interface as follows!
** Intera,t 6ith the "%0i, inter-a,e $- the E+"$!ee ,ass t!"e.
stati, #$id Main&string<= args'
/
C$ns$e.Write8ine&9GGGGG The E+"$!ee T!"e at W$r> GGGGGHn9'2
E+"$!ee e 4 ne6 E+"$!ee&9J$e9( ?;( @;;;;'2
e.Gi#eB$n%s&A;;'2
e.Dis"a!)tats&'2
E+"$!ee eA2
eA 4 ne6 E+"$!ee&9Beth9( ?B( C;;;;'2
eA.Gi#eB$n%s&B;;;'2
eA.Dis"a!)tats&'2
C$ns$e.Read8ine&'2
3
O%t"%t:
99999 The %mployee Type at .or$ 99999
4ame! ,oe
5ay!:;<;;
#d!=;
4ame! 3eth
5ay!>?;;;
8
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
#d!=?
The Piars $- OOP
"ll object-oriented languages contend with three core principles of object-
oriented programming, often called the famed @pillars of 225.A
o En,a"s%ati$n: *ow does this language hide an object's internal
implementationB
o Inheritan,e: *ow does this language promote code reuseB
o P$!+$r"his+: *ow does this language let you treat related objects in a
similar wayB
En,a"s%ati$n
%ncapsulation enables the language's ability to hide unnecessary implementation
details from the object user.
1$r eFa+"e:
** Data0aseReader en,a"s%ates the detais $- data0ase +ani"%ati$n.
Data0aseReader d0O07 4 ne6 Data0aseReader&'2
d0O07.O"en&I9C:HE+"$!ees.+d-9'2
** D$ s$+ething 6ith data0ase...
d0O07.C$se&'2
The Database7eader class has encapsulated the inner details of locating,
loading, manipulating, and closing the data file.
There is no need to worry about the numerous lines of code that are wor$ing
behind the scenes to carry out the wor$ of the Database7eader class.
"nother aspect of encapsulation is the notion of data protection.
Inheritan,e
9
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
#nheritance enables the language's ability to allow you to build new class
definitions based on eisting class definitions.
#nheritance allows you to etend the beha&ior of a 0ase &$r "arent' ,ass by
enabling a s%0,ass to inherit core functionality (also called a deri&ed class or
child class).
Figure illustrates the @is-aA relationship.
7ead as @" heagon is-a shape that is-an object.A
The @is-aA relationship is often termed ,assi,a inheritan,e.
8ystem.2bject is the ultimate base class in any .4%T hierarchy.
*ere, the 8hape class etends 2bject. 8hape defines some number of
properties, fields, methods, and e&ents that are common to all shapes. The
*eagon class etends 8hape and inherits the functionality defined by 8hape
and 2bject.
There is another form of code reuse in the world of 225! the
containment6delegation model (also $nown as the @has-aA relationship). This form
of reuse is not used to establish base6subclass relationships.
Two independent classes wor$ing together, where the containing class creates
and eposes the contained class's functionality!
"%0i, ,ass Radi$
/
"%0i, #$id P$6er&0$$ t%rnOn'
/ C$ns$e.Write8ine&9Radi$ $n: /;39( t%rnOn'23
10
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
3
"%0i, ,ass Car
/ ** Car 9has-a9 Radi$.
"ri#ate Radi$ +!Radi$ 4 ne6 Radi$&'2
"%0i, #$id T%rnOnRadi$&0$$ $nO--'
/ ** Deegate t$ inner $07e,t.
+!Radi$.P$6er&$nO--'2
3
3
*ere, the containing type ((ar) is responsible for creating the contained object
(7adio).
stati, #$id Main&string<= args'
/
** Ca is -$r6ard t$ Radi$ interna!.
Car #i"er 4 ne6 Car&'2
#i"er.T%rnOnRadi$&tr%e'2
3
P$!+$r"his+
P$!+$r"his+ enables a language's ability to treat related objects the same
way. This tenent of an object-oriented language allows a base class to define a
set of members (Formally termed the "$!+$r"hi, inter-a,e) to all
descendents. " class type's polymorphic interface is constructed using any
number of &irtual or abstract members.
The 8hape class has defined a method named Draw(), ta$ing no parameters and
returning nothing.
11
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
For eample, gi&en that *eagon and (ircle deri&e from a common parent (8hape), an
array of 8hape types could contain any deri&ed class.
*ere -ain() method, which instructs an array of 8hape-deri&ed types to render
themsel&es using the Draw() method!
stati, #$id Main&string<= args'
/
** Create an arra! $- )ha"e deri#ed ite+s.
)ha"e<= +!)ha"es 4 ne6 )ha"e<@=2
+!)ha"es<;= 4 ne6 HeFag$n&'2
+!)ha"es<B= 4 ne6 Cir,e&'2
+!)ha"es<A= 4 ne6 HeFag$n&'2
** Iterate $#er the arra! and dra6 ea,h ite+.
-$rea,h &)ha"e s in +!)ha"es'
s.Dra6&'2
C$ns$e.Read8ine&'2
3
The First Pillr! C#"s E#$%s&lti'# (er)i$es
The concept of encapsulation re&ol&es around the notion that an object's field
data should not be directly accessible from the public interface.
#n (), encapsulation is enforced at the syntactic le&el using the public, pri&ate,
protected, and protected internal $eywords.
12
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
To illustrate the need for encapsulation, assume you ha&e created the following
class definition!
** A ,ass 6ith a singe "%0i, -ied.
"%0i, ,ass B$$>
/
"%0i, int n%+0erO-Pages2
3
The problem with public field data is that the items ha&e no ability to @understandA
whether the current &alue to which they are assigned is &alid.
The upper range of a () int is /uite large (<,?CD,C=:,ECD). Therefore, the
compiler allows the following assignment!
** H%++...
stati, #$id Main&string<= args'
/
B$$> +iniN$#e 4 ne6 B$$>&'2
+iniN$#e.n%+0erO-Pages 4 @;;;;;;;2
3
%ncapsulation pro&ides a way to preser&e the integrity of state data.
Defining pri&ate data fields, which are indirectly manipulated by the caller using
one of two main techni/ues!
?. Define a pair of traditional accessor and mutator methods.
<. Define a named property.
.hiche&er techni/ue you choose, the point is that a well-encapsulated class
should hide its raw data and the details of how it operates. This is often termed
0a,> 0$F "r$gra++ing.
En-$r,ing En,a"s%ati$n Using Traditi$na A,,ess$rs and M%tat$rs
** Traditi$na a,,ess$r and +%tat$r -$r a "$int $- "ri#ate data.
"%0i, ,ass E+"$!ee
/
13
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"ri#ate string -%Na+e2
...
** A,,ess$r.
"%0i, string Get1%Na+e&' / ret%rn -%Na+e2 3
** M%tat$r.
"%0i, #$id )et1%Na+e&string n'
/
** Re+$#e an! iega ,hara,ters &D( I( #( J( K'(
** ,he,> +aFi+%+ ength &$r ,ase r%es' 0e-$re +a>ing assign+ent.
-%Na+e 4 n2
3
3
1i&en the fact that 1etFull4ame() and 8etFull4ame() encapsulate a pri&ate string
named full4ame.
The ,aing $gi, is as -$$6s:
** A,,ess$r*+%tat$r %sage.
stati, #$id Main&string<= args'
/
E+"$!ee " 4 ne6 E+"$!ee&'2
".)et1%Na+e&91red 1intst$ne9'2
C$ns$e.Write8ine&9E+"$!ee is na+ed: /;39( ".Get1%Na+e&''2
C$ns$e.Read8ine&'2
3
An$ther 1$r+ $- En,a"s%ati$n: Cass Pr$"erties
** )etting * getting a "ers$nLs ID thr$%gh "r$"ert! s!ntaF.
stati, #$id Main&string<= args'
/
E+"$!ee " 4 ne6 E+"$!ee&'2
** )et the #a%e.
".ID 4 ?B2
** Get the #a%e.
14
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
C$ns$e.Write8ine&9Pers$n ID is: /;3 9( ".ID'2
C$ns$e.Read8ine&'2
3
M *ere is the () synta behind the #D property, another property (5ay) that
encapsulates the curr5ay field, and a final property (4ame) to encapsulate the
full4ame data point.
** En,a"s%ati$n 6ith "r$"erties.
"%0i, ,ass E+"$!ee
/
...
"ri#ate int e+"ID2
"ri#ate -$at ,%rrPa!2
"ri#ate string -%Na+e2
** Pr$"ert! -$r e+"ID.
"%0i, int ID
/
get / ret%rn e+"ID23
set
/
** N$% are sti -ree t$ in#estigate &and "$ssi0! trans-$r+'
** the in,$+ing #a%e 0e-$re +a>ing an assign+ent.
e+"ID 4 #a%e2
3
3
** Pr$"ert! -$r -%Na+e.
"%0i, string Na+e
/
get /ret%rn -%Na+e23
set /-%Na+e 4 #a%e23
3
** Pr$"ert! -$r ,%rrPa!.
15
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"%0i, -$at Pa!
/
get /ret%rn ,%rrPa!23
set /,%rrPa! 4 #a%e23
3
3
M " () property is composed using a get bloc$ (accessor) and set bloc$ (mutator).
The () @&alueA to$en represents the right-hand side of the assignment. The
underlying data type of the &alue to$en depends on which sort of data it
represents.
** ?B is a )!ste+.Int@A( s$ 9#a%e9 is a )!ste+.Int@A.
E+"$!ee e 4 ne6 E+"$!ee&'2
e.ID 4 ?B2
M To pro&e the point, assume you ha&e updated the #D property's set logic as
follows!
** Pr$"ert! -$r the e+"ID.
"%0i, int ID
/
get / ret%rn e+"ID23
set
/
C$ns$e.Write8ine&9#a%e is an instan,e $-: /;3 9( #a%e.GetT!"e&''2
C$ns$e.Write8ine&9#a%eLs #a%e: /;3 9( #a%e'2
e+"ID 4 #a%e2
3
3
M To illustrate, assume that the %mployee class type has an internal pri&ate
member &ariable representing the age of the employee.
"%0i, ,ass E+"$!ee
/
...
** C%rrent age $- e+"$!ee.
16
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"ri#ate int e+"Age2
"%0i, E+"$!ee&string -%Na+e( int age( int e+"ID( -$at
,%rrPa!'
/
...
this.e+"Age 4 age2
3
"%0i, int Age
/
get/ret%rn e+"Age23
set/e+"Age 4 #a%e23
3
"%0i, #$id Dis"a!)tats&'
/
...
C$ns$e.Write8ine&9Age: /;3 9( e+"Age'2
3
3
M Using traditional accessor and mutator methods, you would need to write code
such as the following!
E+"$!ee 7$e 4 ne6 E+"$!ee&'2
7$e.)etAge&7$e.GetAge&' 5 B'2
M *owe&er, if you encapsulate emp"ge using property synta, you are able to
simply write
E+"$!ee 7$e 4 ne6 E+"$!ee&'2
7$e.Age552
Interna Re"resentati$n $- C# Pr$"erties
-any programmers (especially those of the (++ il$) tend to design traditional
accessor and mutator methods using @getFA and @setFA prefies (e.g.,
getFFull4ame() and setFFull4ame()).
17
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
For eample, if you open up the %mployees.ee assembly using ildasm.ee, you
see that each property actually resol&es to hidden getFGGG()6setFGGG()
methods.
"ssume the %mployee type now has a pri&ate member &ariable named emp884 to
represent an indi&idual's 8ocial 8ecurity number, which is manipulated by a property
named 8ocial8ecurity4umber and set &ia constructor parameter.
** Add s%""$rt -$r a ne6 -ied re"resenting the e+"$!eeLs ))N.
"%0i, ,ass E+"$!ee
/
...
** )$,ia )e,%rit! N%+0er.
"ri#ate string e+"))N2
"%0i, E+"$!ee&string -%Na+e( int age( int e+"ID(
-$at ,%rrPa!( string ssn'
/
...
this.e+"))N 4 ssn2
3
"%0i, string )$,ia)e,%rit!N%+0er
/
get / ret%rn e+"))N2 3
18
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
set / e+"))N 4 #a%e23
3
"%0i, #$id Dis"a!)tats&'
/
...
C$ns$e.Write8ine&9))N: /;3 9( e+"))N'2
3
3
#f you were to also define two methods named getF8ocial8ecurity4umber() and
setF8ocial8ecurity4umber(), you would be issued compile-time errors!
** Re+e+0er( a C# "r$"ert! rea! +a"s t$ a getO*setO "air.
"%0i, ,ass E+"$!ee
/
...
** ERRORD Aread! de-ined %nder the h$$d 0! the "r$"ert!D
"%0i, string getO)$,ia)e,%rit!N%+0er&' /ret%rn e+"))N23
"%0i, #$id setO)$,ia)e,%rit!N%+0er &string #a' /e+"))N 4 #a23
3
C$ntr$ing Pisi0iit! 8e#es $- Pr$"ert! get*set )tate+ents
The &isibility of get and set logic was solely controlled by the access modifier of
the property declaration!
** The get and set $gi, is 0$th "%0i,(
** gi#en the de,arati$n $- the "r$"ert!.
"%0i, string )$,ia)e,%rit!N%+0er
/
get / ret%rn e+"))N2 3
set / e+"))N 4 #a%e23
3
19
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
#n some cases, it would be helpful to specify uni/ue accessibility le&els for get and set
$gi,. To do so, simply prefi an accessibility $eyword to the appropriate get or set
$eyword.
** O07e,t %sers ,an $n! get the #a%e( h$6e#er
** deri#ed t!"es ,an set the #a%e.
"%0i, string )$,ia)e,%rit!N%+0er
/
get / ret%rn e+"))N2 3
"r$te,ted set / e+"))N 4 #a%e23
3
#n this case, the set logic of 8ocial8ecurity4umber can only be called by the current
class and deri&ed classes and therefore cannot be called from an object instance.
Read-On! and Write-On! Pr$"erties
.hen creating class types, to configure a read-only property, simply build a
property without a corresponding set bloc$.
To configure a write-only property, omit the get bloc$.
"%0i, ,ass E+"$!ee
/
...
** N$6 as a read-$n! "r$"ert!.
"%0i, string )$,ia)e,%rit!N%+0er / get / ret%rn e+"))N2 3 3
3
)tati, Pr$"erties
() also supports static properties.
8tatic members are accessed at the class le&el, not from an instance (object) of
that class.
For eample !
** )tati, "r$"erties +%st $"erate $n stati, dataD
20
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"%0i, ,ass E+"$!ee
/
"ri#ate stati, string ,$+"an!Na+e2
"%0i, stati, string C$+"an!
/
get / ret%rn ,$+"an!Na+e2 3
set / ,$+"an!Na+e 4 #a%e23
3
...
3
8tatic properties are manipulated in the same manner as static methods.
** )et and get the na+e $- the ,$+"an! that e+"$!s these "e$"e...
"%0i, stati, int Main&string<= args'
/
E+"$!ee.C$+"an! 4 9Interte,h Training92
C$ns$e.Write8ine&9These -$>s 6$r> at /;3 9( E+"$!ee.C$+"an!'2
...
3
C# "r$#ides stati, ,$nstr%,t$rs.
** A stati, ,t$r ta>es n$ a,,ess +$di-er $r arg%+ents.
"%0i, ,ass E+"$!ee
/
...
stati, E+"$!ee&'
/
,$+"an!Na+e 4 9Interte,h Training92
3
3
The benefit of properties is that the users of your objects are able to manipulate
the internal data point using a single named item.
21
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
The (e$'#* Pillr! C#"s I#herit#$e (&%%'rt
#nheritance is the aspect of 225 that facilitates code reuse.
#nheritance comes in two fla&ors!
?. (lassical inheritance (the @is-aA relationship) and
<. (ontainment6delegation model (the @has-aA relationship).
.hen you establish Qis-aR reati$nshi"s between classes, you are building a
dependency between types. The basic idea behind classical inheritance is that
new classes may le&erage (and possibly etend) the functionality of other
classes.
#n the ,assi,a inheritan,e +$de, base classes (such as %mployee) are used
to define general characteristics that are common to all descendents. 8ubclasses
(such as 8ales5erson and -anager) etend this general functionality while
adding more specific beha&iors.
#n (), etending a class is accomplished using the colon operator (!) on the class
definition.
** Add t6$ ne6 s%0,asses t$ the E+"$!ees na+es"a,e.
na+es"a,e E+"$!ees
/
"%0i, ,ass Manager : E+"$!ee
22
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
/
** Managers need t$ >n$6 their n%+0er $- st$,> $"ti$ns.
"ri#ate %$ng n%+0erO-O"ti$ns2
"%0i, %$ng N%+0O"ts
/
get / ret%rn n%+0erO-O"ti$ns23
set / n%+0erO-O"ti$ns 4 #a%e2 3
3
3
"%0i, ,ass )aesPers$n : E+"$!ee
/
** )aes"e$"e need t$ >n$6 their n%+0er $- saes.
"ri#ate int n%+0erO-)aes2
"%0i, int N%+0)aes
/
get / ret%rn n%+0erO-)aes23
set / n%+0erO-)aes 4 #a%e2 3
3
3
3
8ales5erson and -anager ha&e automatically inherited all public (and protected)
members of the %mployee base class.
To illustrate!
** Create a s%0,ass and a,,ess 0ase ,ass -%n,ti$nait!.
stati, #$id Main&string<= args'
/
** Ma>e a saes"ers$n.
)aesPers$n stan 4 ne6 )aesPers$n&'2
** These +e+0ers are inherited -r$+ the E+"$!ee 0ase ,ass.
stan.ID 4 B;;2
stan.Na+e 4 9)tan92
** This is de-ined 0! the )aesPers$n ,ass.
23
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
stan.N%+0)aes 4 4A2
C$ns$e.Read8ine&'2
3
Do be aware that inheritance preser&es encapsulation. Therefore, a deri&ed class
cannot directly access the pri&ate members defined by its base class.
C$ntr$ing Base Cass Creati$n 6ith 0ase
8ales5erson and -anager can only be created using a default constructor.
stati, #$id Main&string<= args'
/
** Ass%+e ,$nstr%,t$r. &na+e( age( ID( "a!( ))N( n%+0er $- st$,> $"ti$ns'.
Manager ,h%,>! 4 ne6 Manager&9Ch%,>!9( @C( SA( B;;;;;( 9@@@-A@-A@AA9( S;;;'2
3
#n the argument list, the parameters should be stored in the member &ariables
defined by the %mployee base class. 8o implement this new constructor as
follows!
** I- !$% d$ n$t sa! $ther6ise( a s%0,ass ,$nstr%,t$r a%t$+ati,a!
** ,as the de-a%t ,$nstr%,t$r $- its 0ase ,ass.
"%0i, Manager&string -%Na+e( int age( int e+"ID(
-$at ,%rrPa!( string ssn( %$ng n%+0O-O"ts'
/
** This "$int $- data 0e$ngs 6ith %sD
n%+0erO-O"ti$ns 4 n%+0O-O"ts2
** 8e#erage the #ari$%s +e+0ers inherited -r$+ E+"$!ee
** t$ assign the state data.
ID 4 e+"ID2
Age 4 age2
Na+e 4 -%Na+e2
)$,ia)e,%rit!N%+0er 4 ssn2
Pa! 4 ,%rrPa!2
3
24
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
The de-a%t ,$nstr%,t$r of a base class is called automatically before the logic
of the custom -anager constructor is eecuted.
To help optimi0e the creation of a deri&ed class, to implement your subclass
constructors to eplicitly call an appropriate custom base class constructor, rather
than the default.
To reduce the number of calls to inherited initiali0ation members (which sa&es
time)
** This ti+e( %se the C# 90ase9 >e!6$rd t$ ,a a ,%st$+
** ,$nstr%,t$r $n the 0ase ,ass.
"%0i, Manager&string -%Na+e( int age( int e+"ID( -$at ,%rrPa!(
string ssn( %$ng n%+0O-O"ts'
: 0ase&-%Na+e( age( e+"ID( ,%rrPa!( ssn'
/
n%+0erO-O"ti$ns 4 n%+0O-O"ts2
3
Directly after the closing parenthesis of the constructor's argument list, there is a
single colon followed by the () base $eyword.
#n this situation, you are eplicitly calling the fi&e-argument constructor defined by
%mployee and sa&ing yourself unnecessary calls during the creation of the child
class.
The 8ales5erson constructor loo$s almost identical!
** As a genera r%e( a s%0,asses sh$%d eF"i,it! ,a an
** a""r$"riate 0ase ,ass ,$nstr%,t$r.
"%0i, )aesPers$n&string -%Na+e( int age( int e+"ID(
-$at ,%rrPa!( string ssn( int n%+0O-)aes'
: 0ase&-%Na+e( age( e+"ID( ,%rrPa!( ssn'
/
n%+0erO-)aes 4 n%+0O-)aes2
3
25
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"lso be aware that you may use the base $eyword anytime a subclass wishes to
access a public or protected member defined by a parent class.
Regarding M%ti"e Base Casses
() demands that a gi&en class ha&e eactly one direct base class. Therefore, it
is not possible to ha&e a single type with two or more base classes (this
techni/ue is $nown as multiple inheritance or simply -#).
() does allow a gi&en type to implement any number of discrete interfaces. #n
this way, a () class can ehibit a number of beha&iors while a&oiding the
problems associated with classic -#.
#t is permissible to configure a single interface to deri&e from multiple interfaces.
Tee"ing 1a+i! )e,rets: The "r$te,ted Te!6$rd
5ublic items are directly accessible from anywhere, while pri&ate items cannot be
accessed from any object beyond the class that has defined it.
.hen a base class defines protected data or protected members, it is able to
create a set of items that can be accessed directly by any descendent. #f you
wish to allow the 8ales5erson and -anager child classes to directly access the
data sector defined by %mployee, you can update the original %mployee class
definition as follows!
** Pr$te,ted state data.
"%0i, ,ass E+"$!ee
/
** Chid ,asses ,an dire,t! a,,ess this in-$r+ati$n. O07e,t %sers ,ann$t.
"r$te,ted string -%Na+e2
"r$te,ted int e+"ID2
"r$te,ted -$at ,%rrPa!2
"r$te,ted string e+"))N2
26
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"r$te,ted int e+"Age2
...
3
The benefit of defining protected members in a base class is that deri&ed types
no longer ha&e to access the data using public methods or properties.
The object user is concernedH protected data is regarded as pri&ate (as the user
is @outsideA of the family). Therefore, the following is illegal!
stati, #$id Main&string<= args'
/
** Err$rD CanLt a,,ess "r$te,ted data -r$+ $07e,t instan,e.
E+"$!ee e+" 4 ne6 E+"$!ee&'2
e+".e+"))N 4 9BBB-BB-BBBB92
3
Pre#enting Inheritan,e: )eaed Casses
.hen you establish base class6subclass relationships, you are able to le&erage
the beha&ior of eisting types.
For eample, assume you ha&e added yet another class to your employee
namespaces that etends the eisting 8ales5erson type.
5T8ales5erson is a class representing (of course) a part-time salesperson.
27
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
To pre&ent others from etending a class, ma$e use of the () sealed $eyword!
** Ens%re that PT)aesPers$n ,ann$t a,t as a 0ase ,ass t$ $thers.
"%0i, seaed ,ass PT)aesPers$n : )aesPers$n
/
"%0i, PT)aesPers$n&string -%Na+e( int age( int e+"ID(
-$at ,%rrPa!( string ssn( int n%+0O-)aes'
: 0ase&-%Na+e( age( e+"ID( ,%rrPa!( ssn( n%+0O-)aes'
/
** Interesting ,$nstr%,t$r $gi,...
3
** Other interesting +e+0ers...
3
3ecause 5T8ales5erson is sealed, it cannot ser&e as a base class to any other
type. To etend 5T8ales5erson, you recei&e a compiler error!
** C$+"ier err$rD
"%0i, ,ass Rea!PT)aesPers$n : PT)aesPers$n
/ ... 3
The sealed $eyword is most useful when creating stand-alone utility classes.
"s an eample, the 8tring class defined in the 8ystem namespace has been
eplicitly sealed!
"%0i, seaed ,ass string : $07e,t(
IC$+"ara0e( IC$nea0e(
IC$n#erti0e( IEn%+era0e /...3
Therefore, you cannot create some new class deri&ing from 8ystem.8tring!
** An$ther err$rD
"%0i, ,ass M!)tring : string
/...3
#f you wish to build a new class that le&erages the functionality of a sealed class,
your only option is to forego classical inheritance and ma$e use of the
containment6delegation model (a$a the @has-aA relationship).
28
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
Pr$gra++ing -$r C$ntain+ent*Deegati$n
#nheritance comes in two fla&ors!
?. (lassical @is-aA relationship
2. the @has-aA relationship (also $nown as the containment6delegation model)
"ssume you ha&e created a new class that models an employee benefits pac$age!
** This t!"e 6i -%n,ti$n as a ,$ntained ,ass.
"%0i, ,ass Bene-itPa,>age
/
** Ass%+e 6e ha#e $ther +e+0ers that re"resent
** 4;BT "ans( denta * heath 0ene-its and s$ $n.
"%0i, d$%0e C$+"%tePa!Ded%,ti$n&'
/ ret%rn BAC.;2 3
3
To do so, you can update the %mployee class definition as follows!
** E+"$!ees n$6 ha#e 0ene-its.
"%0i, ,ass E+"$!ee
/
...
** C$ntain a Bene-itPa,>age $07e,t.
"r$te,ted Bene-itPa,>age e+"Bene-its 4 ne6 Bene-itPa,>age&'2
3
To epose the functionality of the contained object to the outside world re/uires
delegation. Delegation is simply the act of adding members to the containing
class that ma$e use of the contained object's functionality.
For eample,
"%0i, ,ass E+"$!ee
/
"r$te,ted Bene-itPa,>age e+"Bene-its 4 ne6 Bene-itPa,>age&'2
29
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
** EF"$se ,ertain 0ene-it 0eha#i$rs $- $07e,t.
"%0i, d$%0e GetBene-itC$st&'
/
ret%rn e+"Bene-its.C$+"%tePa!Ded%,ti$n&'2
3
** EF"$se $07e,t thr$%gh a ,%st$+ "r$"ert!.
"%0i, Bene-itPa,>age Bene-its
/
get / ret%rn e+"Bene-its2 3
set / e+"Bene-its 4 #a%e2 3
3
3
Updated -ain() method, notice how we can interact with the internal
3enefits5ac$age type defined by the %mployee type!
stati, #$id Main&string<= args'
/
Manager +e2
+e 4 ne6 Manager&'2
C$ns$e.Write8ine&+e.Bene-its.C$+"%tePa!Ded%,ti$n&''2
...
C$ns$e.Read8ine&'2
3
Nested T!"e De-initi$ns
#n (), it is possible to define a type (enum, class, interface, struct, or delegate)
directly within the scope of a class or structure. .hen you ha&e done so, the
nested (or @innerA) type is considered a member of the nesting (or @outerA) class.
30
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"%0i, ,ass O%terCass
/
** A "%0i, nested t!"e ,an 0e %sed 0! an!0$d!.
"%0i, ,ass P%0i,InnerCass /3
** A "ri#ate nested t!"e ,an $n! 0e %sed 0! +e+0ers
** $- the ,$ntaining ,ass.
"ri#ate ,ass Pri#ateInnerCass /3
3
4esting types is similar to composition (@has-aA), ecept that you ha&e complete
control o&er the access le&el of the inner type instead of a contained object.
3ecause a nested type is a member of the containing class, it can access pri&ate
members of the containing class.
" nested type is only useful as helper for the outer class, and is not intended for
use by the outside world.
.hen a type nests another class type, it can create member &ariables of the
type, just as it would for any point of data.
stati, #$id Main&string<= args'
/
** Create and %se the "%0i, inner ,ass. OTD
O%terCass.P%0i,InnerCass inner2
inner 4 ne6 O%terCass.P%0i,InnerCass&'2
** C$+"ier Err$rD Cann$t a,,ess the "ri#ate ,ass.
O%terCass.Pri#ateInnerCass innerA2
innerA 4 ne6 O%terCass.Pri#ateInnerCass&'2
3
To ma$e use of this concept within our employees eample, assume we ha&e
now nested the 3enefit5ac$age directly within the %mployee class type!
31
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
** Nesting the Bene-itPa,>age.
"%0i, ,ass E+"$!ee
/
...
"%0i, ,ass Bene-itPa,>age
/
"%0i, d$%0e C$+"%tePa!Ded%,ti$n&'
/ ret%rn BAC.;2 3
3
3
To programmatically enforce the connection between %mployee, 3enefit5ac$age,
and 3enefit5ac$ageIe&el!
** E+"$!ee nests Bene-itPa,>age.
"%0i, ,ass E+"$!ee
/
** Bene-itPa,>age nests Bene-itPa,>age8e#e.
"%0i, ,ass Bene-itPa,>age
/
"%0i, d$%0e C$+"%tePa!Ded%,ti$n&'
/ ret%rn BAC.;2 3
"%0i, en%+ Bene-itPa,>age8e#e
/
)tandard( G$d( Patin%+
3
3
3
3ecause of the nesting relationships, note how we are re/uired to ma$e use of
this enumeration!
stati, #$id Main&string<= args'
/
32
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
** Creating a Bene-itPa,>age8e#e #aria0e.
E+"$!ee.Bene-itPa,>age.Bene-itPa,>age8e#e
+!Bene-it8e#e 4
E+"$!ee.Bene-itPa,>age.Bene-itPa,>age8e#e.Patin%+2
...
3
The Third Piar: C#Us P$!+$r"hi, )%""$rt
(onsider the %mployee base class defined a method named 1i&e3onus(), which
was implemented as follows!
** Gi#e 0$n%s t$ e+"$!ees.
"%0i, ,ass E+"$!ee
/
...
"%0i, #$id Gi#eB$n%s&-$at a+$%nt'
/ ,%rrPa! 54 a+$%nt2 3
3
3ecause this method has been defined as public, you can now gi&e bonuses to
salespeople and managers (as well as part-time salespeople)!
stati, #$id Main&string<= args'
/
** Gi#e ea,h e+"$!ee a 0$n%s.
Manager ,h%,>! 4 ne6 Manager&9Ch%,>!9( C;( SA( B;;;;;( 9@@@-A@-A@AA9( S;;;'2
,h%,>!.Gi#eB$n%s&@;;'2
,h%,>!.Dis"a!)tats&'2
)aesPers$n -ran 4 ne6 )aesPers$n&91ran9( 4@( S@( @;;;( 9S@A-@A-@A@A9( @B'2
-ran.Gi#eB$n%s&A;;'2
-ran.Dis"a!)tats&'2
C$ns$e.Read8ine&'2
3
33
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
The problem with the current design is that the inherited 1i&e3onus() method
operates identically for all subclasses. #deally, the bonus of a salesperson or part-
time salesperson should ta$e into account the number of sales.
The #irt%a and $#erride Te!6$rds
5olymorphism pro&ides a way for a subclass to customi0e how it implements a
method defined by its base class.
To retrofit your current design, you need to understand the meaning of the ()
&irtual and o&erride $eywords.
#f a base class wishes to define a method that may be o&erridden by a subclass,
it must specify the method as &irtual!
"%0i, ,ass E+"$!ee
/
** Gi#eB$n%s&' has a de-a%t i+"e+entati$n( h$6e#er
** ,hid ,asses are -ree t$ $#erride this 0eha#i$r.
"%0i, #irt%a #$id Gi#eB$n%s&-$at a+$%nt'
/ ,%rrPa! 54 a+$%nt2 3
...
3
.hen a subclass wishes to redefine a &irtual method, it does so using the
o&erride $eyword.
For eample, the 8ales5erson and -anager could o&erride 1i&e3onus() as
follows!
"%0i, ,ass )aesPers$n : E+"$!ee
/
** A saes"ers$nLs 0$n%s is in-%en,ed 0! the n%+0er $- saes.
"%0i, $#erride #$id Gi#eB$n%s&-$at a+$%nt'
/
int saesB$n%s 4 ;2
34
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
i-&n%+0erO-)aes V4 ; WW n%+0erO-)aes X4 B;;'
saesB$n%s 4 B;2
ese i-&n%+0erO-)aes V4 B;B WW n%+0erO-)aes X4 A;;'
saesB$n%s 4 BC2
ese
saesB$n%s 4 A;2 ** An!thing greater than A;;.
0ase.Gi#eB$n%s &a+$%nt G saesB$n%s'2
3
...
3
"%0i, ,ass Manager : E+"$!ee
/
** Managers get s$+e n%+0er $- ne6 st$,> $"ti$ns( in additi$n t$ ra6 ,ash.
"%0i, $#erride #$id Gi#eB$n%s&-$at a+$%nt'
/ ** In,rease saar!.
0ase.Gi#eB$n%s&a+$%nt'2
** And gi#e s$+e ne6 st$,> $"ti$ns...
Rand$+ r 4 ne6 Rand$+&'2
n%+0erO-O"ti$ns 54 &%$ng'r.NeFt&C;;'2
3
...
3
%ach o&erridden method is free to le&erage the default beha&ior using the 0ase
$eyword.
#n this way, you ha&e no need to completely reemployment the logic behind
1i&e3onus(), but can reuse the default beha&ior of the parent class.
stati, #$id Main&string<= args'
/ ** A 0etter 0$n%s s!ste+D
Manager ,h%,>! 4 ne6 Manager&9Ch%,>!9( C;( SA( B;;;;;( 9@@@-A@-A@AA9( S;;;'2
,h%,>!.Gi#eB$n%s&@;;'2
,h%,>!.Dis"a!)tats&'2
35
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
)aesPers$n -ran 4 ne6 )aesPers$n&91ran9( 4@( S@( @;;;( 9S@A-@A-@A@A9( @B'2
-ran.Gi#eB$n%s&A;;'2
-ran.Dis"a!)tats&'2
J
Re#isiting the seaed Te!6$rd
The sealed $eyword can also be applied to type members to pre&ent &irtual
members from being further o&erridden by deri&ed types.
This can be helpful when you do not wish to seal an entire class, just a few select
methods or properties.
For eample, 5T8ales5erson class to be etended by other classes but ma$e
sure those classes did not further o&erride the &irtual 1i&e3onus(), we could write
the following!
** This ,ass ,an 0e eFtended2
** h$6e#er( Gi#eB$n%s&' ,ann$t 0e $#erriden 0! deri#ed ,asses.
"%0i, ,ass PT)aesPers$n : )aesPers$n
/
...
"%0i, $#erride seaed #$id Gi#eB$n%s&-$at a+$%nt'
/
...
3
3
Understanding A0stra,t Casses
The %mployee base class has been designed to supply protected member
&ariables for its descendents, as well as supply two &irtual methods (1i&e3onus()
and Display8tats()) that may be o&erridden by a gi&en descendent.
36
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
1i&en that many base classes tend to be rather nebulous entities, a far better
design for our eample is to pre&ent the ability to directly create a new %mployee
object in code.
#n (), you can enforce this programmatically by using the abstract $eyword!
** U"date the E+"$!ee ,ass as a0stra,t t$ "re#ent dire,t instantiati$n.
a0stra,t "%0i, ,ass E+"$!ee
/ ...3
.ith this, if you now attempt to create an instance of the %mployee class, you
are issued a compile time error!
** Err$rD CanLt ,reate an instan,e $- an a0stra,t ,ass.
E+"$!ee E 4 ne6 E+"$!ee&'2
37
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
En-$r,ing P$!+$r"hi, A,ti#it!: A0stra,t Meth$ds
.hen a class has been defined as an abstract base class, it may define any
number of abstract members (which is analogous to a (++ pure &irtual function).
38
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"bstract methods can be used whene&er you wish to define a method that does
not supply a default implementation.
3y doing so, you enforce a polymorphic trait on each descendent, lea&ing them
to contend with the tas$ of pro&iding the details behind your abstract methods.
Don't allow the object user to create an instance of 8hape directly, as it is too
abstract of a concept. "gain, to pre&ent the direct creation of the 8hape type, you
could define it as an abstract class!
na+es"a,e )ha"es
/
"%0i, a0stra,t ,ass )ha"e
/
** )ha"es ,an 0e assigned a -riend! "et na+e.
"r$te,ted string "etNa+e2
** C$nstr%,t$rs.
"%0i, )ha"e&'/ "etNa+e 4 9N$Na+e92 3
"%0i, )ha"e&string s' / "etNa+e 4 s23
** Dra6&' is #irt%a and +a! 0e $#erridden.
"%0i, #irt%a #$id Dra6&'
/
C$ns$e.Write8ine&9)ha"e.Dra6&'9'2
3
"%0i, string PetNa+e
/
get / ret%rn "etNa+e23
set / "etNa+e 4 #a%e23
3
3
** Cir,e DOE) NOT $#erride Dra6&'.
"%0i, ,ass Cir,e : )ha"e
/
"%0i, Cir,e&' / 3
39
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"%0i, Cir,e&string na+e': 0ase&na+e' / 3
3
** HeFag$n DOE) $#erride Dra6&'.
"%0i, ,ass HeFag$n : )ha"e
/
"%0i, HeFag$n&'/ 3
"%0i, HeFag$n&string na+e': 0ase&na+e' / 3
"%0i, $#erride #$id Dra6&'
/
C$ns$e.Write8ine&9Dra6ing /;3 the HeFag$n9( "etNa+e'2
3
3
3
The point of abstract methods becomes crystal clear when you understand that
subclasses are not re/uired to o&erride &irtual methods.
** The Cir,e $07e,t did n$t $#erride the 0ase ,ass i+"e+entati$n $- Dra6&'.
stati, #$id Main&string<= args'
/
HeFag$n heF 4 ne6 HeFag$n&9Beth9'2
heF.Dra6&'2
Cir,e ,ir 4 ne6 Cir,e&9Cind!9'2
** H%++. Using 0ase ,ass i+"e+entati$n.
,ir.Dra6&'2
C$ns$e.Read8ine&'2
3
40
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
%stablish Draw() as an abstract method of the 8hape class, which by definition
means you pro&ide no default implementation whatsoe&er.
4ote that abstract methods can only be defined in abstract classes. #f you
attempt to do otherwise, you will be issued a compiler error!
** 1$r,e a >ids t$ -ig%re $%t h$6 t$ 0e rendered.
"%0i, a0stra,t ,ass )ha"e
/
...
** Dra6&' is n$6 ,$+"ete! a0stra,t &n$te se+i,$$n'.
"%0i, a0stra,t #$id Dra6&'2
...
3
1i&en this, you are now obligated to implement Draw() in your (ircle class. #f you
do not, (ircle is also assumed to be a noncreatable abstract type that must be
adorned with the abstract $eyword.
** I- 6e did n$t i+"e+ent the a0stra,t Dra6&' +eth$d( Cir,e 6$%d as$ 0e
** ,$nsidered a0stra,t( and ,$%d n$t 0e dire,t! ,reatedD
"%0i, ,ass Cir,e : )ha"e
/
"%0i, Cir,e&'/ 3
"%0i, Cir,e&string na+e': 0ase&na+e' / 3
** N$6 Cir,e +%st de,ide h$6 t$ render itse-.
"%0i, $#erride #$id Dra6&'
/
41
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
C$ns$e.Write8ine&9Dra6ing /;3 the Cir,e9( "etNa+e'2
3
3
** Create an arra! $- #ari$%s )ha"es.
stati, #$id Main&string<= args'
/
C$ns$e.Write8ine&9GGGGG 1%n 6ith P$!+$r"his+ GGGGGHn9'2
)ha"e<= +!)ha"es 4 /ne6 HeFag$n&'( ne6 Cir,e&'( ne6 HeFag$n&9Mi,>9'(
ne6 Cir,e&9Beth9'( ne6 HeFag$n&98inda9'32
** 8$$" $#er the arra! and as> ea,h $07e,t t$ dra6 itse-.
-$r&int i 4 ;2 i X +!)ha"es.8ength2 i55'
+!)ha"es<i=.Dra6&'2
C$ns$e.Read8ine&'2
3
O%t"%t:
99999 Fun with 5olymorphism 99999
Drawing 4o 4ame the heagon
Drawing 4o 4ame the circle
Drawing -ic$ the heagon
Drawing 3eth the circle
Drawing Iinda the heagon
Me+0er Hiding
() pro&ides a facility that is the logical opposite of method o&erriding! member hiding.
#f a deri&ed class redeclares an identical member inherited from a base class, the
deri&ed class has hidden (or shadowed) the parent's member.
1$r eFa+"e assume you recei&e a class named ThreeD(ircle from a cowor$er (or
classmate) that currently deri&es from 8ystem.2bject!
"%0i, ,ass ThreeDCir,e
/
"%0i, #$id Dra6&'
42
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
/
C$ns$e.Write8ine&9Dra6ing a @D Cir,e9'2
3
3
Kou figure that a ThreeD(ircle @is-aA (ircle, so you deri&e from your eisting (ircle type!
"%0i, ,ass ThreeDCir,e : Cir,e
/
"%0i, #$id Dra6&'
/
C$ns$e.Write8ine&9Dra6ing a @D Cir,e9'2
3
3
2nce you recompile, you find the following warning shown in Lisual 8tudio <;;> (see
Figure below).
To address this issue, you ha&e two options.
?. Kou could simply update the parent's &ersion of Draw() using the o&erride
$eyword. .ith this approach, the ThreeD(ircle type is able to etend the parent's
default beha&ior as re/uired.
<. Kou can prefi the new $eyword to the offending Draw() member of the
ThreeD(ircle type. Doing so eplicitly states that the deri&ed type's implemention
is intentionally designed to hide the parent's &ersion.
** This ,ass eFtends Cir,e and hides the inherited Dra6&' +eth$d.
43
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
"%0i, ,ass ThreeDCir,e : Cir,e
/
** Hide an! Dra6&' i+"e+entati$n a0$#e +e.
"%0i, ne6 #$id Dra6&'
/
C$ns$e.Write8ine&9Dra6ing a @D Cir,e9'2
3
3
The new can also apply $eyword to any member type inherited from a base class
(field, constant, static member, property, etc.).
For eample!
"%0i, ,ass ThreeDCir,e : Cir,e
/
ne6 "r$te,ted string "etNa+e2
ne6 "%0i, #$id Dra6&'
/
C$ns$e.Write8ine&9Dra6ing a @D Cir,e9'2
3
3
Finally, be aware that it is still possible to trigger the base class implementation of
a shadowed member using an eplicit cast (described in the net section).
For eample!
stati, #$id Main&string<= args'
/
ThreeDCir,e $ 4 ne6 ThreeDCir,e&'2
$.Dra6&'2 ** Cas ThreeDCir,e.Dra6&'
&&Cir,e'$'.Dra6&'2 ** Cas Cir,e.Dra6&'
3
C# Casting R%es
44
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
The first law of casting between class types is that when two classes are related
by an @is-aA relationship, it is always safe to store a deri&ed type within a base
class reference.
Formally, this is called an implicit cast, as @it just wor$sA gi&en the laws of
inheritance. This leads to some powerful programming constructs.
For eample, if you ha&e a class named The-achine that supports the following
static method!
"%0i, ,ass TheMa,hine
/ "%0i, stati, #$id 1ireThisPers$n&E+"$!ee e'
/
** Re+$#e -r$+ data0ase.Get >e! and "en,i shar"ener -r$+ -ired e+"$!ee...3
3
Kou can effecti&ely pass any descendent from the %mployee class into this
method directly, gi&en the @is-aA relationship!
** )trea+ine the sta--.
TheMa,hine.1ireThisPers$n&+$$nUnit'2 ** 9+$$nUnit9 6as de,ared as an
E+"$!ee.
TheMa,hine.1ireThisPers$n&7i'2 ** 97i9 6as de,ared as a )aesPers$n.
The following code compiles gi&en the implicit cast from the base class type
(%mployee) to the deri&ed type.
#f you pass the fran$ object directly into The-achine.FireThis5erson() as follows!
** A Manager 9is-a9 $07e,t( 0%t...
$07e,t -ran> 4 ne6 Manager&91ran> Ya""a9( S( 4;;;;( 9BBB-BB-BBBB9( C'2
...
TheMa,hine.1ireThisPers$n&-ran>'2 ** Err$rD
45
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
you are issued a compiler error. The reason is you cannot automatically treat a
8ystem.2bject as a deri&ed %mployee directly, gi&en that 2bject @is-not-aA
%mployee.
The object reference is pointing to an %mployee-compatible object. Kou can
satisfy the compiler by performing an eF"i,it ,ast.
#n (), eF"i,it ,asts are denoted by placing parentheses around the type you
wish to cast to, followed by the object you are attempting to cast from.
For eample!
** Cast -r$+ the generi, )!ste+.O07e,t int$ a str$ng! t!"ed
** Manager.
Manager +gr 4 &Manager'-ran>2
C$ns$e.Write8ine&91ran>Ls $"ti$ns: /;39( +gr.N%+0O"ts'2
To condense abo&e code!
** An 9inine9 eF"i,it ,ast.
C$ns$e.Write8ine&91ran>Ls $"ti$ns: /;39( &&Manager'-ran>'.N%+0O"ts'2
"s far as passing the 8ystem.2bject reference into the FireThis5erson() method,
the problem can be rectified as follows!
** EF"i,it! ,ast )!ste+.O07e,t int$ an E+"$!ee.
TheMa,hine.1ireThisPers$n&&E+"$!ee'-ran>'2
#f you attempt to cast an object into an incompatible type, you recei&e an in&alid
cast eception at runtime.
Deter+ining the QT!"e $-R E+"$!ee
The () language pro&ides three ways to determine whether a gi&en base class
reference is actually referring to a deri&ed type!
46
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
?. eplicit casting,
<. the is $eyword, and
:. the as $eyword.
The is >e!6$rd is helpful in that it will return a 3oolean that signals whether the base
class reference is compatible with a gi&en deri&ed type.
"%0i, ,ass TheMa,hine
/
"%0i, stati, #$id 1ireThisPers$n&E+"$!ee e'
/
i-&e is )aesPers$n'
/
C$ns$e.Write8ine&98$st a saes "ers$n na+ed /;39( e.Get1%Na+e&''2
C$ns$e.Write8ine&9/;3 +ade /B3 sae&s'...9(
e.Get1%Na+e&'( &&)aesPers$n'e'.N%+0)aes'2
3
i-&e is Manager'
/
C$ns$e.Write8ine&98$st a s%it na+ed /;39( e.Get1%Na+e&''2
C$ns$e.Write8ine&9/;3 had /B3 st$,> $"ti$ns...9(
e.Get1%Na+e&'( &&Manager'e'.N%+0O"ts'2
3
3
3
*ere, you ma$e use of the is >e!6$rd to dynamically determine the type of
employee. To gain access to the 4umb8ales and 4umb2pts properties, you
ma$e use of an eplicit cast.
"s an alternati&e, you could ma$e use of the as $eyword to obtain a reference to
the more deri&ed type (if the types are incompatible, the reference is set to null)!
)aesPers$n " 4 e as )aesPers$n2
i-&" D4 n%'
47
C# PROGRAMMING AND .NET UNIT-4 OOP WITH C# VIK
VIK
C$ns$e.Write8ine&9# $- saes: /;39( ".N%+0)aes'2
N%+eri,a Casts
4umerical con&ersions follow more or less the same rules. #f you are attempting
to place a @largerA numerical type to a @smallerA type (such as an integer into a
byte), you must also ma$e an eplicit cast that informs the compiler you are
willing to accept any possible data loss!
** I- 9F9 6ere arger than a 0!teLs %""er i+it( data $ss is a+$st ,ertain2
int F 4 Z2
0!te 0 4 &0!te'F2
*owe&er, when you are storing a @smallerA numerical type into a @largerA type
(such as a byte to an integer), the type is implicitly cast on your behalf, as there
is no loss of data!
** N$ need t$ ,ast( as an int is 0ig en$%gh t$ st$re a 0!te.
0!te 0 4 @;2
int F 4 02

You might also like