Why wouldn't I choose abstract? What are the limitations to declaring a class member virtual? Can only methods be declared virtual?
An abstract method or property (both can be virtual or abstract) can only be declared in an abstract class and cannot have a body, i.e. you can't implement it in your abstract class.
A virtual method or property must have a body, i.e. you must provide an implementation (even if the body is empty).
If someone want to use your abstract class, he will have to implement a class that inherits from it and explicitly implement the abstract methods and properties but can chose to not override the virtual methods and properties.
Exemple :
using System;
using C=System.Console;
namespace Foo
{
public class Bar
{
public static void Main(string[] args)
{
myImplementationOfTest miot = new myImplementationOfTest();
miot.myVirtualMethod();
miot.myOtherVirtualMethod();
miot.myProperty = 42;
miot.myAbstractMethod();
}
}
public abstract class test
{
public abstract int myProperty
{
get;
set;
}
public abstract void myAbstractMethod();
public virtual void myVirtualMethod()
{
C.WriteLine("foo");
}
public virtual void myOtherVirtualMethod()
{
}
}
public class myImplementationOfTest : test
{
private int _foo;
public override int myProperty
{
get { return _foo; }
set { _foo = value; }
}
public override void myAbstractMethod()
{
C.WriteLine(myProperty);
}
public override void myOtherVirtualMethod()
{
C.WriteLine("bar");
}
}
}
You would use abstract if you do not want to define any implementation in the base class and want to force it to be defined in any derived classes. Define it as a virtual if you want to provide a default implementatio that can be overriden by derived classes.
Yes, only methods can be virtual.
A member should be declared virtual if there is a base implementation, but there is a possibility of that functionality being overridden in a child class. Virtual can also be used instead of abstract to allow a method implementation to be optional (ie. the base implementation is an empty method)
There is no limitation when setting a member as virtual, but virtual members are slower than non-virtual methods.
Both methods and properties can be marked as virtual.
There is a gotcha here to be aware of with Windows Forms.
If you want a Control/UserControl from which you can inherit, even if you have no logic in the base class, you don't want it abstract, because otherwise you won't be able to use the Designer in the derived classes:
http://www.urbanpotato.net/default.aspx/document/2001
If you want to give it an implementation in your base class you make it virtual, if you don't you make it abstract.
Yes, only methods can be declared virtual.
Abstract means that you can't provide a default implementation. This in turn means that all subclasses must provide an implementation of the abstract method in order to be instantiable (concrete).
I'm not sure what you mean by 'limitations', so can't answer that point.
Properties can be declared virtual, but you can conceptually think of them as methods too.
You question is more related to style than technicalities. I think that this book
http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756
has great discussion around your question and lots of others.
First of all, I will answer you second question. Only methods can be declared virtual.
You would choose virtual instead of abstract when you want some default functionality in your base class, but you want to leave the option of overriding this functionality by classes that inherit from your base class.
For examples:
If you are implementing the Shape class, you would probably have a method called getArea() that returns the area of your shape. In this case, there's no default behavior for the getArea() method in the Shape class, so you would implement it as abstract. Implementing a method as abstract will prevent you to instantiate a Shape object.
On the other hand, if you implement the class Dog, you may want to implement the method Bark() in this case, you may want to implement a default barking sound and put it in the Dog class, while some inherited classes, like the class Chiwawa may want to override this method and implement a specific barking sound. In this case, the method bark will be implemented as virtual and you will be able to instantiate Dogs as well as Chiwawas.
I personally mark most methods and properties virtual. I use proxies and lazy loading alot, so I don't want to have to worry about changing things at a later date.
Related
I have this interface
public interface IColumn
{
bool IsVisible {get;set;}
bool IsGroupBy { get; set; }
Type CLRType { get; set; }
string GetGroupByString();
string GetFilterString();
}
and i have classes which will inherit from it, for the first 3 properties the implementation is exactly the same.
for string GetGroupByString(); the implementation is the same for all classes except 2
so i made an abstract class called ColumnBase which inherits the IColumn interface and implements all of its members and added backing fields because i need to implement INotifyPropertyChanged.
and made my classes inherit from ColumnBase and i did override the implmentations that are not meant to be the same.
I have a very limited experience with Interfaces and Abstract classes, my question is if you had an Interface and some classes that will inherit from it and you realized that the implementation for some but not all properties and functions is the same, do you create an abstract class and put the default implementation and override it inside the classes that have special implementation?
This will get you answers based on opinion and preference.
IMHO, I think this would be best suited to an abstract class with the two methods requiring differing implementations being declared as abstract methods; using abstract on the methods means that the implementations must have an implementation of that method.
public abstract class ColumnBase
{
public bool IsVisible { get; set; }
public bool IsGroupBy { get; set; }
public Type CLRType { get; set; }
public virtual string GetGroupByString()
{
return "base string";
}
public abstract string GetFilterString();
}
public class ConcreteColumn : ColumnBase
{
public override string GetGroupByString()
{
return "concrete string";
}
public override string GetFilterString()
{
return "who owns the filter string?";
}
}
do you create an abstract class and put the default implementation and override it inside the classes that have special implementation?
Yes, I would do it exactly.Actually it's kind a purpose of abstract classes and virtual / override features.In your case I think you don't need IColumn interface,you can use an abstract class.And implement all common methods inside of it, then if you want to change behavior of a method override it in nested class.
If you mark a method with virtual you can override it in nested classes and you can change the behaviour of this method depends on your current class.You might want take a look at the documentation for more details.
If your derived class is some specialized version of the base class then it would be a good idea to inherit it from the a base class, like class Rectangle : Shape. This why the derived classes are all specialized version of a same thing. For example Rectangle and Circle are in fact, inherently a shape. But consider using interfaces when you have different objects and you want some similar behaviors. For instance, you can serialize a Bird object and a Chair object, even if they have only Name and Age properties, it's not a good idea to derive them form a base class which has a Name and Age properties and Serialize() method, because they are different things. Although the implementation of Serialize() method would be the same in both of them, it's better to have an ISerializable interface and implement it in both classes.
We know if a class has an abstract method it will be abstract . It can't get an instance. But why can have an instance method? Does it have any meaning?
public abstract class AbsClass
{
public abstract void GetA();
public void Getb()
{ }
}
Not every method in an abstract class has to be abstract - when you derive from the class, the derived classes will inherit the non-abstract methods from the base class. It's extremely common to want to provide functionality in the base class that is common to all the derived classes (in fact, it's good programming practice to pull shared functionality up to the base class to avoid duplicating code in the various derived classes). It's also extremely common to want to provide "default" functionality in the base class that can then be overridden by individual derived classes.
The fact that you can't instantiate the base class itself doesn't matter - the non-abstract methods from the base class are called on instances of (non-abstract) derived classes.
Yes, it has a meaning.
It will be available for use in any derived class that does not explicitly implement it itself.
Example of a derived class:
public abstract class AbsClass
{
public abstract void GetA();
public void Getb()
{ }
}
public class DerivedClass : AbsClass
{
}
The following code will execute the abstract class's Getb() code:
var derivedClass = new DerivedClass();
derivedClass.Getb();
(Note that in the example above, the code wouldn't compile unless your derived class implemented GetA(), as it's declared as abstract, and therefore must be implemented in any concrete derived class)
Yes, it is perfectly well defined. It can't be invoked until you have an instance, which in turn indicates that you must have a concrete sub-type, but once you do the method is perfectly usable, for example:
AbsClass foo = new ConcreteClass();
foo.Getb();
Or indeed:
ConcreteClass foo = new ConcreteClass();
foo.Getb();
(since the sub-type inherits any types defined on base-types)
It is quite common for such methods to themselves use the abstract or virtual methods of the type - or indeed to be virtual.
The method will be the implementation for a concrete class that derives from AbsClass. Abstract means you can't create an instance of the class, not that it can't have any methods with implementation. You can also have instance data members in an abstract class.
As an example:
public class MyAbsClass : AbsClass
{
}
MyAbsClass mine = new MyAbsClass();
mine.Getb(); //This would call the implementation in AbsClass
If AbsClass were an interface, however, no implementation would be allowed.
I have CPU and human player so I decided to use abstract class in order to define common features. While their methods will differ, the field piecesToPlace will be the same for both.
I do not understand why it must be public, I thought that is like regular inheritance. I do not want this list to be public but it does not work otherwise.
abstract class Player
{
abstract public void Move(Piece p);
abstract public void Place(Piece p);
abstract public void TakeP(Piece p);
List<Piece> piecesToPlace = new List<Piece>();
}
It doesn't have to be public, but it does have to be internal, assuming the inherited class is in the same namespace, protected, or internal protected. An abstract class can define behavior as well as an interface. So, it still may want to hide implementation details.
The default for class members is private, so unless you specify any other access modifier for the piecesToPlace, it will only be accessible inside the Player class.
You don't have to make it public, using protected would make it accessible to inheriting classes.
It sounds like you are after the protected keyword, this will:
Access is limited to the containing class or types derived from the
containing class.
Have a look here for more information: http://msdn.microsoft.com/en-us/library/ba0a1yw2(v=vs.110).aspx
The logic is simple , it depends on how you need it. If you define it public , for eg:
class Base
{
abstract public void Print();
}
class Derived: Base
{
public override void Print()
{}
}
Main()
{
Base base = new Derived();
//its possible
base.Print();
}
if you define it as protected then base.Print is not possible to access(intellisense will not even show that such method exists). Since these methods can be only accessible from the derived class.
I couldn't understand the need or purpose of "protected" when i have "virtual/override" could someone explain me what do i need those 2 things if they are almost the same.
Edit:
Thanks for all the helpers, i now understand that "protected" is only for visibility purposes, while virtual/override is for class behavior.
They are certainly not almost the same.
The protected modifier sets the visibility of a field or method: such a member can only be accessed from the class it is defined in or from a derived class.
The virtual modifier specifies that the method it is applied to can be overridden in a derived class.
These modifiers can be combined: a method can be protected and virtual.
protected means private for current class and derived classes
virtual means it can be used as-is but also be overridden in derived classes
Maybe it is better with some code instead of things you have probably already read, here is a little sample you can play with. Try removing the comments (//) and you can see that the compiler tells you that the properties cannot be accessed
[TestFixture]
public class NewTest
{
[Test]
public void WhatGetsPrinted()
{
A a= new B();
a.Print(); //This uses B's Print method since it overrides A's
// a.ProtectedProperty is not accesible here
}
}
public class A
{
protected string ProtectedProperty { get; set; }
private string PrivateProperty { get; set; }
public virtual void Print()
{
Console.WriteLine("A");
}
}
public class B : A
{
public override void Print() // Since Print is marked virtual in the base class we can override it here
{
//base.PrivateProperty can not be accessed hhere since it is private
base.ProtectedProperty = "ProtectedProperty can be accessed here since it is protected and B:A";
Console.WriteLine("B");
}
}
I can be argued that the Most important distinction about virtual, is that this causes the compiler, when calling a method member polymorphically, which implementation to bind the compiled code to. When you call a member of a class from client code where the actual type of the object is, say derived class foo, but the variable it is being called on is actually typed (declared) as some base class, say bar, Members declared as virtual will bind to the implementation in the actual object type, (or to the most derived base class of the objects type that has an implementation). Members not declared as virtual will bind to the implementation in the type that the variable is declared to be.
A. Virtual. then, if the member is declared as virtual, the implementation in the derived class will be executed even if the variable is declared as a base type.
public class Animal
{ public virtual Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public virtual override Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Bird.Move"
B. Not Virtual. When a member which is not declared as virtual, then the implementation will be chosen based on the declared type of the variable the method is executed on. So if you have a Bird Object, in variable x declared as `Animal', and you call a method that is implemented in both classes, the compiler will bind to the implementation in the Animal class, not in Bird, even though the object is really a Bird.
public class Animal
{ public Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Animal.Move"
I think you need to understand above two things properly, since both has different purpose.
protected is the type or member can only be accessed by code in the same class or struct, or in a derived class.
The virtual keyword is for modify a method, property and allow it to be overridden in a derived class.
I'm not really sure what looks better or when do I really use in abstract classes and properties, or when to use non abstract properties. I'll try to make a simple example. Let's say I have this:
abstract class Human
{
public GenderType Gender { get; set; }
public string Name { get; set; }
public Date Born { get; set; }
public bool IsNerd { get; set; }
abstract public void Speak();
abstract public void Sleep();
abstract public void AnoyingPeopleOnStackOverflow();
//... so on
}
class Peter : Human
{
//Peter is special, he got a second name
//But thats all, everything else is the same as like on other humans
public string SecondName { get; set; }
//...override abstract stuff
}
Is this alright? As I understood, I don't have to use an abstract property if I dont want to override it. And in this situation it would be ok, just the methods like Speak, Sleep and so on should be abstract.
Now, if this is ok, when would or should I use an abstract property?
Use an abstract property when you have no default implementation and when derived classes must implement it.
Use a virtual property when you have an implementation in the base class but want to allow overriding.
Use the override keyword to override a member. Mark the member as sealed override if it should not be overridden again.
Don't mark the property as abstract or virtual if you don't want it to be overridden.
Use the new keyword to hide a non-abstract, non-virtual member (this is rarely a good idea).
How to: Define Abstract Properties
I find that abstract properties often occur in a design which implies that they will have type-specific logic and/or side effects. You are basically saying, "here is a data point that all subclasses must have, but I don't know how to implement it". However, properties which contain a large amount of logic and/or cause side effects may not be desirable. This is an important consideration, though there is no fixed right/wrong way to do it.
See:
Should Properties have Side Effects
CA1024: Use properties where appropriate
Personally, I find that I use abstract methods frequently but abstract properties rarely.
I know what I want them to do, I don't care how they do it: Interface.
I know what I want them to do, I don't care how they do some of it, but I've firm ideas on how they'll (or at least most of them) do other bits: Abstract class.
I know what I want them to do, and how most of them will do it: Concrete class with virtual members.
You can have other cases such as e.g. an abstract class with no abstract members (you can't have an instance of one, but what functionality it offers, it offers completely), but they're rarer and normally come about because a particular hierarchy offers itself cleanly and blatantly to a given problem.
(Incidentally, I wouldn't think of a Peter as a type of Human, but of each peter as an instance of human who happens to be called Peter. It's not really fair to pick on example code in this way, but when you're thinking about this sort of issue it's more pertinent than usual).
Abstract members are simply virtual members that you have to override. You use this for something that has to be implemented, but can't be implemented in the base class.
If you want to make a virtual property, and want that it has to be overridden in the class that inherits your class, then you would make it an abstract property.
If you for example have an animal class, its ability to breathe would not be possible to detemine just from the information that it's an animal, but it's something that is pretty crucial:
public abstract class Animal {
public abstract bool CanBreathe { get; }
}
For a fish and a dog the implementation would be different:
public class Dog : Animal {
public override bool CanBreathe { get { return !IsUnderWater; } }
}
public class Fish : Animal {
public override bool CanBreathe { get { return IsUnderWater; } }
}
Use abstract when all sub-classes have to implement the method/property. If there's no need for each and every sub-class to implement it, then don't use it.
As for your example, if SecondName is not required for each person, then there's no need to make an abstract property in the base class. If on the other hand, every person does need a second name, then make it an abstract property.
Example of correct usage of an abstract property:
public class Car
{
public abstract string Manufacturer { get; }
}
public class Odyssey : Car
{
public override string Manufacturer
{
get
{
return "Honda";
}
}
}
public class Camry : Car
{
public override string Manufacturer
{
get
{
return "Toyota";
}
}
}
Making Maker abstract is correct because every car has a manufacturer and needs to be able to tell the user who that maker is.
An abstract property would be used where you want the class to always expose the property, but where you can't pin down the implemetation of that property - leaving it up to/forcing the inheriting class to do so.
There's an example here, where the abstract class is named Shape, and it exposes an abstract Area property. You can't implement the Area property in the base class, as the formula for area will change for each type of shape. All shapes have an area (of some sort), so all shapes should expose the property.
Your implementation itself looks just fine. Was trying to think of a sensible example of an abstract property for a Human, but couldn't think of anything reasonable.