Friday, April 12, 2019

Virtual Functions - new and override

Every breath you take,
And every move you make
Every bond you break, every step you take
I’ll be watching you

-Every Breath You Take,Sting


New and Override Methods

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
xxx b = new xxx();
yyy c = new xxx();
a.abc();a.pqr();a.xyz();
b.abc();b.pqr();b.xyz();
c.abc();c.pqr();c.xyz();
}
}
class yyy
{
public void abc()
{
System.Console.WriteLine(“yyy abc”);
}
public void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
public void xyz()
{
System.Console.WriteLine(“yyy xyz”);
}
}
class xxx : yyy
{
public void abc()
{
System.Console.WriteLine(“xxx abc”);
}
public void pqr()
{
System.Console.WriteLine(“xxx pqr”);
}
public void xyz()
{
System.Console.WriteLine(“xxx xyz”);
}
}

Compiler Warning
a.cs(30,13): warning CS0108: The keyword new is required on 'xxx.abc()' because it hides inherited member 'yyy.abc()'
a.cs(34,13): warning CS0108: The keyword new is required on 'xxx.pqr()' because it hides inherited member 'yyy.pqr()'
a.cs(38,13): warning CS0108: The keyword new is required on 'xxx.xyz()' because it hides inherited member 'yyy.xyz()'

Output
yyy abc
yyy pqr
yyy xyz
xxx abc
xxx pqr
xxx xyz
yyy abc
yyy pqr
yyy xyz

Class xxx derives from class yyy. That makes xxx the derived class and yyy the base class. The class xxx comprises yyy and more. Thus can we not conclude, albeit in broken English that an object that looks like xxx is bigger than one that looks like yyy. In C#, you can equate a smaller object to a bigger object as stated earlier.

Lets take the case of object a. It looks like yyy and initialized by creating an object that also looks like yyy. When we call the functions abc and pqr and xyz through the object a obviously it will call them from yyy.

Object b looks like xxx, the derived class. It is initialized to an object that looks like xxx. When we call abc, pqr and xyz through b, it calls abc, pqr and xyz from xxx.

Object c again looks like yyy but it is now initialized to an object that looks like xxx which does not give an error as explained earlier. However there is no change at all in the output and the behavior is identical to that of object a. Hence initializing it to an object that looks like yyy or xxx does not seem to matter.

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
xxx b = new xxx();
yyy c = new xxx();
a.abc();a.pqr();a.xyz();
b.abc();b.pqr();b.xyz();
c.abc();c.pqr();c.xyz();
}
}
class yyy
{
public void abc()
{
System.Console.WriteLine(“yyy abc”);
}
public void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
public void xyz()
{
System.Console.WriteLine(“yyy xyz”);
}
}
class xxx : yyy
{
public override void abc()
{
System.Console.WriteLine(“xxx abc”);
}
public new void pqr()
{
System.Console.WriteLine(“xxx pqr”);
}
public void xyz()
{
System.Console.WriteLine(“xxx xyz”);
}
}

Compiler Error
a.cs(30,22): error CS0506: ‘xxx.abc()’ : cannot override inherited member ‘yyy.abc()’ because it is not marked virtual, abstract, or override

We get an error because we have added two new modifiers, new and override to the functions. The error says to add the modifier virtual to the functions in the base class.

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
xxx b = new xxx();
yyy c = new xxx();
a.abc();a.pqr();a.xyz();
b.abc();b.pqr();b.xyz();
c.abc();c.pqr();c.xyz();
}
}
class yyy
{
public virtual void abc()
{
System.Console.WriteLine(“yyy abc”);
}
public virtual void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
public virtual void xyz()
{
System.Console.WriteLine(“yyy xyz”);
}
}
class xxx : yyy
{
public override void abc()
{
System.Console.WriteLine(“xxx abc”);
}
public new void pqr()
{
System.Console.WriteLine(“xxx pqr”);
}
public void xyz()
{
System.Console.WriteLine(“xxx xyz”);
}
}

Output
yyy abc
yyy pqr
yyy xyz
xxx abc
xxx pqr
xxx xyz
xxx abc
yyy pqr
yyy xyz

