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<i'# (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