Published on

Published in: Technology, Health & Medicine
  • Be the first to comment

  • Be the first to like this

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide


  1. 1. '-, .'-1.-V ' 11 Interfaces and Structures Constructors Revisited A constructor is used to inilialli/ e the IlIlilflDt' of in class as explaiincd earlier. g public class m ( public static void l-taint) { System. Conso| e.WribeLine("in main‘); ho a = new bb(); bb o = new bb(l0); ) } public class all { public aa() { System. Console. WriueLine("ln const aa‘); ) public aa(int i) ( System. Con. sole. Wrlueune("ln const aa' + l); ) } public class bb : aa I public ob() { Systc-m. Consolc. Wriu: Linc("ln const bb"); } DUDIIC ob(lnt i) { Systern. Console. Wribel. ine("in const bb" + i); ) } Output
  2. 2. in main in coast a in coast bb In coast as In const bbto Class at: is the base class. It consists of two constructors. One that takes no parameters and the other that takes an int as it parameter. Class H: is derived from class an. i. c. an is the base class. bb the derived class. When we create an object like hh. the compiler does not execute the code for the constnmor but instead asks the umstnlctor which constructor of the base class to execute first. As we haven't stated this. by default. the constructor with no parameters get executed. Remember it is the base class constructor which gets executed first and the derived class constructor specifies which base class constructor to call titst. In the second case. even though we are calling the constructor with n parameter. the constructor with no pnrurnetets in the base class gets called and not the one with one int as a parameter. as public class zzz { ptblic static void Main() { System. Console. Wrltet. ine("in main’); his a - new bbtlz b b - new noun); l ) pd-llic classaa { gibllc 800 System. Conso| e.Wrltet. ine("ln const as‘); ) t{lbllc aa(lnt l) System. Conso| e.Writet. ine("ln eonst as‘ «l» i); l ) pdilicclassbbzaa { politic bb() 2 base() Systern. Console. Writet. 'ne("in oonst bb"); ) ptbllc bb(lnt l) : base(I) { Svstem. Console. Writet. irle("in oonst be" + n; ) ) Output
  3. 3. in main in coast a in coast bb in coast ate in coast bb10 If we do not specify which constructor of the base class to call. CD by default calls the constructor with no parturteters. Which means that C9 rewrites our code . When we write bbt). it gets rewritten as hot) : baset). Base is a reserved word. It means call the constructor of the hate class with no parameters. For the second corntmctor. hhtint i). the line gets rewritten to bhtint i) : beset). We now want to call the comtructor with one int and hence we write bbtint il : bnseti). That is why the constructor with one int gets called. We have the option to decide which constructor of the base class we would like to call. LQ ptmltc class 222 { gublic matte void B-taint) Synem. CnnsoIe. VvrItleune("In main‘); bb a = new bot); } ) public class are { gtblic aat) system. consote. WrItet. tne(“In oonst aa‘); ) gtblic aatint i) syaem. conso| e.wtIwune("In const an‘ + l); ) ) publieclassbb: aa ( gtbllt 500 = W590) System. Conso| e.lNritet. ine("tn eonst bb"); ) ptbllc bb(lot l) : base(I) { Systen1.Console. Wrltat. ir1e("in const tab” 4 i); } } Output In main In coost aa20 In coast bozo in coast bb A constructor gets called at the time of creation of the object. At the line. new bb(). the compiler asks the constructor of bb as to which constructor of the base class an to call. Here he was told that the answer lies with thist20_). this. like base. is n reserved word. It means call tr constructor of the same clam and not the base class. Therefore the compiler now ask: the one constructor of the
  4. 4. derived class bl) which constmctor of the base class to call. bbt int i) : base(i) tells the compiler to execute the one int constructor of am. This is the first constmctor that gets called. Then the one int constructor of bb gets called and finally the one who started it all. the no parameter constructor of Ni. Thus. two derived class constructors get called instead of one. ms ptbllc class zzz { public static void Main() System. Console. Wrltet. lne("ln main‘); aa a = new aa0; ) ) ptbllc class aa { private aa[) ( ) ) Compiler Error acs(6.8): error CSOt22: 'aa. aa0' is inaccessible due to its protection level When you create a comtructor which is private. you cannot create an object that looks like as. Thus an should only contain static members. LQ ptbllt: class zn { Emilie stab’: void Main() ) ) ptblic classaa { private aao { ) } pwllc classbb : aa { ) Compiler Error a. cs(13.14): error C5012: 'aaaa()' is inaccessible due to its protection level Nor can any class derive from an. Thus no one can instantiate an object that looks like as or derive from it as the constructor has been made private. E ptblit: class 22 {
  5. 5. public static void ll-taint) System. ConsoIe. wrItseune(aa. I); ) ) public class a { private at) l some pmltc Int I - 20; ) Oulptn 20 You can however inc all the static variables in an as public class 222 { pdJl‘tt: static void I’-1a'I't() { ) ) dassyyy { gtbllc YYYO } ) dassioouyyy ( pdllic itt: i; a{oot() : base( this. i) ) } Compiler Error a. cs(18.15): error CSOOQ7: Keyword this is not available in the current context Base is called a constructor initializict. When base gets called. the instance or the object has not yet been created. Ergo. this is not available here as this refers to the current object. In the constructor. hammer. this can be freely used. The values of variables in tt class are initialized to their default values as per their data types before the constructor gets called. Thus. in the constructor they have their default values as shown below. 3.5 pmlic class za {
  6. 6. public static void l-taint) { ¥W 6 = new WYO; } dassyyy ( public int i; public bool j; | (:ublic yyy() $ystem. Console. WrlteLine(l+" " +1); } ) Output 0 False Here as before. the first line of code in the constructor gets executed. ms: public class zzz { public static vold l~1a>‘n() { too: a new xxx(); ) ) dasswy { public inti 10; public yyy(-nt J) System. Console. VlIrite1.ine(i); lo 1; ) } dassiotxzyyy { public xxx() : base( 100) { System. Consale. Writ: el. ine(base. i); ) } Output 10 100 Calling the base class constructor is like inserting all the code of the one in! constructor i. e. yyylint jl. In the constnictor of class xxx. We are also allowed to access members ol the bttsc claw after the constructor gets called. Also. first the variable i gets initialized to I0 or the default value of int. Then vie change it to lD0 and in the constructor of . .x. we will see at value of I00.
  7. 7. as public class zzz i{iut: tic static void Main() ‘£0953 = "94 00(0) 3.“ WV §tblic VYYO ; bc(); | (Jt. blic virtud void abc() ) ) dassiotxzyyy ( publlclntx=10; wblicxxxl) { §y= aegt;3ortsole. WrItet. Ine(x); $vstem. Conso| e.Wrltel. ine(x); éublie override void ahco : ystem. Corso| e.Wrllel. 'lte(x); ) Output 10 10 100 We have already confessed a million times in the past that we have copied idem: from anyone and everyone. specially from the documentatiort In this specific case. we wanted to demonstrate that first the variables are initialized. Thus in class xxx. the int x is initialized to I0. Then the base clas constructor of yyy gets called. The value of It in class yyy should be I0. But what gttanntee can we give you as we are not able to print the value of it in an object of a class derived from the base class. Very simple. We call a virtual function abc from class yyy and override it in class root. The abc of class xxx prints the value of x as they belong to the same class and the output is 10. Viola and thank you Mr. Documentation for the above thought and many more such ideas. Once all code in the yyy constructor is executed. the first line in root constructor will get executed which will print the value of x as I0. x is then initialined to I00. hence we see Ill) as the new value of it, displayed on the screen. M3 public class zzz
  8. 8. { static zzz() ( System. Console. WiltteUne("zzz'): } public static void Memo ( $ystem. Console. VVrIttel. -ne("main"); new aa(); } ) publ c class aa { | (:ub| 'ic aa-1) System. Console. WrlteLine("aa"); ) static aa() { System. Console. WrltelJne("stattc aa“); } } Output zzz mat’ n static aa an and if we comment new ant I then the resulting output reads us follows. Output zzz mam A static constructor gets called before any other constructors. 6.55 public class 221 { static 2220 l System. Console. Writ: eUne("zzz'); } public static void Maino { System. Console. WritteLine("rnain"); aa. a(); ) ) public class aa { public aa-1)
  9. 9. { Systern. Coriso| e.vrrltat. ine("aa"); ) publlc static vold a0 { ) static aa() { $vstem. Cortsole. Writet. ine("st3tic ea‘); ) ) Output zu main static as It’ you try to access any static member of a clmus or whenever you instantiate an object. the static constructor gets aulled. A constructor is not inherited by the derived class. A clans is loaded in memory before any instance of the class is created or its static members accessed A class can only be loaded once and that too before its derived class is loaded. The static constructor is called at the time of loading the class. Like other comtructors. a static constructor cannot be explicitly called. 3.5 public class zzz { public antic void Maino { mwqfl); {W-abet); ) class yyy { static mt) { §ystem. consoIe. WrItet. tne("statlc yyy”); public static void abet) $)iystem. Console. Wrltet. itte("abc y-W‘); ) dass roux ( static 2oot() { System. Cnnso| e.Writet. ite("static xxx"); ) public static void pqr() Systern. Console. WrItelJne(“pq' toot‘); )
  10. 10. ) Output static xxx pqr xxx static yyy 390 YYY Do not believe the above rexults as if you run them on your machine. your mileage may wary. This is because C '0 dot-. ~ mandate the order of loading of cltisses and thus the order of execution of the static constructors. On your machine if the yyy constmctor gets executed lint. do not panic. Blame it on your destiny‘. a. cs public class 222 { public static void Maino ( YYY-63360: mcvqrli: ) ) dass )0(X Exatic mo §ystem. Console. WriteL: ne("static xxx”); |? .iubl'»c static void pqr() §ystem. Console. ViIrlteUne("pq' root‘); class yyy : XXX fitatic yyy() §ystem. consoie. NriteLine("statlc yyy"); iliublic static void abct) gystc-rn. console. WriteLine("abc yyy‘); } } Output static yyy 350 WV static xxx PQIXXX We have made only one small change in the above program. We have derived the class yyy from xxx. Since the functions in each cluxs are maritcd static. the program behaves in the same manner
  11. 11. an before. The utxwe order of calls‘ remain-t the sonic. If an object of the type is created. then the output will change. The reason being that before the object of type yyy is created. In must be loaded. Hence the constructors will be called first. 3.55 public class 221 { public static Int x = wy. y + 2; static zzz() { Systern. Cunsole. lNrlttel. ine("static zzz ' + zzz. x + ' ' + yyy. y); x 500; vw-v = 600; System. Console. WritJeLine("static zzz ‘ + mx + ' ' + yyy. y); } public static void Mau'n() ( $ystem. Console. WriteLine("main "+ zzz. x + ' " + yyy. y); ) ) dass wy { static mt) { System. Console. Writet. -ne("static yw " + zzz. x + " " + wy. y); Y 10; zzz. x 2CD; System. Console. Wrltet. ine("statlc yyy “ + Hut -1» " " + wy. y); } public static Int y 222.3: + 3; } Output static yyy 0 3 static yyy 200 10 static zzz 12 10 static 222 500 600 maj n 500 600 Diflicult code to understand and follow. Ct’ first tries to loud Cl'. t.s. ‘ an in memory as it contains the function Main. Unfortunately ll realires that it has to first initialize the variable it before calling the static constructor of 727.. It firs! initiali7es x to 0. Now note that this initialization of x to zero is‘ extremely significant for our understanding. To get the new value of x. Cir‘ now needs the value of the variable y from the class yyy. Before it can call the static constructor of yyy it must initialize the variable y. It makes sure that y's value is first set to mm. It then computes the value of / _/. /.. which is zero ax grated above We are yet left hanging in CliI. at at the line . = l As zu. . is zero. the value of y is 0 4 3 la. 3. This completes the initialization of all the variables in the class. All this happens first. Thus the static constructor of class yyy shows the value of the variable x as 0 and that of variable y as 3. But hold on. the fun is yet to begin. In the static constructor. we now initialize y to 10 and the x of u/ . to 200. The next Writeljne confirms that our initialimtions actually were carried out. Then we go back to class 17/. Here we come back to the initiuli/ ation of the static variable x. As yy_'. _y is now I0 since we changed it in the static constructor of the value of x is ID + 2 i. c. I2.
  12. 12. This overrides the value of x which we changed to 200 in the static constructor yyy. Now Ct! calls the static constructor of 122 as it has finished all the variable initializations. Thus the first WriteLine displays 12 and 10. We are now changing both at and y and they display the same values in the constructor and in Main. ms ptbllc class zzz { ptblicstaficimx - yyy. y+ 2; same 220 { $ystem. ConsoIe. Wrltet. ine("static zzz ' + zzz. x + ' ' + yyy. y); x - soo; m-v - 600. Sy3em. Console. tNrltet. lne(“statlc zzz ' + zzz. x + ' ' + yyy. y); } } class yyy ( static mt) { System. Consote. Wrltet. Ine("sutIc yyy " + zzz. x -4- " " + yyy. y); Y = 10; um: = 200; Systen1.Console. Wr| tet. ine("st3tieyyy " + zzz. x + " " + yyy. y); ) ptblicstaticlnty= zzz. x+3; public static void Mainfl { system. Oonsole. WrIuet. tne(“maIn "+ zzz. x + " " + yyy. y); ) } Output staticzzzzo staticzzz500600 stattcyyy50050e statlcyyyzooto main20010 The above program adds a small twist. It bowls what in cricket parlance ‘Ls called a googly. We simply bring Main fmm the class zzz. to the class yyy. Now (‘.19 as usual first starts at the class containing Main which now happens to be yyy and not zn. Here it has to first initialize all the variables in class yyy. We have only one. It starts by setting y to zero and runs to the clius za to fetch the value of x. X now become 0 + 2 i. e. 2. Then in the static constructor. we are displaying the relevant values of x and y. In the static constructor of class zzz. we are changing x and y to 500 and 6t! ) respectively and displaying the values. When we move back to class yyy. however. y gets a new value of 503 as x is 500. y loses in; value of 600 that was initialized in 2.21. hence you see 500 and 503. The rest remains the same as explained in the earlier example. Interfaces
  13. 13. An interface is ~'imply at collection of function) pmtotypew. Like we derive an claims from another. so also we could derive from am interface. 3_-C_S. class zzz ( public static void l~1afn() { ) ) Interface ddd { mid al(); void a2(); } dass yyy : ddd { ) Compiler Error a. cs(12.7J: error CS0535' yyy‘ does not implement interface member 'ddd. a1()' a. cs(12,7): error CS0585. yyy' does not nmptement interface member 'ddd. a2()' We have just created an interface culled ddd by using zi new keyword interface in place of a class. Our intcrfaec ddd has two function prototypes. .11 and -.12. We can dcriwc from our intcrfncc ddd like we derived {mm 4: class, The difference is that an interface has no code. only function prototypes. Whenever we derive from an interface. we have to implement the code or body of the function. A class gives you lots of free codc. an interface docs not. The error is generated as we have not given the code for al and :12 in yyy am dass zzz { public static void Mafnt) ( WY 3 = new WW): a-att); ddd :1 new yyy(); d. a2(); ) ) interface ddd { vold al(); void a2(); class wy : ddd | £ublic void a1() : ~{‘. ystcm. consotc. NrIt; .~tJnc('wy at’); gublic void a2(){
  14. 14. System. Conso| e.Writel. ine("YW a2"); } ) Output yyy at yyy 32 We get no errors because ms haw now implemented the code of al and :12. Looks wise we do no know whcthcr ddd is it clans or an interface as the syntax at the time of derivation is the same. d is an object that looks like an interface which is syntactically‘ correct 41 can be equated to .1 yyy in n yyy is It yyy + . 'l ddd. We can. by only llSll1f. ' :1. call mcmhcrw ofa ddd. lfi class zzz { public static votd Meant) { aaa a ; a i new aaat); ) ) interface aaa { } Compiler Error a. cs(6.5): error (380144: Cannot create an Lnstance of the abstract class or interface 'aaa' Even though an inIerfar: e anus ifi empty. we cannot write the keyword new in front of it. An interface contains no code and thus cannot be instantiated. However we are allowed to declare objects that look like . in interface. Therefore. in this case. the line am at. does not flag, ‘ an error. 3&5 d35$lI2 { public static void Main() ( } ) lntt. -rlaoc aaa ( void a1() { ) } Compiler Error a. cs(9.6): error CS0531: 'aaa. a1()': ntertaoe members can not have a definition Rcitcmting. an interface can only contain function prototypes. no code at all. The functions cannot have u definition. a. cs dass zzz
  15. 15. { public static void Main() X E { ) ) dass ( ) dass { ) dass { } Compiler Error a. cs(13,17): error cso527: wv : type In Intertaco list is not an Intortaco C93 does not support multiple irthctitnnoc. We can dcrivv: from a single class only at one point in time. M: dasszzz { gtblic static void Maino war a = new YWO; ddd d - new yyy(); r. t.a10; d. a2(); a. a1(); a. a2(); ) ) Interface ddd { void a1(); void a2(); ) dass yyy : ddd { public void ddi: l.a1() { System. ConsoIe. WrIteUne("a1"); } Ptbllt Void 820 { $ystem. ConsoIe. WtIteLine("a2"); ) ) Compiler Error a. cs(19,13): error CS0106: The morilier ‘public’ is not valid tor this item
  16. 16. You are not allowed to use the modifier public for -.4 function which llilx qualified its name with that of the irrleriliue. 3_-C_S. class zzz ( public static void l~1afn() { ) ) interface aaa { public void a1(); } Compiler Error a. cs(9,13): error CSOIC-5 The modllier ‘pub! -»: ' is not va' :1 tor this item Interface mcnibcrs are public by default. The access niodificrs am not allowed here. All the other ii‘s’CL'sS modiiicr rules remain the same as that from classes. The rulcx in Clalxscs stated that the base class must be at least as accessible as the derived class. Replace the word class with interface and you will not he OiTy, am dass zzz { public static void Main() ( WY 3 = 04‘-W YWO: ddd I! new yyy(); d. a1(); d. a2(); a. a1(); a. a2(); } ) interface ddd { void 310; void a2(); ) dass yyy : ddd { void ddd. al() ( $ystem. Console. Wriuei. ine("a1"); ) public void a2() ( System. Console. Wri0ei. ine("a2"); } ) Compiler Error a. cs(8.1): error CS0117: ‘yyy does not contain a dclln-lion tor 'at'
  17. 17. The reason we get an crmr is because we created the function nl in my as ddd. aI and not :11. By doing this. we were telling C# that only objects that look like ddd are nllovmd access to al. Even an object that looks like yyy is not allowed lo axccss‘ al. C ummcnt out Imc number 8 i. e. anal and all works fine as follows Output 8 I a2 :12 inc: class zzz { public static void Marno ( WV 3 = new vwt); ddd :1 new yyy(); cu: c new yyy(); a. a1(); a. a2(): d-610.’ 2.620; } } interface ddd { void .310; ) interface eee { void 320; } dass yyy : ddd , eee { public void al() ( System. Console. Wribel. ine("al"); ) public void a2() ( System. Console. wri0eLine("a2"); } ) output a1 a2 a1 a2 Hen: we am doing . ‘omcthin_-. ' that just cannot be done with classes. W’ are dL'l'i'illf. ' from two intcrfzaccx ddd and ccc at the some Iimt‘. Each has one function prototype al and .12 rexpcdivcl)‘.
  18. 18. Using it which look» like )3‘): we can call both at mid 32 but with d that looks like ddd we can only call ul. Similarly. with e only a2 can be culled. 3_-C_S. class zzz ( public static void l~1afn() { mt 6 new mo; ddd d = new yyy(); eee e = new yw(); a-alt); d. a1(); e. a1(); } } interface ddd ( void a1(); ) interface eee ( void a1(); } dass yyy : ddd , eee { public void 310 { System. Console. WrlteLine("a1"); } } Output at at at The two interfaces share the xaime function mime al. We do not get am error but _w. -t things do not seem tight. Both d and c call the same ml and then: is only one implementation of the function til. We would like to tum: tvm al's but we cannot have the '. tf'Ilt3 function defined twice in a class. as dass zzz { public static void I‘-lal‘n() { ddd d = new yyy(); eee e = new wy(); d. a1(); c. a1(); ) ) interface ddd
  19. 19. { void a1(); ) Interface eee { void a1(); ) dass yyy : ddd , eee { void ddd. a1() { Systern. console. WrlteUne(“ddd at‘); ) void eee. a1() ( System.0onsole. WtlteUne("eee at’); ) } Output M631 @9831 We did what we had explained earlier. We prefaced the name of the function with the name of the interface. Then we removed the modifier public and the object a which looked like yy)-. Now each interface hits its own copy of al to he called. ddd. nl is called the explicit interface member name. 3.13 dasszzz { public static void t-taint) { vw 3 = new WYO; a-all); l interface ddd { void :10; i)nterface eee Sold .110; glass wy : ddd , eee {rold ddd. a1() §yst: em. Ccnso| e.Nrihetjne("ddd at"); vlold eee. a1() {
  20. 20. System. Conso| e.Wrltet. ine("eee at‘); } ) Compiler Error a. cst6.1): error CSO117: 'yyy does not contain a dellnllon lor ‘at’ The reason we removed a was that once we have an explicit interface member. we cannot access it through the class. it is done only through the interface. This make a lot of sense as there are two functions of the same name. and C# does not know which one it should call. By prefacing the functions with the names of the interface. we are making them part of the interface and not the clas. In a sense they are private to the class. As there is no ftnction by the name of al in class yyy, we see the above error. M3 dass zzz { public static void Main() { ) ) interface ddd { void a1(); ) Interface eee ( void a1(); t class yyy : ddd { void ddd. al() { ) vold eee. a1() I ) ) compllor Error a. cs(21.6): error cso54o: 'yyy. eoo. a10': containing class does not Implement Intortaeo .399. We get an error as class yyy is derited only from interface ddd. '11|us we cannot use eee. aI() as interface eee is not a base interface for class yyy. as dass zzz { public static void Main() ( ) }
  21. 21. interfaoeddd { void 310; ) class yyy : ddd { void ddd. al() { ) ) class XXX 2 yyy ( void ddd. a1() { ) ) Compiler Error %3(t9.e): error csosao: 5cxx. ddd. a1()': containing class does not implement interface The key concept earlier was that we could only use the name of an interface explicitly if it was categorically stated as a base class. Anything indirect would not do. Here claws yyy is derived from interface ddd and thus we can use the form ddd. al. However even though class not is derived from class yyy and thus also fmrn interface ddd. we am not allowed to write ddd. a| as interface ddd is not explicitly stated in the derivation list of class xxx. An interface defines a contract and can only contain four entities viz methods, properties. events and indexers. An interface thus cannot contain constants. fields. operators. constructors. destructors. static constmctors, or types. Also an interface cannot contain static members of any kind. The modifiers abstract. public. protected. internal, private. virtual. override are disallowed as they make no sense in this context. as: dasszzz { ptbtic static void Main() ( l pwlic delegate void d1(); public interface aaa { void a1(string 5); int 32 { rt" 9°" event on ddd; string this(itt :1 { 931“. set". M
  22. 22. The above example demonstrates the four entities an interface can contain. Anything else will flag an error. as dasszzz { pdllic static void Main() { one c = new coco; aaa a = c; blah b I c; calozc-a2(); a. a1(); b-al(): b.a2(): } ) lnterfaoeaaa { void a1(); ) Interface bbb : aaa { void a2(); ) dassooczbbb | {3tblic void no . £,ystem. consoIe. wrioame('a1"); lzwlit ‘Did I10 : {‘>ystem. Console. Wrltset. lne("a2"); ) ) Output at 82 at a1 a2 An interface can also. like it class. inherit from one or more interfaces. In this case bbb as an interface. can inherit from as. The class ccc inherits from interface hbh and and thus interface am has to implement functions al and a2. The object c not only looks like a ccc but also looks like an mm and bbb. Thus equating them does not give an error. The reverse. however. is not true. It will obviously flag an error. However a can only access ftmctions from the interface it belongs to. in this case al and b can access al and :12. h cannot access members from class ccc even though a. b. and c have the same values. Whenever an interfaee derives [rum another it is called an explicit base interface. Like classes. circular definitions are not permitted. In fact nowhere in the C? ! programming language are we permitted to have circular definitiom.
  23. 23. At) interface also creates a new type and as in classes. methods must have their own unique signatures. Properties and methods czuinot have similar names. i; § dasszzz ( ptblit: static void Main() { } ) Interface aaa { void a1(); ) Interface bbb : aaa { void a1(); ) Compiler Waming a. cs(13.e): warning csoros: The keyword new is required on bbb. a10' because it hides Inherited rnemoer 'aaa. a1()' Like classes if interfaces derive from each other. there is a possibility that they may contain the same function signatures. Thus we get is wanting which can be removed by adding the keyword new as follows. interface bbb : an ( new void alt); } The point to he stressed here is that the keyword new really does not do much. other than remove the warning. This is because the implementation of the interface is done in the class. There. we will have only one implementation of ftmction al and not um. one for nae and the other for bbh. At one level. from the point of view of the class which derives from interface bhb. it will see only one function in it. not um. All that we are doing is hiding the base interface member. Llé class { gtblic static void Maint) ) void abc(cec c) { call); ((bbb)c)-08(1): ((aaa)c)«1a(l): c. aa = 2; ttaaaiclaa - 3; §(bbb)c). aa - 3;
  24. 24. } Interface aaa { Int aa { gfifisfi; ) interface bbb { void ea(Int I); ) Interfaoecoczaambbb { ) Compiler Error a. cs(8.1 ): error CS0229: Nnoloulty between ‘aaa. aa' and ‘bob. aa{tm)‘ a. cs(1o.1o): error csm 18: ‘aaa. aa' denotes a property‘ where a ‘method’ was expected a. cs(1 1.1): error CS0229: Ambiguity between 'aaaaa' and 'bob. aa(int)' 1es(13,10): error CS0654: Method bbb. ea(int)' referenced without parentheses Interface arm has only one member. a propeny called an. whereas interline bbb has one function called aa. 111e interface occ does not give us an error in spite of the fact that we have a propeny and a function with the same name. In the function abc. we are pmsing c. an object that looks like occ. The line c. na[l) gives us an error as we have a property and a function called on. C! gets confused whether it is the property or the function we are referring to. In our humble opinion. we could only be referring to the function as per the syntax. but you dont argue with a compiler. In the second case cat: = 2 also flags an error due to the name confusion. In this case also. we could only be referring to a property. The only way out is to cast. 'lhe second cast in each case gives an error as the syntax for calling it function and pmpetty is difl"erent. Normally. to cast. we need to give two sets of lncloets. A cast incurs no mn time costs i. e.. it does not slow down the program. All that is cast does in the above case is lowers the pointer from a ccc to an or bbb at compile time. In an earlier example. we spoke of functions from two interfaces having similar names. The same rules stated then: apply here also. an dasszzz ( public static void Main() { } void ebe(coc c) { caat 1); C-3i((btN! )1); ((aM)¢). aa(1): §(bbb)c)-68(1): }
  25. 25. interface aaa Sold aa(b~/ be r); i)nterface bbb {rold aa(short i); interface ccc : aaa . bbb } Compile’ Error a. cs(8.1): error (280121: The call is ambguous between the following methods or properties: bbb. aa(short)' and 'aaa. aa(byte)' a. cs(9.1): error (380121: The call is ambiguous between the following methods or properties: bbb. aa(shcn]‘ and 'aaa. aa[byte)' We have : t similar problem again. c. .1a( I) does‘ not know which function :13 to cull. C** could L‘UlIH'Il the I an int. either to at short or at byte. Thus the airibiguily. Even if we cast the l to it byte. for some reason, Cf? yet given us an error. The only wary out is like what we did earlier, explicitly cast your way out of trouble. When we cast. we are restricting ourselves to only one method and thus no ambiguity. E dass zzz ( public static void l-lain() ( ) } interface aaa { void .330: ) interface bbb : aaa { new vold aa0; ) interface cc: : aaa { void 0:0: } interface ddd : bbb , co: { ) dass eee : ddd { } Compiler Error a. cs(22,7): error CS0535: 'eee‘ does not implement interface member 't: «bb. aa()' a. cs(22.7): error CS0535: 'eee' does not implement interface member 't: t:t: .cc{)'
  26. 26. a. cs(22.7): error CS0535: 'eee' does not implement interface member 'aaa. aa(J' The interface aaa has one function a. The interface bbb is derived from aim and also has one function called an. The keyword new informs the Cit compiler that. it has hidden or has nothing to do with the function as in interface aaa. Remember in interfaces. we cannot write my code. The interface ecc also derives from art: but does not have a function called an. Then we are creating another interface ddd which derives from both bbb and cec. The class eee is then derived from interface ddd. We get three errors as we have to implement three functions in class tree. The interface ccc brings in two functions. One cc and the other no from interface an. The interface bbb has only one function. aa which is different from the an which is present in interface aaa. thanks to the keyword new which is optional. i; .§ dasszzz ( public static vold Maino { ea: 3 - new eee(); a. aa(); bbb b = new eeeo; b-330; ace c - new «:0; cut); ddd d = new eee(); Mal); eee e - new eee(); /le. a80.' (taaaldl-aaoz ((bbb)d)-330; ((c0t)d)aa(); §(ddd)d). aa0; } Interface an { vold aa(); ) Interface bbb : aaa ( new vold aat); ) interfaoecoczaaa { void (:0; ) Interfaoedctd : bbb, ooc ( ) dasseeezddd ( vold eaa. aa() {
  27. 27. System. Console. Writet. ine("aa aaa"); } vold bbb. aa() { System. Cunsole. Writ: eLine("aa bbb"); } public void oc() { System. Console. WriteUne("cc'); } ) Output aa aaa aa bbb aa aaa a bbb aa aaa aa bbb aa aaa a bbb With or without the keyuord new. the output remains the same. By adding the keyword new. all that we have achieved is removal of the warning. Lets explain the above program step by step. We have implemented the three functiom that chm eee needed. We could have implemented only one an. and then in every case that one ua. would have been culled. In this case we need two aa functions. One for the interface aim and the other for the interface bbb. As we need a separate function sun for each interface we will land up having two of them. Thttx we need to preface them with the nztmc of the interface. We are creating objects that look like all our interfaces and initializing them to an object that looks like Clttss eee. The object a that looks like interface amt. will obviously call the an of interface .133. The object b that looks like interfaze bbb will call the an of interface aazi implemented in class eee. The object c. that look» like we is derived from interface ztuu and thux it will call the function an of intttrfuctr anti. All of this is obvious. Now d looks like ddd which is derived from race and bbb. The reason it will call the an of bbb and not of anti is because we have asked it to hide the function an of interface Once at function is hidden. it will remain hidden forcvcr in all the atcccxs paths Thus function an of interface hhb bid. -x the function tut of intcrtktcc uaa even in interface ccc. The existing gives ux the same answer as above. In the first case. cast (1. at ddd looks alike to an ll. ll£L Thus the an from Jan gets called. In the second case it calls the an of bbb. Just like before. when we cast c to a ccc. it calls the an form amt . Now we cast c to a ddd. it can call either the function uzt from bbb or function tttl front zuta. In this case it choo~e- to call the an front bbb as ilx an hides the an of interface Lttul. To sum up. if ; t function is hidden from one illZOL‘ path. it is hidden from all. A little later in this chapter. we will show you that stmctuies can also implement from an intcrface. This process of implementing all the functions is called interface mapping. 6.6
  28. 28. dasszzz { public stattc vold Mazno { } } tntcrfaoc aaa { void a1(); } lntcrtaoc bbb : aaa ( new Int at { Set: ) ) dasscnc : bbb { vold aaa. a1() { } Int bbb. a1 { N/ HV'fiu E class ddd: bbb { public void a1() (} Int bbb. a1 ‘9‘Vfir§§% dass eee: bbb ( void aaa. a1() { ) public Int at V‘NfV#H§4-'- The interface am: has one function al which clashes with the name of the pmfx-rty in interface bbb. We have three ways to ctcate at chm which i' derived from bbb. In the first ca»: ccc. we are
  29. 29. explicitly qualifying with the name of interfaice. In the second one of ddd. we are qurrlifying only the property und not the function. In the third case i. e. class tee. we do the reverse. Thus one of the nlor both must be qualified or else it will result in an error. ass dasszzz I public static void Ma>'n() I ) } Interface oaa ( vold at(); } Interface bbb : aaa I void a2(); ) Interface ccc : aaa I vold a3(); } dass ddd : aaa, bbb, ccc { void bbb. a1() { } public vold a2() { } public void 330 I } } Compiler Error a. cs(21.6J: error CS0539: bbb. a1' In uxpllclt interface declaration is not a member of interface a. es(t9,7): error CS0535: ‘ddd’ does not implement interface member 'aaa. at (]' Both interfaces bbb and ccc derive from interface and. C la» ddd derives from three interfacex mm and bbb and cu‘ in chm ddd. we have only 3 functiom. 31'. a2 and 33 that come from mun. bbb and ccc respectively. liven though interface bbb derives from arm. it does not carry nl into class ccc. So. we cannot write bbb. al in clan ccc. Hence. the have only one at from interface Jan in L‘l4'L' cce and none fnorn ilIleI'f:1-Sew‘ bbb and ccc. This proves that Cir‘ forgets the lI'll€I’f: ‘1Ce bbb and Ca‘ are dcnvcd from. It also l! K'£ln. that bbb and ccc cannot have their mm implcmcntzrurms of al. fl. £S dasszzz I public static void l~1aln()
  30. 30. { aaa a new coco; a. a1(); } } interface aaa {I0ld a1(); t}: lass no gublsc vold al() §ystem. Console. VVrihel. ine("bbb at"); ) class CCC : bbb. aaa { ) Output boo at Th: -. class act’ dcrivcs from bbb and min. Th: fundion all from irttcrtlwc nun is impk-menu-d by clam bbb and not by ccc. No one cures as long as there is a function nl some'whcrc. The function u I . in this case. can he in the actual clam or in the haw clam. a. cs dass zzz { public static void Marno ( bbb b = new coco; b. a1(): occ c new ocq); c. a1(); aaa a = new coco; a. a1(); aaa a new bbbo; aa. a1(); ) } interface aaa (¢old a1(); glass bbb : aaa nubile vold a1() §ystem. Consute. VVrihet. ine("bbb al”); )
  31. 31. class coczbbb { new public void a1() { System. Console. WrlteUne("cnc 31'); } } Output bbb at car: at bbb at bbb at In this case. class ccc is derived front class bbb. which in tum i~ derived from interface ztasr. Both the classes implement the function al. The question on our minds is from which class will the function al he called. Both b and c are initialized to an object that looks like ccc. b. al() will obviously call the function al from bbb and call ) will call it from ccc. Saying the same thing over and over again like u malfunctioning record disk is trying but essential. Objects a and an look like turn but are initialized to objects that look like ccc and bhh respectively. It does not «cm to make any difference as earl: time the function ul gets called from the base class bbb and not from the derived class ccc or the class that we have initialized the object to. This means that the derived class cannot alter the interface mappings it receives from the ham: clam. The mapping of function at is to the clam bbb us bbb was derived from the interface. Clam ccc cannot change this fact. 6&5 UBSSZZZ ( public static vold Ma«'n() { bbb b new coc(); b. a1(); bbb bl = new bbbo; bi. a1(); ccc c new occ(); e. a1(); aaa a = new coco; a. a1(); aaa a new bbb(); aa. a1(); } l interface aaa Sold a1(); r}: lass bbb : aaa gubllc virtual vold a1() £. iystem. Console. Wti0eLine("bbb 31"); }
  32. 32. } dasscoczbbb { public override vold alt) { System. Conso| e.WrItsel. ine("ooe at’); } ) Oulptl cecal bbbat oocat eocat bbbat We have made two changes in our program. We made the function al virtual in the class bbb and also. in the class ccc. we declared al with the override modifier. Whenever we declare a function to be virtual. the derived classes will and can override it The modifier override has the opposite meaning over new. It means do not create a new function but override the base clms definition. Objects b and bl both look like bbb but are initialized to objects that look like ccc and bbb respectively. When we write b. al(). C8 first looks into the class bbb m that is the data type of h. Here the function all is marked virtual. so Cit now mks ‘what was I: initialized by‘? As the answer is an object that looks like ccc. CO now looks at the class ccc for the function at. As it is marked override. C# will execute the function all from class ccc and not bbb. If the override win missing. the default is new. and the function will he called froth the data type of the object i. e. bhb. As object bl has been initialized by an object that looks like bbb, C0 will call al from class bbb only. The object c follows the earlier specified nrles. M for objects a and an. both look like interface arm which has no code for the function aaa. Here the object used to initialize will decide the class al will be called from. This is due to the explanation above as al is marked virtual in class bbb and override in class we. as classzzz { garlic static void Main() ) ) interface ppp { vold a1(); ) Interface aaa { vold a1(); ) dassbbb: aaa, ppp { ptblic virtual vold aaa. a1() {
  33. 33. System. Console. WribeUne("bbb at"); } ) dass ooczbbb { public override vcfd a1() { Systcm. Consolc. Vvrltcl. inc("ooc a1’); ) } Compiler Error a. cs(1721): error CS0106: The modifier ‘public’ is not valid tor this item a. cs(l7.2l): error CSOIOS: The modifier ‘virtual’ is not valid for this item Lets ntul; -2 muucix worse. We have an inlcrfacc ppp which aim brings in :2 function called ~. rl. The class bbb zil~o derives from ppp. Thus we have two ul functions and we have to explicitly qualify them. Unfonnnatcly we cannot add the qualifier virtual here. The only way out is as follows. 15 dasszzz { public static vold Malno { aaa a new ooc(); a-all); aaa a = new bbb(); aa. a1(); } ) Interface ppp { void al(); } interface aaa ( void a1(); } dass bbb : aaa , ppp I void aaa. a1() { Ball); } void ppp-all) § public virtual void aa1() { System. Console. WribeUne("aa1"); ) ) class cat 2 bbb {
  34. 34. public override vc’d aal() { System. Console. WrlbeLme("aa1 ccc“); } } Output aal ccc aat What we have done here is that in the al function nf aura we have called the function :13]. So in other vmrds, ill simply culls stall. We have made autl vinual such that each time hall is called. the question asked will be - which object Wéb used at the time of initistlizutiun‘? Depending upon the type of object. the relevant function zul would be executed. Thus we get the same answer as earlier. If we have to reimplcmem an interface. you can look at the example earlier. C? fongctx about the initial tlcrivution. 6.95 dasszzz { public static vold Matno { } } Interface aaa ( vold a1(); void a2(); ) abstraa class bbb : aaa { } Compiler Error a. cs( 12.16): error CS0535: ‘bbb’ does not implement fntertace member 'aaa. a1()' a. t:s(l2.16): error CS0535: ‘bbb’ does not implement interface member ‘aaa. a2()‘ Whenever we have 41 abstract clam deriving from an interface. the cl. 'Ls. ~. must implement all the methods of the interface its follows 3.95 dasszzz { publvc static vold Mafno { ) ) Interface aaa { void a1(); void 320; )
  35. 35. abstract class bbb : aaa { ptmlic void a1() ) public abstract void a2(); ) If the abstract elm does not want to implement all the members of the interface. it has to mark the functiom as abstract and public. The class deriving from bbb will nnw have to supply the code of the class bbb Structures E. -Q dass { ptblic static vold t-taint) { toot x - new xxx(10); $ynem. ConsoIe. wrlteune(x. l); x. abc0; } ) SCVIKIXXX { pubr-cinti; wblic mt ht! ) { i - 1'; ) llbllt VIM IMO { System.0orsole. Writet. ine('abc'); ) } Output 10 abr: A structure or strucl to be precise is similar to a class in many ways. A struct can contain fields, methods etc. If a struct and class were I00 per cent similar. than why have both? We will now explain the differences between at struct and a class. Unless otherwise stated. they share the same features. 15 dasszzz { ptbllc static void Matno { )
  36. 36. ) suuct xxx ( public Intl = 10; } Compiler Error a. cs(9.12): error CS0573: ‘xxx. i‘: cannot have instance field initializers in structs In -.1 class we are allowed to create a fieldlvariablt: and initialize it at the ‘. tnll. ‘ time. A structure cannot contain such initiulizzitiom Thu~ thew fields must be initialized either through functionx or by using the object itself. Fields cannot be given initial values at the time of mtation. LG dasszzz { public static void Mai'n() ( root a = new xxx(); ) } struct xxx { public int i; public xxx() ( } } Compiler Error a. cs(11.8): error CS0568: Structs cannot contal n expli-: it paramaterless constructors A class can contain many constructors. And even if we do not have any. C# supplies a free eonstnictor with no pumnrcterx. It's very different with . Illi'llll'0.. You cannot have at l. Z(. ‘lIlI'llCl0l‘ with no parameters. If you do. you will get the above error. Thus C It lets you have as many constructors as you like but none without parameters. B45 class 222 { public statlc vold Mamt) { not a = new xxx(lO); ) } structzoot l public int i; |)3ublic xxx(int p) { ) Compiler Error a. cs(l0.8): error csom: Held 'xxx. r must be luly assigned before contro‘. leaves the constructor
  37. 37. A small problem here. As mentioned earlier we cannot initialize at Field like we do in a class. Hence C3 insists on constructors that accept pararnetets to initialize fields: at the end of the constructor if you have not initialized the fields in the structure. we get the above error. Thus C8 actually reads our code and makes sure that the constructor initializes all the fields in the structure. §-_§ class ( ptblic static void Mainfl { not a I new xxx(10); ) ) sbructxxx { pubtgc Inu. _1; Plbllt xxx(Int p){ | ' P? l ) Compiler Error a. cs(11.§): error CSO171: Field ’xxx. j' must be twy assigned before control leaves the constructor 'I'he keyword shown in all the above errors is fields. Lg class { public static vold Maino { )00( a - new )0tX(l0); ) ) structxxx { public Int 0,); Emile xxx(Int p) I - D; J = 0: ) } We get no error as the stmctun: has two fields and we tnve now initialized both of them. MS dasszzz { public static vold Main() { not a I new aozxo;
  38. 38. System. Conso| e.Writet. ine(a. l); } ) SUUCI XXX { public int i; ) Compiler Warning a. cs(11.12i: warning CSOB49: Feid 'm«. -' is never assigned to. and will aiways have its deiault vaiuu 0 Output 0 If we do not have any constmctorx, we get no error. As we have not initialized thc field i, in the constructor. we have none. Ci. ‘ gives you it warming and for the sake of your sanity. initrnlizes i to 0. 3&5 dass zzz { public static void Ma>'n() ( not a new xxxt); System. Console. WriteLine(a. l); ) ) struct xxx { public int i: ) struck vyy : xxx { } Compiler Error a. cs(13,14): error CS0527: ‘xxx’ type n lntertace list as not an interiace A structure yyy cannot be derived from ammhcr slntclttrc. A useful fcutun: of at C| .'r. x was the fact that we could shareluse code from other classes. A structure does not support the concept of inheritance. Had xxx hccn at claim we imuld have received the same error. as dass zzz { public static void Ma: 'n() ( not a = new yyy(); ) } lntcrtaoc XXX {
  39. 39. YWZXXX Vtrfigfifl The previous error message gate us a hint . It expected not to be a interface. Thus we can derive a suucture from an interfttce. As xxx has no members we do not hate to implement any code in our structure. an dasszzz { pibiic static void Main() ( XXX a = new mo; 3.. . WV Vfifihifi 3 3 Compiler Error a. cs(t 1,7): error CS0509: xxx’ : cannot Inherit lrorn sealed class wy’ As a structure could not inherit from it class. the reverse is also true. xxx cannot inherit from a structure yyy. Internally a structure behaves as a sealed class as the error rnessage reads. For those who came in late. a sealed class cannot be used a base class. £§ class §tl: ii'| c staticvoid Main() ; rm” ) Compiler Error a. cs(7.15): error csoioez the modifier ‘sealed’ is not valid tor this item You cannot declare a structure as sealed as they are by definition sealed. If you add the word sealed in we have done. Cit complains about the fact that we are repeating the same modifier again and nobody likes repetition. LG CBSSZIZ { public static void Main()
  40. 40. abstroctstructyyy { ) Compiler Error e. cs(7.17): error CSO106: The modifier ‘abstract is not vald for this item As C! ) does not like repetition. we have to bow to its wishes. But you do not have an option. We are free to repeat ottselves with you as many times as we like. So let us indulge ourselves. A structure as mentioned earlier cannot be used as a base class i. e. be used in it derivation. An abstract modifier. meats an incomplete entity which cannot be used directly but only as a tune close. It makes no sense for a structure to use the modifier abstract. In the same vein. function in it stmcture cannot be marked abstract or virtual as these are concepts. which apply to derived closes only. Q-_§ dass Etbiicstaocvold Main() i P'00ect: edstruct! ¥X{ } Compiler Error &cs(7.1 ): error CS1527: Narnespeoe elements cannot be explicitly dedared as private or protected A structure cannot be derived from and the modifier protected deals with the visibility of members from derived classes. Replacing protected with private results in the saune error. §: .§ dasszzz { ptbllc static void Main() { WY 8 - MW WVO; ?ystem. Oonsole. Vltrltet. he(a. ToStrIng()); ) struct yyy { ) Output WY However every stnrcture like a class is implicitly derived from the class Object and thus has the functions Object contains. In this case Tostring returns the name of the derived class.
  41. 41. an dasszzz { public static vold Main() { war a = new wv(); Sys%em. Coosole. lNritel. 'ne(a. ToString()); ) ) suuct yyy : Systemobject { ) Compiler Error a. cs(9.14): error CS0527: 'Systarn. Object‘ : type in interface list is not an ‘nterlace How do we explain the above error? We just mentioned earlier that as l stnrcture inherits from the class Object and we called a function called Tostring front the class Object. However we cannot derive from Object explicitly as the compiler insists on the name of an interface and Objea is a name of a class. These little quirks make learning C# clifiicult. If you replace the word struct with class in the above example. you will not get an en'or. A computer has lots of memory. We logically divide this memory into two. the stack and the heap. Memory denoted as the stack lives as long as the function lives and heap memory lives as long as your program runs. Objects. instances of a class are allocated on the heap. They will live for a long time. They are also called reference objects. Structures are allocated on the stack by new and live for a shorter duration. We call them value objects. This means that a structure directly represents the data where as a object contains a reference to the data. Structures thus offer it more efficient access to variables than classes. Int. bool and all the other basic data types are implemented as structures. 3.53 dasszzz { pmlic aatte vold Matno ( 300‘ ‘W3 nwmm x - new ioor(1); y - new xxx(2); a = new mitt); b = newywtz); Svstem. Conso| e.WrlteUne(x. i + " " + y. I + " " + at + " ' + b. i); X-we-m System. ConsoIe. WrlteL'ne(x. i + " " + y. I + " " + ai + " ' + b. i); x. l = 100; a. l = 200; Svstem. Console. WriteUne(x. i + " " 4» VJ + ' " + a. i + " ' + b. i); } ) dass yw { public int i;
  42. 42. Public vw(int ll { I =1: ) ) struct xxx { public bit I; ptlalic aoor(intj) I - J; ) ) Output 1212 2222 1002200200 We have created N0 objects a and h which look like a class yyy and two structures it and y which look like xxx. In the constructors of each. we are initializing the field i to I and 2 respectively. Then we are equating the object a to b and the structure at to y. This will set the i of x to 2 frvorn I and also the i of at to 2. Thus the second WriteLine displays all two's. We are now changing the i of x. which is a structure to 100 and we realize that the i of y. the structure it was initialized to remains the same. Thus x. i is I00 and y. i remains at 2. For classes it does not work the same way. Gnmging ml to 200. somehow changes the i of b which a was initialized to. also to 2(1). This could only be possible if when we equate structures, each has its own copy of the data. When we equate objects. no copying takes place and now object ll refers to object b in memory. Both ll and I) represent the same object. Changing a change; b. A little later. we dwell on this concept further. The same rules of passing parumetens to ll function i. e. out and ref that apply to an int also apply to I structure as int is also in structure intemally. 3.5 classzzz { public static vold Maino
  43. 43. Compiler Error a. cs(7.3): error CSC037: Cannot convert null to Xxx‘ because it is a va'ue type In computer programming. :1 large number of time» we do not know the value of at variable at at point in time. Tlrese variables are given a value of null. Null can be only applied to objects of reference types and not value types. us dasszzz { public static vold Maln() l } } struct xxx ( public ~xxx() { } ) Compiler Error a. cs(9.9): error CS0575: Only class types can contain destructors After a long time. we get an en'or mcwtgc that is readable. Structures are created on the stack and die when we reach the closing brace. There is thus no memory management to be done from the point of view of the programmer. The structure life cycle is very dctcrrninistic and hence no dcstructors are pemrittod.