There is a single subtle change in the workings of the objects c only and not a and b. Adding the virtual modifier has made all the difference. The difference is in the object c. c looks like the base class yyy but is initialized to an object that looks like the derived class xxx. C# remembers this fact. When we execute c.abc(), C# remembers that object c was initialized by a xxx object and hence it first goes to class xxx. Here the function has a modifier override which in English means, forget about the data type of c which is yyy, call abc from xxx as it overrides the abc of the base class. The override modifier is needed as the derived class functions will get first priority and be called. We mean to override the abc of the base class. We are telling C# that this abc is similar to the abc of the base class.     

New has the exactly the opposite meaning. The function pqr has the new modifier. C.pqr() calls pqr from yyy and not xxx. New means that the function pqr is a new function and it has absolutely nothing to do with the pqr in the base class. It may have the same name pqr as in the base class, but that is only a coincidence. As c looks like yyy, the pqr of yyy gets called even though there is a pqr in xxx. When we do not write any modifier, then it is assumed that we wrote new. Thus every time we write a function, C# assumes it has nothing to do with the base class. These modifiers can only be used if the function in the base class is a virtual function. To us virtual means that the base class is granting us permission to call the function from the derived class and not the base class. We have however one caveat, we have to add the modifier override if our derived class function has to be called.

a.cs
class zzz
{
public static void Main()
{
yyy a = new xxx();
yyy b = new vvv();
xxx c = new vvv();
a.abc();a.pqr();a.xyz();
b.abc();b.pqr();b.xyz();
c.abc();c.pqr();c.xyz();
}
}
class yyy
{
public void abc()
{
System.Console.WriteLine(“yyy abc”);
}
public virtual void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
public virtual void xyz()
{
System.Console.WriteLine(“yyy xyz”);
}
}
class xxx : yyy
{
public virtual void abc()
{
System.Console.WriteLine(“xxx abc”);
}
public new void pqr()
{
System.Console.WriteLine(“xxx pqr”);
}
public override void xyz()
{
System.Console.WriteLine(“xxx xyz”);
}
}
class vvv : xxx
{
public override void abc()
{
System.Console.WriteLine(“vvv abc”);
}
public void xyz()
{
System.Console.WriteLine(“vvv xyz”);
}
}

Output
yyy abc
yyy pqr
xxx xyz
yyy abc
yyy pqr
xxx xyz
vvv abc
xxx pqr
xxx xyz


Pretty long example. To reiterate, we are allowed to initialize a base object to a derived object. The other way around will generate an error. This leads to an object of a base class being initialized to an object of the derived class. The question that now springs to mind is, which function will get called. The one from the base class or the derived class. If the base class object declared the function virtual and  the derived class used the modifier override, the derived class function will get called. Otherwise the base class function will get executed. Thus for virtual functions, the data type created is decided at run time. All functions not tagged with virtual are non virtual, and the function to be called is decided at compile time, depending upon the static data type of the object. If the object is initialized to the same data type, none of the above apply. Whenever we have a mismatch, we need rules to resolve the mismatch. Thus we can land up with a situation where an object to a base class can call a function in the derived class.

The object a looks like yyy but is initialized to the derived class xxx. a.abc(), first looks into the class yyy. Here it checks whether the function abc is virtual. The answer is an emphatic no and hence everything stops and the function abc gets called from class yyy. a.pqr does the same thing, but the function now is virtual in class yyy. Thus C# looks at the class yyy, the one it was initialized to. Here pqr is flagged with the modifier new. This means that pqr is a new function which has nothing to do with the one in the base class. They only accidentally share the same name. Thus as there is no function called pqr (as it is  a new pqr) in the derived class, the one from base class gets called.  In the case of a.xyz(), the same steps are followed again, but in the class yyy, we meet the modifier override, which overrides the function in the base class. We are telling C# to call this function in class xxx and not the one in the base class yyy.

The object b which also looks like class yyy, is now initialized with an object that looks like vvv and not xxx like before. As abc is non virtual it gets called from yyy. In the case of function pqr, C# now looks into class vvv. Here it sees no function pqr and hence now looks into class xxx. Thus the above rules repeat and it gets called from class yyy. In the case of b.xyz, in class vvv, it is marked new by default and hence this function has nothing to do with the one in class yyy. Hence the one from vvv does not get called but the one from class yyy where it specifies override.

public override void xyz()
{
System.Console.WriteLine(“vvv xyz”);
}

If we change xyz in class vvv to the above, i.e. we change new to override, the xyz of vvv will get called.

