Overriding base class methods - c#

Is it possible to override a base class method in C++, like we can do in C# using the override keyword ?
Please Help
Thank You

Yes.
Just make the base method virtual.
C++ doesn't have an override keyword; any method with the same signature (including parameter types and const-ness) as a virtual base method will override it.

Only in C++0x, the next upcoming standard of the C++ language. In C++03, that is the current C++ you override implicitly, that is you don't mark the overriding method explicitly as an overriding one. But be careful, if you accidentally write another signature but the same name, the base class function will be hidden and not overriden!
struct X
{
virtual void f() {...};
};
struct Y:X
{
void f() {...} //overrides X::f
};
struct Z:X
{
void f() const {... } //hides X::f!!!
};
The only thing that can differ in the functions' declarations is that if in base class the function returns T1* ( or T1&) and in derived class T2* (or T2&) and T2 is derived from T1 then it's OK, it's still overrifing, not hiding. HTH

Yes, you can override base class methods; if you use the keyword virtual in your base class, the binding of the method will be dynamic (i.e. fully polymorphic); if you don't use the keyword virtual in your base class, the binding of the method will be static.

A lot of answers have said you make a base class function virtual, this is often done but not needed. you could just do the following...
class A{
public:
void foo();
}
class B: public A{
public:
void foo();
}
class C: public A{
public:
void foo();
}
If you had an array of A pointers such as A* basePTR[2] you can instance basePTR[0] as an instance of B then basePTR[1] as an instance of C. but if you tried to call basePTR[0]->foo() you will call A::foo()
if you defined A as
class A{
public:
virtual void foo();
}
then calling basePTR[0]->foo() will call B::foo()
Their is overhead for using this functionality as at run time a look up has to be done to see if you are calling the base functions foo() or a derived class's foo() but normally, this feature is worth the relatively minor performance hit.
You could define A as
class A{
public:
virtual void foo() =0;
}
the =0 at the end of foo() means that this function is a pure virtual function, this means that it HAS to be defined by a derived class and you can't make an instance of A. A good example of where you would use this would be in a game, you might have a base class GameToken that has an XYZ position and a pure virtual function draw and update. from this you could derive player AI dynamicObject etc... your engine could then just store one array of type GameToken* and iterate through this array calling draw() and update() for all the different types in the array

Related

Method overriding works without using virtual/override properties [duplicate]

