Relevance of 'public' constructor in abstract class - c#

Is there any relevance of a 'public' constructor in an abstract class?
I can not think of any possible way to use it, in that case shouldn't it be treated as error by compiler (C#, not sure if other languages allow that).
Sample Code:
internal abstract class Vehicle
{
public Vehicle()
{
}
}
The C# compiler allows this code to compile, while there is no way i can call this contructor from the outside world. It can be called from derived classes only.
So shouldn't it allow 'protected' and 'private' modifiers only.
Please comment.

There's no reason for a public constructor for an abstract class. I'd assume that the reason that the compiler doesn't complain is as simple that they just didn't spend time covering that since it really doesn't matter if it's public or protected.

Inside an abstract class, for an instance constructor, modifiers public, protected internal, and protected are all equivalent. Then internal is more strict than them, and private is the most strict access.
If all instance constructors are private, only classes nested inside the class in question can inherit from it.
Note: If no instance constructors are given for a non-static class, then the compiler will generate one by itself. That's a constructor taking zero arguments. If the class is abstract, that auto-generated constructor is protected. Otherwise it is public.
The only situation I can think of where it makes a difference if an instance constructor of an abstract class is public or protected, is when you use reflection. As an example, saying
ConstructorInfo[] ctors = typeof(Vehicle).GetConstructors();
will give an empty array if the sole constructor is protected, and a length-1 array if it's public. But of course there are overloads that specify BindingFlags, so this is not a problem, just something to remember if one uses reflection.

Dupe: there is another question on SO just like this: Abstract class constructor access modifier
The answers on that question come down to the same thing in the end: it does not really matter if you declare it protected or public.
Also there seems to be some discussion about it in literature (e.g. in Framework Design Guidelines). This is referenced in this blogpost: Good design or bad design of abstract class?

Yes, a public ctor on an abstract class is meaningless and a bit misleading as it will behave as protected in that only derived classes may call it.
A private ctor will have little meaning outside of interesting edge cases.
A protected ctor would make sense if required by derived classes.

Related

Do C# classes inherit constructors?