The last object c looks like xxx but is now initialized to an object that looks like the derived class vvv. c.abc(), first looks into class xxx where it is marked as virtual. Remember abc is non virtual in class yyy but virtual in xxx. From now on, the function abc is virtual in vvv also but not in class yyy. Virtual is like water, it flows downwards not upwards. As abc is virtual, we now look into class vvv. Here it is marked override and hence abc gets called from class vvv. In the case of pqr, pqr is marked virtual in class yyy and new in xxx, but as there is no function pqr in vvv, none of the modifiers matter at all. Thus it gets called from class xxx. Lastly for function xyz, in class vvv it is marked new. Hence it has no connection with the xyz in class xxx and thus function xyz gets called from xxx and not yyy.

a.cs
class zzz
{
public static void Main()
{
}
}
class yyy
{
public virtual void pqr() {}
}
class xxx : yyy
{
public new void pqr() {}
}
class vvv : xxx
{
public override void pqr() {     }
}

Compiler Error
a.cs(17,22): error CS0506: ‘vvv.pqr()’ : cannot override inherited member ‘xxx.pqr()’ because it is not marked virtual, abstract, or override

We get an error as the function pqr in class xxx is marked new. This means that it hides the pqr of class yyy. Form the viewpoint of class vvv, xxx does not supply a function called pqr. The pqr in class xxx has nothing to do with the pqr in yyy. This means that the function pqr of xxx does not inherit the virtual modifier from the function pqr of class yyy. This is what the compiler is complaining about. As the function pqr in xxx has no virtual modifier, in vvv we cannot use the modifier override. You can, however, use the modifier new and remove the warning.

a.cs
class zzz
{
public static void Main()
{
yyy a = new vvv();
a.pqr();
xxx b = new vvv();
b.pqr();
}
}
class yyy
{
public virtual void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
}
class xxx : yyy
{
public virtual new void pqr()
{
System.Console.WriteLine(“xxx pqr”);
}
}
class vvv : xxx
{
public override void pqr()
{
System.Console.WriteLine(“vvv pqr”);
}
}

Output
yyy pqr
vvv pqr

and if we remove the override modifier from pqr in vvv we get

public void pqr()
{
System.Console.WriteLine(“vvv pqr”);
}

Output
yyy pqr
xxx pqr

That’s the problem with virtual functions. We call them the cause of migraine. The answers are always different from what you expect. Object a looks like a yyy but is initialized to the derived class vvv. As pqr is virtual, C# now looks into class vvv. However before looking into the class, it realizes that in class xxx, pqr is new. This cuts of all connection with the pqr in yyy. Thus the word new is preceded with virtual, otherwise the override modifier would give us an error in class vvv. As pqr in class xxx is new function, having nothing to do with the class yyy, class vvv inherits a new which also has nothing to do with the class yyy. The pqr in class vvv is related to the pqr of class xxx and not of class yyy. Thus the pqr of class yyy gets called.

In the second case object b looks like class xxx now but is initialized to an object of class vvv. C# first looks at class xxx. Here pqr is new and virtual, which makes it a unique function pqr. Unfortunately, the pqr in vvv has the override modifier which sees to it that the pqr of vvv hides the pqr of xxx. This calls the pqr of vvv instead. If we remove the override modifier from pqr in class vvv, the default is new, that cuts off the umbilical cord from the pqr of xxx. Thus, as it is, a new function, the pqr of xxx gets called.

A virtual function cannot be marked by the modifiers static, abstract or override. A non virtual function is said to be invariant. This means that the same function gets called always, irrespective of whether one exists in the base class or derived class. In a virtual function the run-time type of the instance decides on which function to be called and not the compile-time type as is in the case of non virtual functions. For a virtual function there exists a most derived implementation which gets always gets called.

a.cs
class zzz
{
public static void Main()
{
yyy a = new vvv();
xxx b = new vvv();
www c = new vvv();
vvv d = new vvv();
a.pqr();b.pqr();c.pqr();d.pqr();
}
}
class yyy
{
public virtual void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
}
class xxx : yyy
{
public override void pqr()
{
System.Console.WriteLine(“xxx pqr”);
}
}
class www : xxx
{
public virtual new void pqr()
{
System.Console.WriteLine(“www pqr”);
}
}
class vvv : www
{
public override void pqr()
{
System.Console.WriteLine(“vvv pqr”);
}
}

