Let's say this abstract class:
abstract public class MyBase {
abstract public int GetValue();
<some concrete methods here>
}
Now I want to inherit that as another abstract class, implementing GetValue() but adding new abstract methods:
abstract public class MyBase2 : MyBase {
abstract public int GetValue2();
public override int GetValue() {
// some code here
return something;
}
}
Why do I have to specify override for MyBase2.GetValue()? Isn't MyBase.GetValue() already marked as abstract and thus will naturally be overridden by anything inheriting from MyBase?
Why do I have to specify override for MyBase2.GetValue()?
This is a paradigm which has been adopted by c++ as well.
The idea is: by explitly having the need to use the keywords override for virtual and abstract, you will ensure that you're not making a typo when doing the override. Because if you would mot see such a typo, the behaviour, escpecially on virtual would change significantly.
Having said that; I still find it strange that the new keyword for added methods is still optional and only emits a warning when omitted.
Since your MyBase2 class is also marked as abstract you should tell the compiler that GetValue() is implemented in this class instead of other class(es) higher in hierarchy (implementing MyBase2)
Related
I have a user control that will handle images on a form. But depending on what the source is (web cam or ID scan or other video source) the user control is different.
But they share some common features so I want to create a base class.
My other controls all have some interface items that I need. I would like to declare the interface at the base level though and just implement at the class level. But virtual and override seems to be the closest way to get what I want. Is there any to do it, force the new class to implement the interface assigned at the base class? Looking around it look like making the class abstract (which I don't fully understand) might be a start. If it was just methods that might be alright, but I am also using properties. In that area I have hit a dead end in my searches for answers. Here is what I have so far. Am I on the right track? I just have not worked with abstract classes at all and only limited exposure to interfaces. From the research I think I have the method correct just not sure about the property.
public interface RequiredAnswer
{
void LabelRequiredFieldEmpty();
bool AnswerRequired{ get;}
}
public abstract partial class ExtImage : UserControl, RequiredAnswer
{
public virtual bool AnswerRequired
{
get
{
throw new NotImplementedException ("Answer Required");
}
}
public abstract void LabelRequiredFieldEmpty ()
{
//checkBox_AgreementAcceptedText.ForeColor = Color.Red;
}
So I would have a class
public partial class ExtImageWebCam : ExtImage
{
public override bool AnswerRequired
{
get
{
return valueFromThisClassThatMeansAnAnswerIsRequired;
}
}
public override void LabelRequiredFieldEmpty ()
{
// do something
}
}
When you declare a method abstract, you are basically saying that a child class must supply the definition of the method. You can make properties abstract. This sounds like it is exactly what you need.
Here is the MSDN article for further reference.
From MSDN
Properties
Abstract properties behave like abstract methods, except for the differences in declaration and invocation syntax.
It is an error to use the abstract modifier on a static property.
An abstract inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.
Continuing later
In this example, the class DerivedClass is derived from an abstract class BaseClass. The abstract class contains an abstract method, AbstractMethod, and two abstract properties, X and Y.
abstract class BaseClass // Abstract class
{
protected int _x = 100;
protected int _y = 150;
public abstract void AbstractMethod(); // Abstract method
public abstract int X { get; }
public abstract int Y { get; }
}
Abstract base class with an Interface
An abstract class must provide implementation for all interface members.
An abstract class that implements an interface might map the interface methods onto abstract methods. For example:
interface I
{
void M();
}
abstract class C : I
{
public abstract void M();
}
First of all, interfaces should start with an I by convention, so your interface would be IRequiredAnswer.
Second, if you want to force the inherited classes to implement their own methods rather than inheriting them, just make them abstract in the base class:
public abstract class ExtImage : UserControl, IRequiredAnswer
{
public abstract bool AnswerRequired { get; }
public abstract void LabelRequiredFieldEmpty ();
}
Your child classes would then have to implement the method and property.
You're on the right track. Here's a simple example of what you could do. Making the Bar() method abstract forces the inheritors to implement it.
public interface IFoo{
void Bar();
}
public abstract class BaseFoo : IFoo
{
public abstract void Bar();
public void Implemented(){
Debug.WriteLine("this is a shared implementation");
}
}
public class KungFoo : BaseFoo{
public override void Bar()
{
}
}
You are on the right track for the creation of an interface and then defining an abstract class for your purpose.
Standard naming conventions for an interface has been broken however, interfaces are usually prefixed with an I to help identify them
public interface IRequiresAnswer
{
void LabelRequiredFieldEmpty();
bool AnswerRequired { get; }
}
I would also suggest changing the AnswerRequired property to a function as your concrete class says "do somthing to find result". Properties are usually meant to be quick, so performing any calculation within a property is masking that real work takes place when you call the property. With a function it is more apparent to callers that the result will not be achieved immediately.
I'm getting a compilation error on following code:
public abstract class DbHandler<T>
{
public abstract bool Save(T obj);
...
}
and its implementing class:
public class SpaghettiTableDb : DbHandler<SpaghettiTable>
{
public bool Save(SpaghettiTable obj)
{
return false;
}
...
}
The error is :
'SpaghettiTableDb' does not implement inherited abstract member 'SeatPicker.DbHandler<SeatPicker.SpaghettiTable>.Save(SeatPicker.SpaghettiTable)'
But I think it does, so I'm not sure why I'm receiving this error.
(SpaghettiTable is just a class with some properties, nothing more)
Any help?
You need to use the override keyword. Otherwise you're not implementing the abstract base class and just creating a "new" separate method on the subclass.
public override bool Save(SpaghettiTable obj)
{
return false;
}
Think of abstract methods just like virtual methods that you override. The only difference is that you force subclasses to provide an implementation of that method whereas virtual methods provide their own implementation that subclasses can optionally override with their own implementation.
EDIT: Additionally, if you want to make your life easier in Visual Studio, you can right-click (or ctrl+.) on the inheritance declaration and choose "implement abstract class" (or something like that, I don't have VS with me right now) which will automatically create all the overridden methods for you.
public class SpaghettiTableDb : DbHandler<SpaghettiTable> //right-click on "DbHandler"
Alternatively, in the empty code space within your class, you can start typing "override", then the IntelliSense will list all overridable members from the base class and when you pick one it will automatically write a default implementation for you.
EDIT:
Just to extend on what you have in your code, without the override keyword, you are creating a new method that belongs to your subclass and not overriding the base class. When you call that method but from the context of using the base class, it won't call your subclass implementation since it doesn't override the base method.
Consider the following classes. (I'm using virtual instead of abstract just so it compiles and have it simpler)
public class BaseClass
{
public virtual void Print()
{
Console.WriteLine("base print");
}
public virtual void AnotherPrint()
{
Console.WriteLine("base another print");
}
}
public class SubClass : BaseClass
{
public override void Print()
{
Console.WriteLine("sub print");
}
public void AnotherPrint()
{
Console.WriteLine("sub another print");
}
}
Note that SubClass.AnotherPrint does not override BaseClass.AnotherPrint.
And when you use code like:
SubClass mySub = new SubClass();
mySub.Print(); //sub print
mySub.AnotherPrint(); //sub another print
BaseClass myBase = mySub;
myBase.Print(); //sub print
myBase.AnotherPrint(); //base another print
Note that through the code, mySub and myBase both point to the same object, but one is typed as SubClass and the other as BaseClass. When the runtime calls myBase.Print(), it can easily check the inheritance of the classes and see that SubClass has overridden the Print method and calls the SubClass implementation. However, since SubClass.AnotherPrint wasn't explicitly marked with override, the runtime/compiler considers that to be a completely different method with no link to the BaseClass.AnotherPrint method. Thus the runtime sticks with the base class implementation. When your instance is typed as the SubClass though, the compiler does see that you're pointing to that new method and essentially not to the base implementation.
You need to use the override keyword when implementing abstract methods or overriding virtual methods.
public override bool Save(SpaghettiTable obj)
{
return false;
}
I have two two types of base class;
public abstract class Base
{
public abstract object Work();
}
public abstract class AuthenticatedBase : Base
{
public abstract object Work(T request);
}
The authenticated class does some extra work to check a login beforehand. Then I have different classes extending from both base classes;
public class A : Base
{
public override object Work()
{
// Work here
}
}
public class B : AuthenticatedBase
{
public override object Work(T request)
{
// Work here
}
}
Basically, when I create a new class B that derives from AuthenticatedBase, Visual Studio says I need to implement Work() from the Base class even though I have an alternate implementation in AuthenticatedBase that I am overriding, admittedly with different parameters. What should I be doing so that I don't have to implement the Work() method from the base class in inherited classes?
Implement the parameterless Work method in your AuthenticatedBase and use the "sealed" keyword to stop it from showing on inheritors of AuthenticatedBase.
You have to implement it, there is no way around it. This is the case where multiple inheritance would come in handy.
You could use composition so that B has a reference to an A. Then B.Work() can call A.Work().
Alternatively, implement B.Work() so that it calls B.Work(T). Or even have Base.Work() be a virtual method with the base implementation from A.
In the following example, the class Derived implements the abstract method method from class Main. But I can't think of a reason to fill in the method body in the abstract Derived class' implementation. Surely I should only implement abstract methods within real classes.
So how can I avoid doing it? What else can I do?
abstract class Main
{
public abstract void method();
}
abstract class Derived : Main
{
public override void method()
{
}
}
class RealClass : Derived
{
}
Usually if someone has specified that an abstract class has an abstract method, it's either because that class depends on that method for some of what it does, or it's because it's part of an expected API that it wouldn't make sense for the parent class to implement at this time. In either case, there must be an implementation once you get to a non-abstract implementation of the class.
Note also that if you are implementing an interface, you are required to state how that interface will be implemented, even if you just call the member abstract and pass the responsibility onto the subclass
public interface IPet {string GetNoise(); int CountLegs(); void Walk();}
public abstract class Pet : IPet
{
public string Name {get; set;}
public abstract string GetNoise(); // These must be here
public abstract int CountLegs();
public abstract void Walk();
}
When it comes to implementing the sub-class, you have a few choices depending on the circumstances. If your implementation is itself an abstract class, you shouldn't need to implement the abstract method.
public abstract class Quadruped : Pet
{
public override int CountLegs () { return 4; }
}
If your implementation is non-abstract, but the standard reason for the method in question really doesn't apply in your circumstance, you can do a no-op method (in the case of void methods), or return some dummy value, or even throw a NotImplementedException to indicate that the method should never have been called in the first place.
public class Fish : Pet
{
public override string GetNoise() {return "";} // dummy value: fish don't make noise
public override int CountLegs() {return 0;}
public override void Walk() {} // No-op
// public override void Walk() { throw new NotImplementedException("Fish can't walk"); }
}
Does that answer your question?
If there's no implementation of method in Derived then you can just make Derived abstract as well:
abstract class Derived : Main
{
}
class RealClass : Derived
{
public override void method() { ... }
}
EDIT: To clarify the comments - if there is no meaningful implementation of an abstract method in a subclass, then one does not need to be provided. This will however require that the derived class is itself abstract, and an implementation must be provided somewhere in the chain of descendant classes to some concrete subclass. I am not saying you should leave the implementation of method empty, as it is in the question, but rather you remove the override in Derived and mark the class abstract. This forces RealClass to provide an implementation (or itself be marked abstract).
All non-abstract descendant classes must provide concrete implementations of abstract methods. If you don't provide an implementation, then it's impossible to call that method.
If some concrete classes don't have an obvious proper implementation of a abstract method then your object design is incorrect. Maybe you should have an abstract class with some abstract methods (but not all). That class could have an both an abstract descendant and some concrete descendants.
In MSDN, it is mentioned,
http://msdn.microsoft.com/en-us/library/9fkccyh4(VS.80).aspx
I am confused what does this item mean "A virtual inherited property can be overridden in a derived class by including a property declaration that uses the override modifier."?
(this is the 2nd differences between virtual and abstract)
thanks in advance,
George
The only difference between virtual and abstract, is that an abstract method or propery has no implementation in the class where it has been defined (the abstract class), and that it must be overriden in a subclass; whereas a virtual method or property has an implementation in the class where it has been defined, and so it is not mandatory to override it in a subclass.
public abstract AbstractClass
{
// This class cannot be instantiated, since it is
// abstract, and the class is abstract because
// it has an abstract member
public abstract MyProperty {get; set; }
}
In a class where you derive from AbstractClass (the above AbstractClass is just for explanation purposes; since it has no methods / properies that have an implementation, you could create an interface instead of an abstract class), you will have to provide an implementation of MyProperty. Otherwise, it won't compile.
You do this by 'overriding' the MyProperty, you don't want to introduce a new member, but just provide an implementation for a property that has been defined previously.
public class ConcreteClass : AbstractClass
{
public override MyProperty {
get
{
return _someValue;
}
set
{
if( _someValue != value ) _someValue = value;
}
}
I can understand the confusion. I have been there before, so I'll share how I keep the basic differences straight...
virtual vs. abstract:
If a class method (or property) is
marked virtual, then it may be
overridden using the override
keyword, if you choose to inherit
(aka derive) from that class. The virtual keyword is intended to evoke the idea that the method may or may not be the actual method called. Therefore, I always think of virtual members as default implementations, meaning that it represents functionality that can be generalized, such as an Eat() method on a Human class, which might involve eating with one's hands. However, a ChineseHuman class might override the default implementation of Eat(), in order to allow for an implementation that uses chop sticks instead. Finally, because virtual methods and properties are default implementations, the class that defines that member must provide a complete implementation of the method or property. All Human objects must know how to Eat(). An object-oriented way of thinking might declare that virtual members represent instincts. To Eat() is an instinct of a Human class object. A ChineseHuman may learn to Eat() with chop sticks.
If a class method (or property) is
marked abstract, then it must
be overridden using the override
keyword, if you choose to inherit
from that class.The abstract keyword is intended to evoke the idea that the class only supports the capability represented by the member, and that there is not any common logic that can be generalized for that feature. In other words, abstract members are only conceptual, and therefore they lack an implementation. It is a little confusing that C# asks us to override abstract members when we implement an inheritance relationship, but in this case it really means that we are overriding the empty concept with a concrete implementation. An example of an abstract member of a Human class might be Speak(). There would not be a common way of speaking for all Human objects, nor is it instinctual, because it requires language to express. Note: Some might argue that Speak() belongs on an interface instead.An object-oriented way of thinking might declare that abstract members represent behavior (methods) to be learned and knowledge or beliefs (properties) to be acquired. To Speak() is a learned behavior of a Human class object. A ChineseHuman may learn to Speak() differently than an EnglishHuman and neither knows how to Speak() just because they are both Human.
Nuances:
virtual methods do NOT need to be overridden.
There is no such thing as a virtual class.
abstract members can only appear on abstract classes. In the above examples, having an abstract method on the Human class implies that Human is an abstract class, and that, therefore, a Human cannot be instantiated using the phrase var baby = new Human();. Instead, the BabyHuman class should inherit from Human, and it should be instantiated as var baby = new BabyHuman();. Because a BabyHuman() is a Human and EnglishHuman and ChineseHuman both also inherit from Human, EnglishHuman could inherit from BabyHuman instead of Human. Being Human is abstract because we are all something more than simply Human.
abstract members cannot be hidden, only their override implementations may be (further up the inheritance chain). For example, BabyHuman must implement the abstract Speak() method as an override. If EnglishHuman inherits from BabyHuman, it may then hide the BabyHuman implementation of Speak() with its own implementation by using the new keyword (see "Method Hiding in C#" reference below).
abstract classes can have virtual members. That's a main distinction between an interface and an abstract class. In that sense, an abstract class can define both a contract and a template of the class' behavior, whereas an interface only defines a contract.
Code Reference:
Abstract Class versus Interface
By Rahman Mahmoodi
http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx
Method Hiding in C#
By Chetan Kudalkar
http://www.codeproject.com/KB/cs/cs_methodhiding.aspx
Can you explain what's confusing about it? Properties can be overridden like any other method.
public class Base {
public virtual int Prop1 { get { ... } set { ... } }
}
public class Derived : Base {
public override int Prop1 { get { ... } set { ... } }
If you declare a method virtual in your base class you can override it in your derived class.
Example
class MyBaseClass
{
public virtual void MyOverridableMethod()
{
...
}
}
class MyDerivedClass : MyBaseClass
{
public override void MyOverridableMethod()
{
...
}
}
Notice the override modifier in MyDerivedClass.
Okay, let's say you have a base class, and that that base class is, itself, derived from another class.
public class Bar : Foo
{
virtual public int SomeProperty { get; set; }
}
What the virtual keyword means is that in a class derived from Bar, you can override SomeProperty to change its behavior:
public class Baz : Bar
{
private int thisInt;
override public int SomeProperty
{
get { return thisInt; }
set
{
if(value < 0)
{
throw new ArgumentException("Value must be greater than or equal to zero.");
}
thisInt = 0;
}
}
}
Clarification: When an object of type Baz is used, its version of SomeProperty is invoked, unless the type is cast to Bar. If you define Baz's SomeProperty as virtual, classes derived from Baz can also override it (in fact, that may be required--can't recall right off the top of my head).
Further Clarification: An abstract method has no implementation; when you add one to your class, you must also mark the class as abstract, and you cannot instantiate new instances of it, like this:
MyAbstractType m = new MyAbstractType();
Virtual members, on the other hand, can have an implementation (like SomeProperty, above), so you don't have to mark the class abstract, and you can instantiate them.