I just read http://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet/
I don't know when it is written. It says:
"Since C# unfortunately doesn’t inherit constructors of base classes, this new type only has the standard constructor with no parameters and is therefore relatively useless."
This says the same in 2010: C#: inheriting constructors
Is this still true?
EDIT: Following on from answers, I'm sure there would be a way around the default parameterless constructor. Are there other reasons for lack of constructor inheritance?
Constructors have never been inheritable in the entire lifetime of the C# language. That hasn't changed in C# 5.0: at the end of section 1.6.7.1 of the C# 5.0 spec, it still says:
Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.
So it still holds true today, and I imagine it will remain so in the foreseeable future.
You have to explicitly call the constructor of the base class, unless the base class defines a default constructor. So yes they are not inherited.
Which sometimes lead to a bunch of boiler plate code where you do nothing than pass arguments from one constructor to another
public class NegativArgument : Exception {
public NegativeArgument() : this("The number given was less than zero"){}
public NegativeArgument(string message) : this(message,null){}
public NegativeArgument(string message, Exception inner) : base:(message,inner){}
}
but what if you had an Exception type that should always have the same message? how would you solve that if the constructors were inherited? The exception class has a constructor that accepts a message so creating a new Exception type would in that case get that constructor too, not inheriting constructors makes it easy
public class NegativArgument : Exception {
public NegativeArgument() : base("The number given was less than zero"){}
}
If the base class does not have a default constructor you will have a compile error if you do not explicitly call a base class constructor.
Constructors are not inherited in C#.
If they were, then every class would have a default parameterless constructor (because all classes derive from Object and Object has a default parameterless constructor).
Many classes should only be constructed with specific values; this would be impossible to ensure if every class had a default parameterless constructor.
You should call them explicitly the constructor of the base classes. They are not inheritable.
Didn't change anything about them.
Check out : Constructors (C# Programming Guide)
From the spec §1.6.7.1:
Unlike other members, instance constructors are not inherited, and a
class has no instance constructors other than those actually declared
in the class. If no instance constructor is supplied for a class, then
an empty one with no parameters is automatically provided.
http://msdn.microsoft.com/en-us/library/ms228593.aspx
This answer is based upon the section "Constructors are not inherited" near the bottom of this entry on Jon Skeet's blog.
Summary
There are many cases in which a derived class may require information beyond that contained in the base class. Jon gives the example of the FileInfo class which requires additional information to be well-defined. Namely, that of the file for which info is to be provided
Any suggested 'fix' for this would entail overriding things in a way that prevents constructing such derived objects using the inherited constructors. However, knowingly requiring derived classes to override their base classes in a way that makes them more restrictive goes against best practice. (see: this question for Jon's discussion of the Liskov Substitution principle and the importance of being able to use derived classes wherever their base can be used.)
Additionally, from just a maintenance perspective, forcing manual override of constructors would make it difficult to reason about future behavior should the base class constructors change, and would entail having to always check, and often modify, any derived classes when new constructors are added to the base. Even a few of these would be problematic; but in cases where there are dozens or more such classes (and derived classes of those classes, etc.), maintenance and QA will quickly become a nightmare.

Abstract keyword in front of a class: to be or not to be

Should I always annotate a class which has only protected constructors by design with abstract keyword? Why?
Let’s suppose the class does not have abstract members.
If no, could you give some examples?
No. A type with only protected constructors is still creatable - either through a static factory method on the type, or via reflection (including, as one option, totally skipping the constructors).
An abstract type is never creatable.
Mark the type as abstract: if it is abstract. So: does it make sense for an object of that type (rather than a subclass) to exist?
No, you should not do this by design since thats not what abstract classes are made for.
abstract on MSDN
In my opinion, an abstract class is used to represent a bunch of classes which are of same type in logical view. It means that this bunch of classes are common in either properties or behaviours. It is not used to represent the class which has a 'Private' constructor and can not be created outside the class itself.

Abstract Method in Non Abstract Class

I want to know the reason behind the design of restricting Abstract Methods in Non Abstract Class (in C#).
I understand that the class instance won't have the definition and thus they wont be callable, but when static methods are defined,they are excluded from the instance too. Why abstract methods are not handled that way, any specific reason for the same?
They could be allowed in concrete class and the deriving class can be forced to implement methods, basically that is what, is done in case of abstract methods in an abstract class.
First, I think that what you're asking doesn't logically make sense. If you have an abstract method, it basically means that the method is unfinished (as #ChrisSinclair pointed out). But that also means the whole class is unfinished, so it also has to be abstract.
Or another way to put it: if you had an abstract method on a class that wasn't abstract, that would mean you had a method that cannot be called. But that means the method is not useful, you could remove it and it would all work the same.
Now, I'll try to be more concrete by using an example: imagine the following code:
Animal[] zoo = new Animal[] { new Monkey(), new Fish(), new Animal() };
foreach (Animal animal in zoo)
animal.MakeSound();
Here, Animal is the non-abstract base class (which is why I can put it directly into the array), Monkey and Fish are derived from Animal and MakeSound() is the abstract method. What should this code do? You didn't state that clearly, but I can imagine few options:
You can't call MakeSound() on a variable typed as Animal, you can call it only using a variable typed as one of the derived classes, so this is a compile error.
This is not a good solution, because the whole point of abstract is to be able to treat instances of derived classes as the base class, and still get behaviour that's specific to the derived class. If you want this, just put a normal (no abstract, virtual or override) method into each derived class and don't do anything with the base class.
You can't call MakeSound() on an object whose runtime type is actually Animal, so this is a runtime error (an exception).
This is also not a good solution. C# is a statically typed language and so it tries to catch errors like “you can't call this method” at compile time (with obvious exceptions like reflection and dynamic), so making this into a runtime error wouldn't fit with the rest of the language. Besides, you can do this easily by creating a virtual method in the base class that throws an exception.
To sum up, you want something that doesn't make much sense, and smells of bad design (a base class that behaves differently than its derived classes) and can be worked around quite easily. These are all signs of a feature that should not be implemented.
So, you want to allow
class C { abstract void M(); }
to compile. Suppose it did. What do you then want to happen when someone does
new C().M();
? You want an execution-time error? Well, in general C# prefers compile-time errors to execution-time errors. If you don't like that philosophy, there are other languages available...
I think you've answered your own question, an abstract method isn't defined initially. Therefore the class cannot be instanciated. You're saying it should ignore it, but by definition when adding an abstract method you're saying "every class created from this must implement this {abstract method}" hence the class where you define the abstract class must also be abstract because the abstract method is still undefined at that point.
The abstract class may contain abstract member. There is the only method declaration if any method has an abstract keyword we can't implement in the same class. So the abstract class is incompleted. That is why the object is not created for an abstract class.
Non-abstract class can't contain abstract member.
Example:
namespace InterviewPreparation
{
public abstract class baseclass
{
public abstract void method1(); //abstract method
public abstract void method2(); //abstract method
public void method3() { } //Non- abstract method----->It is necessary to implement here.
}
class childclass : baseclass
{
public override void method1() { }
public override void method2() { }
}
public class Program //Non Abstract Class
{
public static void Main()
{
baseclass b = new childclass(); //create instance
b.method1();
b.method2();
b.method3();
}
}
}
You can achieve what you want using "virtual" methods but using virtual methods can lead to more runtime business logic errors as a developer is not "forced" to implement the logic in the child class.
I think there's a valid point here. An abstract method is the perfect solution as it would "enforce" the requirement of defining the method body in children.
I have come across many many situations where the parent class had to (or it would be more efficient to) implement some logic but "Only" children could implement rest of the logic"
So if the opportunity was there I would happily mix abstract methods with complete methods.
#AakashM, I appreciate C# prefers compile time errors. So do I. And so does anybody. This is about thinking out-of-the-box.
And supporting this will not affect that.
Let's think out of the box here, rather than saying "hurrah" to big boy decisions.
C# compiler can detect and deny someone of using an abstract class directly because it uses the "abstract" keyword.
C# also knows to force any child class to implement any abstract methods. How? because of the use of the "abstract" keyword.
This is pretty simple to understand to anyone who has studied the internals of a programming language.
So, why can't C# detect an "abstract" keyword next to a method in a normal class and handle it at the COMPILE TIME.
The reason is it takes "reworking" and the effort is not worth supporting the small demand.
Specially in an industry that lacks people who think out of the boxes that big boys have given them.
It's still not clear why you would want that, but an alternative approach could be to force derived classes to provide a delegate instance. Something like this
class MyConcreteClass
{
readonly Func<int, DateTime, string> methodImpl;
// constructor requires a delegate instance
public MyConcreteClass(Func<int, DateTime, string> methodImpl)
{
if (methodImpl == null)
throw new ArgumentNullException();
this.methodImpl = methodImpl;
}
...
}
(The signature string MethodImpl(int, DateTime) is just an example, of course.)
Otherwise, I can recommend the other answers to explain why your wish probably isn't something which would make the world better.
So the answers above are correct: having abstract methods makes the class inherently abstract. If you cannot instance part of a class, then you cannot instance the class itself. However, the answers above didn't really discuss your options here.
First, this is mainly an issue for public static methods. If the methods aren't intended to be public, then you could have protected non-abstract methods, which are allowed in an abstract class declaration. So, you could just move these static methods to a separate static class without much issue.
As an alternative, you could keep those methods in the class, but then instead of having abstract methods, declare an interface. Essentially, you have a multiple-inheritance problem as you want the derived class to inherit from two conceptually different objects: a non-abstract parent with public static members, and an abstract parent with abstract methods. Unlike some other frameworks, C# does permit multiple inheritance. Instead, C# offers a formal interface declaration that is intended to fill this purpose. Moreover, the whole point of abstract methods, really, is just to impose a certain conceptual interface.
I have a scenario very similar to what the OP is trying to achieve. In my case the method that I want to make abstract would be a protected method and would only be known to the base class. So the "new C().M();" does not apply because the method in question is not public. I want to be able to instantiate and call public methods on the base class (therefore it needs to be non-abstract), but I need these public methods to call a protected implementation of the protected method in the child class and have no default implementation in the parent. In a manner of speaking, I need to force descendants to override the method. I don't know what the child class is at compile time due to dependency injection.
My solution was to follow the rules and use a concrete base class and a virtual protected method. For the default implementation, though, I throw a NotImplementedException with the error "The implementation for method name must be provided in the implementation of the child class."
protected virtual void MyProtectedMethod()
{
throw new NotImplementedException("The implementation for MyProtectedMethod must be provided in the implementation of the child class.");
}
In this way a default implementation can never be used and implementers of descendant implementations will quickly see that they missed an important step.

Should a base class be marked abstract if there are no abstract members?

Is it okay for a class to be marked as abstract if it has no abstract members? Even if there is no practical reason for to directly instantiate it? (aside from unit tests)
Yes, it is reasonable and beneficial to mark explicitly as abstract a base class that should not be instantiated -- even in the absence of abstract methods.
It enforces the common guideline to make non-leaf classes abstract.
It prevents other programmers from creating instances of the class. This may make it easier for you to add abstract methods to it later.
Do you want that class to ever have an actual instance? If yes, then don't mark it abstract. If no, then mark it abstract.
Short answer: yes.
Long answer: The abstract keyword marks a class and/or its members as not being useful directly. Why this may be varies from case to case; an abstract class may be too basic to do any real work, or it may have abstract members that are required to exist for other code in this class to work, but cannot be concretely defined at this level. The short of it is that by marking a class abstract, you tell the compiler and other developers not to instantiate this class directly, but instead to inherit from it to create a concrete useful implementation. You can do this even if the class has a working implementation for all its members, if you feel that the class must be inherited to make the best use of that implementation.
If the goal is to make a base class that other classes will extend, it makes sense to make this an abstract class.
If, however, the goal is to make some form of Utility class -- one that has only static members -- the best way to handle this is to give the class a single constructor marked private. That way, the class can not be instantiated, nor subclassed. This sends a clear signal that the only use of the class is to use its static methods. (This is a tip from Effective Java, by Josh Bloch)
Yes, I think so. At least that's what I do from time to time ;-)

Abstract Class Design: Why not define public constructores?

Look here (Abstract Class Design): http://msdn.microsoft.com/en-us/library/ms229047.aspx
It says:
(1) Do not define public or protected internal (Protected Friend in Visual Basic) constructors in abstract types.
In C#, we are not able to instantiate an abstract class. So, does it still matter to define public constructors for abstract classes in C# ? Or not writing public constructors for abstract classes because of semantic meaning?
It also says:
(2) Do define a protected or an internal constructor in abstract classes.
Define internal constructors ?? In (1), it tells us that not defining internal protected constructors is because that "Constructors with public or protected internal visibility are for types that can be instantiated". Doesn't defining internal constructors for abstract classes break the rules in (1) ?
Thanks in advance. :)
Let's look at each of the cases.
Recommended:
protected - The most obvious case - all subclasses can call the constructor, irrespective of which assembly they reside in (as long as the the abstract base-class itself is visible to them).
internal - Useful when you want the abstract type to be publicly visible, but not publicly inheritable. In this case, you would want to make all of the non-private constructors internal. Only subclasses within the same assembly as the abstract base-class would be able to call the constructors - effectively, only they would be able to inherit. Another use-case would be if you wanted a 'special' constructor that should only be visible to same-assembly subclasses.
private - Used mainly for 'dirty-work' constructors that are targeted by other constructors of the abstract class when it uses constructor-chaining. The only other use, when all the constructors are private, is to only allow subclassing by nested classes, which do have access to private members of the containing-type.
Not recommended:
public - Not useful, behaves identically to protected. Only subclasses can call the constructor anyway, since the base-class is abstract.
protected internal - This too is no different from protected. The protected internal accessibility level means protected OR internal, not protected AND internal. However, the internal modifier here serves no purpose - it doesn't prevent subclasses residing outside the assembly from calling the constructor (assuming the abstract base-class is public) since they can rely on protected access, nor does it allow same-assembly types that are not subclasses from calling it (the type is abstract).
The key point here is that every non-private constructor in an abstract class is already at best protected. The vanilla internal-modifier strengthens restrictions on who can call the constructor. public and protected internal don't accomplish anything because they appear to weaken restrictions, but don't really succeed in doing so.
n C#, we are not able to instantiate an abstract class. So, does it still matter to define public constructors for abstract classes in C# ? Or not writing public constructors for abstract classes is because of the semantic meaning?
Exactly. You don't want the user to see an accessible constructor, but when they call it, they get a compile error.
Define internal constructors ?? In (1), it tells us that not defining internal protected constructors is because that "Constructors with public or protected internal visibility are for types that can be instantiated". Doesn't defining internal constructors for abstract classes break the rules in (1) ?
I believe rule 1 is about public and protected internal rule 2 is about protected and internal. So there's no intersection between the two.
Years passed. I think I have better understanding of this question now. So I would like to add some more input besides Ani's excellent answer.
In C#, we are not able to instantiate an abstract class. So, does it
still matter to define public constructors for abstract classes in C#
?
It doesn't matter to the compiler, but it does matter to code readers. Public constructors in abstract types is misleading to code readers (they might think they can be instantiated).
Define internal constructors ?? In (1), it tells us that not defining
internal protected constructors is because that "Constructors with
public or protected internal visibility are for types that can be
instantiated". Doesn't defining internal constructors for abstract
classes break the rules in (1) ?
If we want the abstract class to be inheritable only by subclasses within the same assembly, obviously we cannot use protected (otherwise it can be inherited outside the assembly). Now we have some options to choose:
public - As mentioned above, public is misleading to code readers. Don't use it.
private - We want the abstract class to be inheritable by subclasses within the same assembly, not just by nested subclasses, so private won't work.
protected internal - We'll never need it because it's no different from protected.
internal - It is misleading to code readers, but we have no other choice. I would think it a trade-off.

Categories