Output
xxx pqr
xxx pqr
vvv pqr
vvv pqr

One last explanation of virtual with a slightly more complex example involving 4 classes.

The first line in Output, xxx pqr, is the result of the statement a.pqr();. We have the function pqr as virtual in class yyy. Hence, when using new, we now proceed to class xxx and not vvv as explained earlier. Here, pqr has an override and C# knows that class www inherits this function pqr. In class www, as it is marked as new, C# will now backtrack and not proceed further to class vvv. Hence the function pqr gets called from class xxx as shown in the output.
public override void pqr()
{
System.Console.WriteLine(“www pqr”);
}

If we change the function pqr in class www to override, then C# will proceed to class vvv and call the pqr of class vvv as it overrides the pqr of www. Remove the override from pqr in class vvv and the function will get called from class www as the default is new.

For object b, everything remains the same as object a, because it overrides the pqr of class yyy.

Restoring back the defaults, lets look at the third line. Object c looks like www. In class www, pqr is a new and hence it has nothing to do with the earlier pqr functions. In class vvv, we are overriding the pqr of class www and hence the pqr of vvv gets called. Remove the override and then it will get called from class www. The object d thankfully follows none of the above rules as the left and the right of the equal to sign are the same data types.

An override method is a method that has the override modifier included on it. This introduces a new implementation of a method. You cannot use the modifiers new, static or virtual along with override. However abstract is permitted.

a.cs
class zzz
{
public static void Main()
{
yyy a = new xxx();
a.pqr();
yyy b = new www();
b.pqr();
}
}
class yyy
{
public virtual void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
}
class xxx : yyy
{
public override void pqr()
{
base.pqr();
System.Console.WriteLine(“xxx pqr”);
}
}
class www : xxx
{
public override void pqr()
{
base.pqr();
System.Console.WriteLine(“www pqr”);
}
}

Output
yyy pqr
xxx pqr
yyy pqr
xxx pqr
www pqr

Using the keyword base, we can access the base class functions. Here whether pqr is virtual or not, it is treated as non virtual by the keyword base. Thus the base class pqr will always be called. The object a knows that pqr is virtual. When it goes to yyy, it sees base.abc and hence it calls the pqr of yyy. In the second case, it first goes to class vvv, here it calls the base.abc, i.e. the function pqr of class xxx, which in turn calls function pqr in class yyy.

a.cs
class zzz
{
public static void Main()
{
yyy a = new xxx();
a.pqr();
}
}
class yyy
{
public virtual void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
}
class xxx : yyy
{
public override void pqr()
{
((yyy)this).pqr();
System.Console.WriteLine(“xxx pqr”);
}
}

Output
Unhandled Exception: StackOverflowException.

No amount of casting will stop the infinite loop. Thus even though this is being cast to a yyy, it will always call pqr from xxx and not yyy. Hence you see no output

a.cs
class zzz
{
public static void Main()
{
yyy a = new www();
xxx b = new www();
a.pqr();a.xyz();
b.pqr();b.xyz();
}
}
class yyy
{
public virtual void pqr()
{
System.Console.WriteLine(“yyy pqr”);
}
public virtual void xyz()
{
System.Console.WriteLine(“yyy xyz”);
}
}
class xxx : yyy
{
private new void pqr()
{
System.Console.WriteLine(“xxx pqr”);
}
public new void xyz()
{
System.Console.WriteLine(“xxx xyz”);
}
}
class www : xxx
{
public override void pqr()
{
System.Console.WriteLine(“www pqr”);
}
public void xyz()
{
System.Console.WriteLine(“www xyz”);
}
}

Output
www pqr
yyy xyz
www pqr
xxx xyz

More virtual functions, more complications in life. Let us embark on a thousand mile journey with a single step.

When we have a statement a.pqr, C# starts at the class yyy as usual, sees virtual, then goes to class xxx. Here pqr is private and hence its scope is limited to class xxx. The modifier new is thus ignored. C# now goes to class www where the pqr overrides the pqr of class yyy and thus we see www pqr. If we remove the override modifier from function pqr in class www, as it is a new function, it will now be called from class yyy. a.xyz calls pqr from yyy due to the explanation given many times before i.e. they are all news.

