parent and child is an analogy of limited applicability, because a derived class is not a "child" of the base as a person's or animal's child is a child of them, or even as a subdirectory is of a directory or dependent node in a tree (GUI or data-structure).
The relationship is actually that of hypernym to hyponym. Sadly, hypernym isn't as well-known a word as parent, so people often use the less-accurate parent in explaining inheritance rather than hypernym.
Now, let's consider the first class declaration:
class GrandParent
{
public int A {get; protected set;}
public int B {get; protected set;}
public GrandParent (int a, int b)
{
A = a;
B = b;
}
}
This is exactly as in the question, except the erroneous () on the first line and ; on the sixth have been removed.
It has a single constructor, that takes two integers.
This means either:
- It makes no logical sense for a
GrandParent to ever be created, without two integers being passed.
- There's a bug in how this was defined.
- Okay, maybe not a bug, but certainly a tad lazy.
When we come to the declaration of Parent:
class Parent : GrandParent
{
public Parent () {}
}
Here I've fixed the syntax errors, but nothing else.
Since there is no explicit use of base in the constructor there is an implied call to a parameterless base(). That is, the above is exactly the same as:
class Parent : GrandParent
{
public Parent()
: base()
{
}
}
Any call to new Parent() will through the base() call new GrandParent(). Since there is no parameterless constructor on GrandParent() this can't compile.
And here the language rules are helping us:
- We said that it makes no sense for a
GrandParent to be created without two integers being used.
- We said that a
Parent is a type of GrandParent.
- We said that a
Parent is only ever created without those two integers being set.
We said three things are true that cannot all be true. The language rules are correct to point out our mistake.
To fix this we need to either:
- Allow a
GrandParent to be created without those two integers being used in its construction.
- Force
Parents to always have two integers being used in their construction, which are then in turn used in turn with the base constructor.
- Have the parameterless constructor on
Parent call base(a, b) with some set values.
- Do a mixture of the above. E.g. we could have both set values called if the parameterless constructor was called, and also another constructor that passes arguments to the base constructor.
The 3rd above would look something like:
class Parent : GrandParent
{
public Parent()
: base(42, -343213)
{
}
}
Or whatever, as long as those numbers come from somewhere (obviously in real code they would relate to something more sensible than my random typing).
Now we have a Parent that actually makes logical sense, and the rest can follow.
Parentneed a constructor that takes two arguments?A=aandB=bas well as taking in its arguments into Child. My question regards if it is possible without?()after the name of the class.Parent,GrandparentandChildas example names when explaining inheritance. A child is not a type of parent, a parent is not a type of grandparent. The names don't adequately explain the hypernym/homonym relationship, and so it isn't as immediately obvious that "thing that can be created without an A or B being set" cannot be a type of "thing that can only be created with an A or B being set".