This question already has answers here:
Difference between shadowing and overriding in C#?
(6 answers)
Closed 3 years ago.
I am a bit confused about overriding vs. hiding a method in C#. Practical uses of each would also be appreciated, as well as an explanation for when one would use each.
I am confused about overriding - why do we override? What I have learnt so far is that by overring we can provide desired implementation to a method of a derived class, without changing the signature.
If I don't override the method of the superclass and I make changes to the method in the sub class, will that make changes to the super class method ?
I am also confused about the following - what does this demonstrate?
class A
{
virtual m1()
{
console.writeline("Bye to all");
}
}
class B : A
{
override m1()
{
console.writeLine("Hi to all");
}
}
class C
{
A a = new A();
B b = new B();
a = b; (what is this)
a.m1(); // what this will print and why?
b = a; // what happens here?
}
Consider:
public class BaseClass
{
public void WriteNum()
{
Console.WriteLine(12);
}
public virtual void WriteStr()
{
Console.WriteLine("abc");
}
}
public class DerivedClass : BaseClass
{
public new void WriteNum()
{
Console.WriteLine(42);
}
public override void WriteStr()
{
Console.WriteLine("xyz");
}
}
/* ... */
BaseClass isReallyBase = new BaseClass();
BaseClass isReallyDerived = new DerivedClass();
DerivedClass isClearlyDerived = new DerivedClass();
isReallyBase.WriteNum(); // writes 12
isReallyBase.WriteStr(); // writes abc
isReallyDerived.WriteNum(); // writes 12
isReallyDerived.WriteStr(); // writes xyz
isClearlyDerived.WriteNum(); // writes 42
isClearlyDerived.writeStr(); // writes xyz
Overriding is the classic OO way in which a derived class can have more specific behaviour than a base class (in some languages you've no choice but to do so). When a virtual method is called on an object, then the most derived version of the method is called. Hence even though we are dealing with isReallyDerived as a BaseClass then functionality defined in DerivedClass is used.
Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived then there's no way of knowing that there is a different WriteNum() on DerivedClass so it isn't called. It can only be called when we are dealing with the object as a DerivedClass.
Most of the time hiding is bad. Generally, either you should have a method as virtual if its likely to be changed in a derived class, and override it in the derived class. There are however two things it is useful for:
Forward compatibility. If DerivedClass had a DoStuff() method, and then later on BaseClass was changed to add a DoStuff() method, (remember that they may be written by different people and exist in different assemblies) then a ban on member hiding would have suddenly made DerivedClass buggy without it changing. Also, if the new DoStuff() on BaseClass was virtual, then automatically making that on DerivedClass an override of it could lead to the pre-existing method being called when it shouldn't. Hence it's good that hiding is the default (we use new to make it clear we definitely want to hide, but leaving it out hides and emits a warning on compilation).
Poor-man's covariance. Consider a Clone() method on BaseClass that returns a new BaseClass that's a copy of that created. In the override on DerivedClass this will create a DerivedClass but return it as a BaseClass, which isn't as useful. What we could do is to have a virtual protected CreateClone() that is overridden. In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide this with a new Clone() that returns a DerivedClass. Calling Clone() on BaseClass will always return a BaseClass reference, which will be a BaseClass value or a DerivedClass value as appropriate. Calling Clone() on DerivedClass will return a DerivedClass value, which is what we'd want in that context. There are other variants of this principle, however it should be noted that they are all pretty rare.
An important thing to note with the second case, is that we've used hiding precisely to remove surprises to the calling code, as the person using DerivedClass might reasonably expect its Clone() to return a DerivedClass. The results of any of the ways it could be called are kept consistent with each other. Most cases of hiding risk introducing surprises, which is why they are generally frowned upon. This one is justified precisely because it solves the very problem that hiding often introduces.
In all, hiding is sometimes necessary, infrequently useful, but generally bad, so be very wary of it.
Overriding is when you provide a new override implementation of a method in a descendant class when that method is defined in the base class as virtual.
Hiding is when you provide a new implementation of a method in a descendant class when that method is not defined in the base class as virtual, or when your new implementation does not specify override.
Hiding is very often bad; you should generally try not to do it if you can avoid it at all. Hiding can cause unexpected things to happen, because Hidden methods are only used when called on a variable of the actual type you defined, not if using a base class reference... on the other hand, Virtual methods which are overridden will end up with the proper method version being called, even when called using the base class reference on a child class.
For instance, consider these classes:
public class BaseClass
{
public virtual void Method1() //Virtual method
{
Console.WriteLine("Running BaseClass Method1");
}
public void Method2() //Not a virtual method
{
Console.WriteLine("Running BaseClass Method2");
}
}
public class InheritedClass : BaseClass
{
public override void Method1() //Overriding the base virtual method.
{
Console.WriteLine("Running InheritedClass Method1");
}
public new void Method2() //Can't override the base method; must 'new' it.
{
Console.WriteLine("Running InheritedClass Method2");
}
}
Let's call it like this, with an instance of InheritedClass, in a matching reference:
InheritedClass inherited = new InheritedClass();
inherited.Method1();
inherited.Method2();
This returns what you should expect; both methods say they are running the InheritedClass versions.
Running InheritedClass Method1
Running InheritedClass Method2
This code creates an instance of the same, InheritedClass, but stores it in a BaseClass reference:
BaseClass baseRef = new InheritedClass();
baseRef.Method1();
baseRef.Method2();
Normally, under OOP principles, you should expect the same output as the above example. But you don't get the same output:
Running InheritedClass Method1
Running BaseClass Method2
When you wrote the InheritedClass code, you may have wanted all calls to Method2() to run the code you wrote in it. Normally, this would be how it works - assuming you are working with a virtual method that you have overridden. But because you are using a new/hidden method, it calls the version on the reference you are using, instead.
If that's the behavior you truly want, then; there you go. But I would strongly suggest that if that's what you want, there may be a larger architectural issue with the code.
Method Overriding is simpley override a default implementation of a base class method in the derived class.
Method Hiding : You can make use of 'new' keyword before a virtual method in a derived class
as
class Foo
{
public virtual void foo1()
{
}
}
class Bar:Foo
{
public new virtual void foo1()
{
}
}
now if you make another class Bar1 which is derived from Bar , you can override foo1 which is defind in Bar.

Inheritance in C# - override and virtual

I'm new to C# override and virtual. In the following example I want to call Callee method in B class from Caller method in A class. B inherits A. Any thoughts?
namespace Blah
{
public class Program
{
public static void Main(string[] args)
{
A a = new A();
a.Caller();
}
}
class A
{
public void Caller()
{
Console.WriteLine("In Caller");
Callee(); // How to make this call B:Callee() and make it print "in B"
}
public virtual void Callee()
{
Console.Write("In A");
}
}
class B : A
{
public override void Callee()
{
Console.Write("In B");
}
}
}
If you want to call the Callee method inside class B, you have first to create an instance of this class and then call this method:
var b = new B();
B.Callee();
If that is you are looking for (despite it does not make sense from a practical prespective), you should place the above two lines inside the method Caller in class A.
Usually we define a base class and if we think that a method in the class we define can be re-implemented from classes that would be derived from our class, we mark the method as virtual. When we derive a class from our base class and we do not override the virtual method, then the method that has been defined in the base class is called. Whereas when we have overriden a virtual method defined in a base class, the method in the derived class is called.
In your example you have the baseclass A with a subclass B that overrides a method in A. This means that you create an alternative A, that can interact as an A but might have different behavior.
However, this does not mean that every instance of A suddenly starts to use this definition. In your example you create a hard instance of A, but as the overriding method is in B it will never be called.
Instead you should create an instance of B, which you can cast to an A. Allowing your code to treat it as an A object, even though its B.
In your example, the only thing you'll need to do is create an instance of B (fiddle):
A a = new B();
a.Caller();
// Prints:
// In Caller
// In B
The way this works is more or less the same as Java inheritance, only in C# you need to mark methods as virtual in order to override them.
However, if your intention was to change definition of Callee in A without having to create a B (so new A().Caller()would print out "In B"), you should rethink whatever you are trying to do. It is something completely different from virtual methods and in most situations something you should try to avoid.

Overriding vs method hiding [duplicate]

This question already has answers here:
Difference between shadowing and overriding in C#?
(7 answers)
Closed 3 years ago.
I am a bit confused about overriding vs. hiding a method in C#. Practical uses of each would also be appreciated, as well as an explanation for when one would use each.
I am confused about overriding - why do we override? What I have learnt so far is that by overring we can provide desired implementation to a method of a derived class, without changing the signature.
If I don't override the method of the superclass and I make changes to the method in the sub class, will that make changes to the super class method ?
I am also confused about the following - what does this demonstrate?
class A
{
virtual m1()
{
console.writeline("Bye to all");
}
}
class B : A
{
override m1()
{
console.writeLine("Hi to all");
}
}
class C
{
A a = new A();
B b = new B();
a = b; (what is this)
a.m1(); // what this will print and why?
b = a; // what happens here?
}
Consider:
public class BaseClass
{
public void WriteNum()
{
Console.WriteLine(12);
}
public virtual void WriteStr()
{
Console.WriteLine("abc");
}
}
public class DerivedClass : BaseClass
{
public new void WriteNum()
{
Console.WriteLine(42);
}
public override void WriteStr()
{
Console.WriteLine("xyz");
}
}
/* ... */
BaseClass isReallyBase = new BaseClass();
BaseClass isReallyDerived = new DerivedClass();
DerivedClass isClearlyDerived = new DerivedClass();
isReallyBase.WriteNum(); // writes 12
isReallyBase.WriteStr(); // writes abc
isReallyDerived.WriteNum(); // writes 12
isReallyDerived.WriteStr(); // writes xyz
isClearlyDerived.WriteNum(); // writes 42
isClearlyDerived.writeStr(); // writes xyz
Overriding is the classic OO way in which a derived class can have more specific behaviour than a base class (in some languages you've no choice but to do so). When a virtual method is called on an object, then the most derived version of the method is called. Hence even though we are dealing with isReallyDerived as a BaseClass then functionality defined in DerivedClass is used.
Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived then there's no way of knowing that there is a different WriteNum() on DerivedClass so it isn't called. It can only be called when we are dealing with the object as a DerivedClass.
Most of the time hiding is bad. Generally, either you should have a method as virtual if its likely to be changed in a derived class, and override it in the derived class. There are however two things it is useful for:
Forward compatibility. If DerivedClass had a DoStuff() method, and then later on BaseClass was changed to add a DoStuff() method, (remember that they may be written by different people and exist in different assemblies) then a ban on member hiding would have suddenly made DerivedClass buggy without it changing. Also, if the new DoStuff() on BaseClass was virtual, then automatically making that on DerivedClass an override of it could lead to the pre-existing method being called when it shouldn't. Hence it's good that hiding is the default (we use new to make it clear we definitely want to hide, but leaving it out hides and emits a warning on compilation).
Poor-man's covariance. Consider a Clone() method on BaseClass that returns a new BaseClass that's a copy of that created. In the override on DerivedClass this will create a DerivedClass but return it as a BaseClass, which isn't as useful. What we could do is to have a virtual protected CreateClone() that is overridden. In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide this with a new Clone() that returns a DerivedClass. Calling Clone() on BaseClass will always return a BaseClass reference, which will be a BaseClass value or a DerivedClass value as appropriate. Calling Clone() on DerivedClass will return a DerivedClass value, which is what we'd want in that context. There are other variants of this principle, however it should be noted that they are all pretty rare.
An important thing to note with the second case, is that we've used hiding precisely to remove surprises to the calling code, as the person using DerivedClass might reasonably expect its Clone() to return a DerivedClass. The results of any of the ways it could be called are kept consistent with each other. Most cases of hiding risk introducing surprises, which is why they are generally frowned upon. This one is justified precisely because it solves the very problem that hiding often introduces.
In all, hiding is sometimes necessary, infrequently useful, but generally bad, so be very wary of it.
Overriding is when you provide a new override implementation of a method in a descendant class when that method is defined in the base class as virtual.
Hiding is when you provide a new implementation of a method in a descendant class when that method is not defined in the base class as virtual, or when your new implementation does not specify override.
Hiding is very often bad; you should generally try not to do it if you can avoid it at all. Hiding can cause unexpected things to happen, because Hidden methods are only used when called on a variable of the actual type you defined, not if using a base class reference... on the other hand, Virtual methods which are overridden will end up with the proper method version being called, even when called using the base class reference on a child class.
For instance, consider these classes:
public class BaseClass
{
public virtual void Method1() //Virtual method
{
Console.WriteLine("Running BaseClass Method1");
}
public void Method2() //Not a virtual method
{
Console.WriteLine("Running BaseClass Method2");
}
}
public class InheritedClass : BaseClass
{
public override void Method1() //Overriding the base virtual method.
{
Console.WriteLine("Running InheritedClass Method1");
}
public new void Method2() //Can't override the base method; must 'new' it.
{
Console.WriteLine("Running InheritedClass Method2");
}
}
Let's call it like this, with an instance of InheritedClass, in a matching reference:
InheritedClass inherited = new InheritedClass();
inherited.Method1();
inherited.Method2();
This returns what you should expect; both methods say they are running the InheritedClass versions.
Running InheritedClass Method1
Running InheritedClass Method2
This code creates an instance of the same, InheritedClass, but stores it in a BaseClass reference:
BaseClass baseRef = new InheritedClass();
baseRef.Method1();
baseRef.Method2();
Normally, under OOP principles, you should expect the same output as the above example. But you don't get the same output:
Running InheritedClass Method1
Running BaseClass Method2
When you wrote the InheritedClass code, you may have wanted all calls to Method2() to run the code you wrote in it. Normally, this would be how it works - assuming you are working with a virtual method that you have overridden. But because you are using a new/hidden method, it calls the version on the reference you are using, instead.
If that's the behavior you truly want, then; there you go. But I would strongly suggest that if that's what you want, there may be a larger architectural issue with the code.
Method Overriding is simpley override a default implementation of a base class method in the derived class.
Method Hiding : You can make use of 'new' keyword before a virtual method in a derived class
as
class Foo
{
public virtual void foo1()
{
}
}
class Bar:Foo
{
public new virtual void foo1()
{
}
}
now if you make another class Bar1 which is derived from Bar , you can override foo1 which is defind in Bar.

What are the rules for multiple casts in C#?

I have this code snippet and I would like to know why is the output as written in comment below:
interface I {
void m1();
void m2();
void m3();
}
class A : I {
public void m1() { Console.WriteLine("A.m1()"); }
public virtual void m2() { Console.WriteLine("A.m2()"); }
public virtual void m3() { Console.WriteLine("A.m3()"); }
}
class C : A, I {
public new void m1() { Console.WriteLine("C.m1()"); }
public override void m2() { Console.WriteLine("C.m2()"); }
public new void m3() { Console.WriteLine("C.m3()"); }
}
------
C c = new C();
((I) ((A) c)).m1(); //"C.m1()"
((I) ((A) c)).m2(); //"C.m2()"
((I) ((A) c)).m3(); //"C.m3()"
One original guess of what the output shoud be was:
A.m1();
C.m2();
A.m3();
Change class C to this:
class C : A {
public new void m1() { Console.WriteLine("C.m1()"); }
public override void m2() { Console.WriteLine("C.m2()"); }
public new void m3() { Console.WriteLine("C.m3()"); }
}
Explanation from Jeffrey Richter:
The C# compiler requires that a method that implements an interface be marked as public. The
CLR requires that interface methods be marked as virtual. If you do not explicitly mark
the method as virtual in your source code, the compiler marks the method as virtual and
sealed; this prevents a derived class from overriding the interface method. If you explicitly
mark the method as virtual, the compiler marks the method as virtual (and leaves it
unsealed); this allows a derived class to override the interface method.
If an interface method is sealed, a derived class cannot override the method. However, a
derived class can re-inherit the same interface and can provide its own implementation for the
interface's methods. When calling an interface's method on an object, the implementation
associated with the object's type is called.
Because C class also implements I interface, than when we calling interface methods on C object, we will call implementation accosicated with the object's type is called (i.e class C methods) but not methods derived from C's base class (not A class methods).
All these type-casts are redundant and I'm pretty sure they get optimized away by the compiler.
Here's what I mean. (A) c is redundant since C is A, so we're left just with (I)c, which is redundant as well, since C implements I. Thus, we have just an instance of C class, for which the compiler applies normal resolution rules.
EDIT
Turns out, I was completely wrong. This document describes what happens:
Interface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. The implementation of a particular interface member I.M, where I is the interface in which the member M is declared, is determined by examining each class or struct S, starting with C and repeating for each successive base class of C, until a match is located:
If S contains a declaration of an explicit interface member implementation that matches I and M, then this member is the implementation of I.M.
Otherwise, if S contains a declaration of a non-static public member that matches M, then this member is the implementation of I.M.
I think you're misunderstanding what the cast operator does for reference conversions.
Suppose you have a reference to an instance of C on the stack. That's a certain set of bits. You cast the thing on the stack to A. Do the bits change? No. Nothing changes. It's the same reference to the same object. Now you cast it to I. Do the bits change this time? No. Same bits. Same reference. Same object.
An implicit reference conversion via a cast like this simply tells the compiler to use different rules when figuring out at compile time what method to call.
So the casts to "A" are completely irrelevant and ignored by the compiler. All the compiler knows or cares about is that you have an expression of type I, and you're calling a method on it. The compiler generates a call that says "at runtime, look at the object reference that is on the stack and invoke whatever is in the "I.m1" slot of the object.
The way to figure this stuff out is to think about the slots. Every interface and class defines a certain number of "slots". At runtime, every instance of a class has those slots filled in with references to methods. The compiler generates code that says "invoke whatever is in slot 3 of that object", and that's what the runtime does -- looks in the slot, calls what's there.
In your example there are all kinds of slots. The interface requires three slots, the base class provides more, and the "new" methods of the derived class provide two more. When an instance of the derived class is constructed, all of those slots are filled in, and, understandably, the slots associated with I are filled in with the matching members of the derived class.
Does that make sense?
Casting does not matter as C already contains A and I.
for ((I) ((A) c)).m1() and ((I) ((A) c)).m3(): - The "new" keyword hides the A.m1 implementation (in fact without the new keyword you will get a warning). So C.M1 and C.M3 are chosen.
For ((I) ((A) c)).m2():
- The override takes care that the C.M2 implementation is chosen.

.net abstract override quirk

Lets say i have the following c# classes:
abstract class a
{
protected abstract void SomeMethod();
}
abstract class b : a
{
protected abstract override void SomeMethod();
}
class c : b
{
protected override void SomeMethod()
{
}
}
Is there actually any point in overriding the method in b when it could just as easily be writen as:
abstract class b : a
{
}
What would be the "prefered" way of writting b? And if there is no point overriding an abstract method or property why is it allowed?
One reason you might want to allow it: it shows intent. It explains that yes, you know this method is abstract in the base class. I know that, and I still want it to be abstract here.
That way, if the base class removes the method, your abstract class will fail to compile, rather than only the concrete class (which may not even be in your code).
That said, it's not a particularly important reason... I'd normally leave it out.
Additional to the already said:
override could also be used to declare attributes that are not defined in the base class. If still not having an implementation, it will be an abstract override.
abstract class b : a
{
[SomeAttribute]
protected abstract override void SomeMethod();
}
I normally don't re-declare abstract methods when I don't actually intend to supply an implementation - for several reasons:
I doesn't change the semantics of your code.
It adds one more thing to refactor if the base class changes.
It leads to inconsistency of new abstract methods are added to the base class and you don't add them to intermediate classes.
It's quite painful to do so in a class hierarchy with more than a few levels.
It clutters your code with declaration that add little value.
Have a look at this blog. Sometimes combining both is useful:
"Good language design usually results
in a few well defined simple
primitives that can be combined
together in intuitive and intelligent
ways. In contrast, poor language
design usually results in many bloated
constructs that don't play well
together.
The "abstract" and "override" keywords
in C# are a great example of this.
They both have simple definitions, but
they can be combined to express a more
complex concept too.
Let's say you have a class hierarchy:
C derives from B, and B derives from
A. A has an abstract method Foo() and
Goo(). Here are 2 scenarios where
"abstract override" would come up. 1)
Let's say B only wants to implement
Goo(), and let C implement Foo(). B
can mark Foo() as "abstract override".
This clearly advertises that B
recognizes Foo() is declared in the
base class A, yet it expects another
derived class to implement it.
2) Let's say B wants to force a C to
reimplement Foo() instead of using A's
definition of Foo(). B marks Foo() as
both override (which means B
recognizes Foo() is declared in the
base class) and abstract (which means
B forces derived class C to provide an
implementation; regardless that A
already provided an implementation).
This came up in one of my recent blog
entries here. In that example,
A=TextReader, Foo=ReadLine, B= a
helper class, C=some class that wants
to implement ReadLine() instead of
Read(). Now TextReader already has a
default implementation of ReadLine()
based on Read(), but we want to go the
other way around. We want an
implementation of Read() based off a
derived classes implementation of
ReadLine(). Thus B provides an
implementation of Read() that consumes
ReadLine(), and then marks ReadLine()
as "abstract override" to force C to
redefine ReadLine() instead of picking
up the one from TextReader.
In summary, "abstract override" is
cool not because it's yet one more
language feature to express some
complex corner case; it's cool because
it's not one more language feature.
The neat part is that you don't really
need to think about any of this. You
just use the individual basic concepts
naturally, and the complicated stuff
comes together automatically."
This is my example code for scenario 1:
public abstract class A
{
public abstract void Foo();
public abstract void Goo();
}
public abstract class B : A
{
public abstract override void Foo();
public override void Goo()
{
Console.WriteLine("Only wanted to implement goo");
}
}
public class C : B
{
public override void Foo()
{
Console.WriteLine("Only wanted to implement foo");
}
}
And my sample code for scenario 2:
public abstract class A
{
public virtual void Foo()
{
Console.WriteLine("A's Foo");
}
public abstract void Goo();
}
public abstract class B : A
{
public abstract override void Foo();
public override void Goo()
{
Console.WriteLine("Only wanted to implement goo");
}
}
public class C : B
{
public override void Foo()
{
Console.WriteLine("Forced to implement foo");
}
}
In your question the code is not that useful, but that doesn't mean that abstract and override combined is not useful.
You should not need to override SomeMethod() in b. An abstract class declares that there can be undefined/abstract methods in it. When you extend one abstract class with another, it implicitly inherits any abstract methods from the parent.

Categories

Resources