b.pqr knows that pqr in class xxx is private. The scope of this pqr does not extend to class www, the derived class. As the pqr in class www overrides the pqr of class xxx, the one from class www gets called as it overrides the one from the base class yyy. If you change the override to new, then the pqr in www is a new one and has nothing to do with the one from yyy. This calls pqr from the base class yyy.

b.xyz calls it from class xxx. This has already been explained at least a  trillion times earlier.    

Abstract Classes

a.cs
public class zzz
{
public static void Main()
{
new aaa();
}
}
abstract class aaa {
}
Compiler Error
a.cs(5,1): error CS0144: Cannot create an instance of the abstract class or interface ‘aaa’

The keyword abstract can be written before a class. It is called a class modifier. An abstract class cannot be instantiated by the keyword new. We cannot create an object that looks like aaa. Thus we cannot use the class and for all practical purposes the class is useless to us.

a.cs
public class zzz
{
public static void Main()
{
new aaa();
}
}
abstract class aaa
{
public int i;
public void abc()
{
}
}

The error remains the same. Since we have used the modifier abstract in front of the class we cannot use new. Had we removed the modifier abstract, all would be fine. This program is to show that an abstract class can contain variables and functions.

a.cs
public class zzz
{
public static void Main()
{
new bbb();
}
}
abstract class aaa
{
public int i;
public void abc()
{
}
}
class bbb : aaa
{
}

We can derive a class bbb from an abstractc class aaa. Thus creating an object that looks like bbb does not give us any error. We cannot yet use aaa directly.

a.cs
public class zzz
{
public static void Main()
{
new bbb();
}
}
abstract class aaa
{
public void pqr();
public int i;
public void abc()
{
}
}
class bbb : aaa
{
}

Compiler Error
a.cs(10,13): error CS0501: ‘aaa.pqr()’ must declare a body because it is not marked abstract or extern

In a abstract class we have added a function prototype. An extern or abstract function implies that the actual definition or code is created somewhere else. A function prototype in a abstract class must also be declared abstract as per the rules of C#.

a.cs
public class zzz
{
public static void Main()
{
new bbb();
}
}
abstract class aaa
{
abstract public void pqr();
public int i;
public void abc()
{
}
}
class bbb : aaa
{
}

Compiler Error
a.cs(16,7): error CS0534: ‘bbb’ does not implement inherited abstract member ‘aaa.pqr()’

After declaring pqr abstract in aaa, we get another error. We are not allowed to create objects that look like bbb because it is derived from aaa, an abstract class which has one abstract function. We have to implement this abstract function pqr in bbb .

a.cs
public class zzz
{
public static void Main()
{
new bbb();
}
}
abstract class aaa
{
abstract public void pqr();
public int i;
public void abc()
{
}
}
class bbb : aaa
{
public void pqr()
{
}
}

Compiler Warning
a.cs(18,13): warning CS0114: ‘bbb.pqr()’ hides inherited member ‘aaa.pqr()’. To make the current method override that implementation, add the override keyword. Otherwise add the new keyword.

Compiler Error
a.cs(16,7): error CS0534: ‘bbb’ does not implement inherited abstract member ‘aaa.pqr()’

Now we are really lost. The error clearly says that both classes aaa and bbb have a similar function called pqr. Whenever a class (bbb) derives from another class (aaa) and they both have a function with the same name, an error results. The only way out is for the derived class bbb to explicitly add a keyword override to the function definition. This tells the compiler that we know that the base class has a function of the same name and we want the pqr of bbb to be called, not aaa’s . It is more of a caution exercised by the compiler so that you do not inadvertently override functions of the base class. C# has a large number of such cautions that make you think.

a.cs
public class zzz
{
public static void Main()
{
new bbb();
}
}
abstract class aaa
{
abstract public void pqr();
public int i;
public void abc()
{
}
}
class bbb : aaa
{
public override void pqr()
{
}
}

The warning vanishes after using the keyword override.

a.cs
public class zzz
{
public static void Main()
{
new bbb();
}
}
abstract class aaa
{
abstract public void pqr();
public int i;
public void abc()
{
}
}
class bbb : aaa
{
public override int pqr()
{
}
}

Compiler Error
a.cs(18,21): error CS0508: ‘bbb.pqr()’: cannot change return type when overriding inherited member ‘aaa.pqr()’

