Why I can't declare abstract an constructor of my class like this:
public abstract class MyClass {
public abstract MyClass(int param);
}
Why I can't declare abstract an constructor of my class like this:
public abstract class MyClass {
public abstract MyClass(int param);
}
You can't declare it abstract
, but you can have a constructor on your abstract class; just remove the word abstract
and provide a body for it.
By definition, the class can't be instantiated directly, so in a sense, it already is abstract.
Constructors are only applicable to the class in which they are defined, that is, they are not inherited. Base class constructors are used (you have to call one of them, even if only calling the default one automatically) but not overridden by deriving classes. You can define a constructor on an abstract base class -- it can't be used directly, but can be invoked by deriving classes. What you can't do is force a derived class to implement a specific constructor signature.
It is perfectly reasonable to have a constructor defined, typically as protected, in order to define some common set up code for all derived classes. This is especially true, perhaps, when the abstract class provides some other default behavior which relies on this set up. For example:
public abstract class Foo
{
public string Name { get; private set; }
protected Foo( string name )
{
this.Name = name;
}
}
public class Bar
{
public Bar() : base("bar")
{
...
}
}
A constructor is not an ordinary method. It has a special purpose, and so is restricted to language features that make sense for that purpose. See also: http://stackoverflow.com/questions/1788312/why-constructor-not-returns-value
Because abstract constructors are not supported.
But a abstract class can have a constructor.
What wrong with this:
public abstract class MyClass {
protected MyClass(int param)
{
}
}
In this case you oblige all derived classes to call base class constructor.
Abstract implies virtual. A non-default constructor can never be called polymorphically, so virtual and abstract are not allowed on constructors.
IF in a future version of C#, generics are enhanced to allow calling non-default constructors through a generic type parameter, then polymorphic calls to constructors would be possible and virtual and abstract constructors might be added as well.
Constructors are closer to static methods rather than "regular" methods. Like static methods, they can be overloaded, but not overriden. That is, they are not inherited but can be redefined.
public BaseClass
{
public BaseClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass extends BaseClass
{
public SubClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass2 extends BaseClass
{
}
new SubClass( "hello" );
SubClass.doIt( "hello" );
new SubClass2( "hello" ); // NOK
SubClass2.doIt( "hello" ); // NOK
Constructors and static methods are never dispatched dynamically (virtually) -- You always know the concrete type you instantiate or the concrete class of the static method. That's why it makes no sense to have abstract constructor and abstract static method. That's why you can also not specify constructor and static method in interfaces.
You can even think of constructor as static factory method (and see the corresponding pattern):
MyClass obj = new MyClass(); // the way it is
MyClass obj = MyClass.new(); // think of it like this
The only case I see where it would make sense to define abstract constructor or abstract static method would be if reflection is used. In this case, you could ensure that all subclass would redefine the corresponding static method or constructor. But reflection is another topic...
Note: in languages such as Smalltalk where classes are regular objects, you can override static method and have abstract constructor. But it doesn't apply to Java because classes are not "regular" objects even if you can get them with reflection.