As I understand it, a method being marked abstract is implicitly virtual. The reason: Suppose the compile-time type of a given object is abstract. If one of the object's abstract methods is being called, the actual method to be executed is the one defined in the object's runtime type. Isn't it? If I'm right then the abstract method behaves as if it is also virtual.
In spite of that, I have successfully marked a C# method both abstract and virtual simultaneously:
public abstract virtual void crazy();
I suppose it means that an abstract method is not necessarily virtual and being abstract is actually orthogonal to being virtual.
What do I get wrong? How can an abstract method not be virtual?
You cannot mark a method as both abstract and virtual. It will result in a compiler error:
The abstract method 'Namespace.Class.Foo()' cannot be marked virtual
The rest of your question is correct: abstract methods are implicitly virtual.
From MSDN
An abstract method is implicitly a virtual method.
Abstract method declarations are only permitted in abstract classes.
Because an abstract method declaration provides no actual implementation, there is no method body; the method declaration simply ends with a semicolon and there are no braces ({ }) following the signature.
The implementation is provided by an overriding method, which is a member of a non-abstract class.
It is an error to use the static or virtual modifiers in an abstract method declaration.
"You cannot use the virtual modifier with the static, abstract, private, or override modifiers."
http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.100).aspx
Related
The following interface has no errors in a .Net Core Console application with C#-8.0
interface I
{
public abstract void f();
public virtual void g() => Console.WriteLine("g");
public sealed void h() => Console.WriteLine("h");
}
abstract prevents adding a definition in interface. virtual and sealed necessitate a definition in interface. sealed prevents an implementation of h in derived classes.
Do abstract, virtual and sealed, when used in interfaces, have any other meaning or applications in current implemented version of C# - 8? How and when should they be used in interfaces?
This is from the proposal:
The syntax for an interface is relaxed to permit modifiers on its
members. The following are permitted: private, protected, internal,
public, virtual, abstract, sealed, static, extern, and partial.
An interface member whose declaration includes a body is a virtual
member unless the sealed or private modifier is used. The virtual
modifier may be used on a function member that would otherwise be
implicitly virtual. Similarly, although abstract is the default on
interface members without bodies, that modifier may be given
explicitly. A non-virtual member may be declared using the sealed
keyword.
It is an error for a private or sealed function member of an interface
to have no body. A private function member may not have the modifier
sealed.
Not really dealt with abstract methods that much but am looking at an abstract method inside an abstract class.
protected abstract bool Validate()
{
}
When I create the above class I get an error that tells me I need to specify a return type as per a normal method. Is this correct or am I doing something wrong?
If you declaring the abstract method then you should not give body
protected abstract bool Validate();
If it is not abstract method declaration but you giving implementation of an abstract method then you should return bool using return statement from method method to satisfy the return type in declartion.
protected abstract bool Validate()
{
//The method code
return false;
}
An abstract method declaration introduces a new virtual method but
does not provide an implementation of that method. Instead,
non-abstract derived classes are required to provide their own
implementation by overriding that method. Because an abstract method
provides no actual implementation, the method-body of an abstract
method simply consists of a semicolon, MSDN.
Abstract method should not have body. It is yielded to the derived class to implement the method.
protected abstract bool Validate();
Take a look at the documentation:
Use the abstract modifier in a method or property declaration to indicate that the method or property does not contain implementation.
Abstract methods have the following features:
An abstract method is implicitly a virtual method.
Abstract method declarations are only permitted in abstract classes.
Because an abstract method declaration provides no actual implementation, there is no method body; the method declaration simply ends with a semicolon and there are no curly braces ({ }) following the signature.
http://msdn.microsoft.com/en-us/library/sf985hc5.aspx
In C# abstract methods do not have implementation, so your code should look like:
//no { and } in there
protected abstract bool Validate();
You cannot create an instance of an abstract class, you should create another class that is derived from you abstract class, and in that new class you implement this method.
As others mentioned abstract methods dont have bodies.
The reason why they do not is that classes cant have instances. That mean youll never have object of abstract class.
You have to extend abstract class and implement body in concrete class
The template method pattern provides that the abstract base class has a not overridable method: this method implements the common algorithm and should not overridden in the subclasses. In Java the template method is declared final within the abstract base class, in C# the sealed keyword has a similar meaning, but a not overridden method can not be declared sealed.
public abstract class Base
{
protected abstract AlgorithmStep1();
protected abstract AlgorithmStep2();
public sealed void TemplateMethod() // sealed: compile error
{
AlgorithmStep1();
AlgorithmStep2();
}
}
How can I solve this problem?
Why can not prevent a method can be overridden by subclasses (in C#)?
The sealed modifier is only valid for function members which are overriding base class members, to stop them from being virtual for derived classes. Function members are non-virtual by default in C# (unlike Java). You still need the sealed modifier for a class though - classes aren't sealed by default.
Just remove the sealed modifier from your method and it should be fine.
See section 10.6.5 of the C# 4 spec for more details about sealed methods (sealed properties and events are in section 10.7.5 and 10.8.4 respectively).
When an instance method declaration includes a sealed modifier, that method is said to be a sealed method. If an instance method declaration includes the sealed modifier, it must also include the override modifier. Use of the sealed modifier prevents a derived class from further overriding the method.
Just remove the sealed keyword. By default, methods are not overridable; subclasses cannot override them, only hide them.
C# methods are sealed by default
I have a base class which I want to provide some 'base' functionality for methods for all inheriting classes.
In my inheriting classes I want to do:
public override void Setup()
{
base.Setup();
}
But at the moment it says I have to use the new keyword.
How to I have it so I have to use the override keyword?
Is there any difference between how it is currently with me using the new keyword and using override?
It says so because you have not declared the base method virtual. Once you do so, the base virtual/derived override pair of keywords will make sense. Right now, the compiler is complaining that you cannot override a non-virtual method.
When you use the override keyword the derived method is used even when the instance is passed as a Base class type. Hence there needs to be a virtual in the base class so that the programme knows it has to make a runtime check of what the actual type of the instance is. It then looks up what the actual type is and if it is a derived type it checks if their is an override in the derived class for that particular method in the base class.
Member hiding is different. The base member will only be hidden if it is actually passed as an instance of the derived class. If the object is passed as a base class, the base class method will still be used. If you hide a member, you get a warning if you haven't use the new keyword. The new keyword is merely to tell the complier, that you really do mean to hide the base type method.
Are abstract methods internally public and virtual in c#?
All methods are, by default, private and if an abstract method is private, it will not be available to derived class, yielding the error "virtual or abstract members cannot be private"
I think you are asking a different question than most people think (in other words it seems like you understand what abstract means).
You cannot declare a private abstract method - the compiler issues an error. Both of these classes will not compile:
class Foo
{
private abstract void Bar();
}
class Baz
{
// This one is implicitly private - just like any other
// method declared without an access modifier
abstract void Bah();
}
The compiler is preventing you from declaring a useless method since a private abstract member cannot be used in a derived class and has no implementation (and therefore no use) to the declaring class.
It is important to note that the default access modifier applied to an abstract member by the compiler (if you do not specify one yourself) is still private just like it would be if the method was not abstract.
Abstract is just a way to say: "I am here, but no one has told me what I'm going to do yet." And since no one has implemented that member yet someone must do that. To do that you have to inherit that class, and override that member.
To be able to override something it has to be declared either abstract or virtual, and must at least be accessible to the inheritor, i.e. must be marked protected, internal or public.
Abstract methods cannot be private and are virtual. They must be at least protected.
By virtue of Jon Skeet's argument here (What are the Default Access Modifiers in C#?)
The default access for everything in C# is "the most restricted access you could declare for that member"
It must be "protected"
As pointed out by Pieter default is always private, so:
abstract class Foo
{
abstract void Bar();
}
Gives compiler error
virtual or abstract members cannot be private