I have written a simple generic class in C#.
class Foo<T>
{
public object O{get;set;}
public Foo(object o)
{
O=o;
}
}
and another class inheriting from it
class Bar:Foo<object>
{
public Foo(object o):base(o)
{ }
}
My question is whether I can avoid writing that constructor in Bar class, because it does nothing special at all. PS: the parameter in constructor is necessary.
No, you can't. There's no inheritance of constructors. The constructor in Bar does do something: it provides an argument to the base constructor, using its own parameter for that argument. There's no way of doing that automatically.
The only constructor the compiler will supply for you automatically is one of equivalent to:
public Bar() : base()
{
}
for a concrete class, or for an abstract class:
protected Bar() : base()
{
}
... and that's only provided if you don't supply any other constructors explicitly.
Related
I am trying to learn C#. The below data is from a Microsoft C# help website.
I don't understand this statement, "If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor by using base."
I thought that if there is no default constructor for a class, C# will automatically assign default values to int, char or whatever is declared in a class. If a base class does not have a constructor and it has a child class, does the rule mentioned in the last sentence not apply? Please clarify.
In a derived class, if a base-class constructor is not called explicitly by using the base keyword, the default constructor, if there is one, is called implicitly. This means that the following constructor declarations are effectively the same:
C#
public Manager(int initialdata)
{
//Add further instructions here.
}
C#
public Manager(int initialdata)
: base()
{
//Add further instructions here.
}
If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor by using base.
If you do not define a constructor for a class:
public class DemoClass
{
public void SomeFunction() { }
}
C# will add a default (parameterless) constructor for you. In this case; nothing special needs to be done with derived classes, as they will use the provided default constructor. Of course, you can always define your own default (parameterless) constructor:
public class DemoClass
{
public void DemoClass() { }
public void SomeFunction() { }
}
Which still doesn't require anything special for derived classes, since they can still use it. If however, you define a parameterized constructor, without defining a default:
public class DemoClass
{
public void DemoClass(string argument) { }
public void SomeFunction() { }
}
Now there is no default (parameterless) constructor for derived classes to use; and you need to say which constructor to use with base:
public class DerivedClass : DemoClass
{
public DerivedClass() : base(String.Empty) { }
}
Is it possible to instruct a construct in C# to forcefully call an implementing method?
I've created an interface that forces implementing classes to implement a method. Now I want this method to be called by all constructors of implementing classes.
I know I can create a base class and call the method in its constructor, but I cannot force every child class to call the base class constructor?
No, Abstract class will be your workaround.
public abstract class MyAbstract : IMyInterface
{
public MyAbstract()
{
MyMustCallmethod();
}
public abstract void MyInterfaceMember();//Let derived classes implement your interface
private void MyMustCallmethod()
{
//implementation
}
}
When you call the constructor to an inheriting class (say B inheriting from A), the constructor for the inherited class will be also called. So if you want to make sure that all classes inheriting from A call the Foo method you can set the call in the A constructor:
public class A {
public A() {
Foo();
}
public void Foo() {/* something here */}
}
public class B: A {
public B(string param) {/* A constructor will be called */}
}
poke comment below explains that the default constructor is selected. If no default constructor exists you must call a constructor explicitly.
But you cannot force an interface method to be called because interfaces contain no implementation. Using the above code will mean that only the A class will implement the interface. So in order to ensure that inheriting classes call the method and must define it explicitly i use something like this:
public interface IHasFooThatMustBeCalledInConstructor {
void Foo();
}
public abstract class A: IHasFooThatMustBeCalledInConstructor {
public A() {
Foo();
}
public abstract void Foo();
}
public class B: A {
public B(string param) {}
public void Foo() { };
}
abstract class CAbstract
{
private string mParam1;
public CAbstract(string param1)
{
mParam1 = param1;
}
}
class CBase : CAbstract
{
}
For the class CBase, it should be initialized by providing the parameter, so how to disable the parameterless constructor for CBase class?
If you define a parameterized constructor in CBase, there is no default constructor. You do not need to do anything special.
If your intention is for all derived classes of CAbstract to implement a parameterized constructor, that is not something you can (cleanly) accomplish. The derived types have freedom to provide their own members, including constructor overloads.
The only thing required of them is that if CAbstract only exposes a parameterized constructor, the constructors of derived types must invoke it directly.
class CDerived : CAbstract
{
public CDerived() : base("some default argument") { }
public CDerived(string arg) : base(arg) { }
}
To disable default constructor you need to provide non-default constructor.
The code that you pasted is not compilable. To make it compilable you could do something like this:
class CBase : CAbstract
{
public CBase(string param1)
: base(param1)
{
}
}
Please correct me if I am wrong, but I think I achieved that goal with this code:
//only for forbiding the calls of constructors without parameters on derived classes
public class UnconstructableWithoutArguments
{
private UnconstructableWithoutArguments()
{
}
public UnconstructableWithoutArguments(params object[] list)
{
}
}
As an abstract class cannot be instantiated, why is a constructor still allowed inside the abstract class?
public abstract class SomeClass
{
private string _label;
public SomeClass(string label)
{
_label=label;
}
}
Constructors of any derived class still have to call a constructor in the abstract class. If you don't specify any constructors at all, all derived classes will just have to use the default parameterless one supplied by the compiler.
It absolutely makes sense to have a constructor - but "public" is really equivalent to "protected" in this case.
Because you can still do the following:
public class SomeChildClass : SomeClass
{
public SomeChildClass(string label) : base(label){ }
public string GetLabel() { return _label; }
}
As you can see, the child class can call the base contructor (on the abstract class) to create an instance of itself.
Like Jon said though, public really isn't necessary. It's effectively the same as protected.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can’t I create an abstract constructor on an abstract C# class?
Why I can't declare abstract an constructor of my class like this:
public abstract class MyClass {
public abstract MyClass(int param);
}
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 : Foo
{
public Bar() : base("bar")
{
...
}
}
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.
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.
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.
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.
Because abstract constructors are not supported.
But a abstract class can have a constructor.
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: Why do constructors not return values?
By definition, the class can't be instantiated directly, so in a sense, it already is abstract.