When you are overriding an abstract function from a derived class, you cannot change the parameters passed to it or the return type. If the abstract class has 5 functions, the class derived from it should also implement the same 5 functions without changing return type and/or parameters passed to it.

a.cs
public class zzz
{
public static void Main()
{
new bbb();
}
}
abstract class aaa
{
abstract public void pqr();
abstract public void pqr1();
abstract public void pqr2();
public int i;
public void abc()
{
}
}
class bbb : aaa
{
public override void pqr()
{
}
}

Compiler Error
a.cs(18,7): error CS0534: ‘bbb’ does not implement inherited abstract member ‘aaa.pqr1()’
a.cs(18,7): error CS0534: ‘bbb’ does not implement inherited abstract member ‘aaa.pqr2()’

The error goes away if we implement functions pqr1 and pqr2 in bbb.

An abstract class implies that the class is incomplete and cannot be directly used. It can only be used as a  base class for other classes to derive from. Hence we get a error if we use new on an abstract class. If we do not initialize a variable in an abstract class, it will have a value of 0 which is what the compiler kept warning us about. We can initialize i to any value we want. The variables have the same use and meaning in an abstract class like any other class. Whenever a class is incomplete i.e. we do not have the code for certain functions, we make those functions abstract and the class abstract . This enables us to compile the class without errors. Other classes can then derive from our incomplete class but they have to implement the abstract i.e. our incomplete functions. Abstract thus enables us to write code for part of the class and allows the others to complete the rest of the code.

a.cs
public class zzz
{
public static void Main()
{
}
}
class aaa
{
abstract public void pqr();
public int i = 20;
public void abc()
{
}
}

Compiler Error
a.cs(9,22): error CS0513: ‘aaa.pqr()’ is abstract but it is contained in nonabstract class ‘aaa’

If a class has even one abstract function, then the class has to be declared abstract. An abstract method cannot also use the modifiers static or virtual.

Only in the abstract class can we have one abstract function. Anyone who implements from an abstract class has to write the code for its function. By default the modifier new gets added, which makes it a new/different function.

a.cs
class zzz
{
public static void Main()
{
}
}
abstract class yyy
{
public abstract void abc();
}
class xxx : yyy
{
public override void abc()
{
base.abc();
}
}

Compiler Error
a.cs(15,1): error CS0205: Cannot call an abstract base method: ‘yyy.abc()’
Like the Sting number, C# is always watching every step you take and every move you make. Like a hawk. You cannot call the function abc from the base class as it does not carry any code along with it and has been declared abstract. Common sense prevails and C# does not allow you to call a function that has no code.

a.cs
class zzz
{
public static void Main()
{
yyy a = new www();
xxx b = new www();
a.abc();b.abc();
}
}
class yyy
{
public virtual void abc()
{
System.Console.WriteLine(“yyy abc”);
}
}
abstract class xxx : yyy
{
public abstract new void abc();
}
class www : xxx
{
public override void abc()
{
System.Console.WriteLine(“www abc”);
}
}

Output
yyy abc
www abc

a.abc() will first peek into the class yyy. Here it finds function abc tagged as virtual. How many times have we repeated the above lines? Countless times. C# will then toddle over to class xxx. Here it finds to its dismay that the function abc is abstract i.e. there is no code for abc and also that it is a new function, thus severing all links with the base class. Activity stops and all hell breaks loose and the function abc from yyy gets executed. In the case of b.abc(), as the function is new, the links to the base class are broken, we have no choice but to call the function from www as it says override. We cannot replace the modifier new with the keyword override for function abc in abstract class xxx .

Compiler Error
a.cs(21,7): error CS0534: ‘www’ does not implement inherited abstract member ‘xxx.abc()’

If we replace the override keyword with new in class www, we will get an error as there is no code for the function abc. Remember the abc of yyy has nothing to do at all with that of xxx and www.

Virtual functions run slower than non virtual functions and it is obvious that an abstract class cannot be sealed.

a.cs
public class zzz
{
public static void Main()
{
}
}
sealed abstract class aaa
{
public abstract void abc();
}

Compiler Error
a.cs(7,23): error CS0502: 'aaa' cannot be both abstract and sealed

No comments:

Post a Comment

No String Argument Constructor/Factory Method to Deserialize From String Value

  In this short article, we will cover in-depth the   JsonMappingException: no String-argument constructor/factory method to deserialize fro...