Single Inheritance in C# - object class? - c#

I have been asking myself this question for a long time now. Thought of posting it. C# doesn't support Multiple Inheritance(this is the fact). All classes created in C# derive out of 'Object' class(again a fact).
So if C# does not support Multiple inheritance, then how are we able to extend a class even though it already extends Object class?
Illustating with an example:
class A : object - Class A created.
class B : object - Class B created.
class A : B - this again is supported. What happens to the earlier association to object.
We are able to use object class methods in A after step 3. So is the turned to multi level inheritance. If that is the case, then
class A : B
class C : B
class A : C - I must be able to access class B's methods in A. Which is not the case?
Can anyone please explain?

Joel's answer is correct. There is a difference between multiple inheritance and an inhertance tree (or derivation chain). In your example, you actually show an inhertance tree: One object inherits (derives) from another object higher in the tree. Multiple inheritance allows one object to inherit from multiple base classes.
Take, for example, the following tree:
public class BaseClass { }
public class SpecialBaseClass : BaseClass {}
public class SpecialtyDerivedClass : SpecialBaseClass {}
This is perfectly valid and says that SpecialtyDerivedClass inherits from SpecialBaseClass (SpecialtyDerivedClass' parent) which, in turn, derives from BaseClass (SpecialtyDerivedClass' grandparent).
Under the idea of multiple inheritance, the example would look like this:
public class BaseClass { }
public class SpecialBaseClass {}
public class SpecialtyDerivedClass : BaseClass, SpecialBaseClass {}
This is not allowed in .NET, but it says that SpecialityDerivedClass inherits from both BaseClass and SpecialBaseClass (which are both parents).
.NET does allow a form of multiple inheritance by allowing you to inherit from more than one interface. Changing the example above slightly:
public class BaseClass { }
public interface ISpecialBase {}
public interface ISpecialDerived {}
public class SpecialtyDerivedClass : BaseClass, ISpecialBase, ISpecialDerived {}
This says that SpecialtyDerivedClass inherits from BaseClass (it's parent) and also ISpecialBase and ISpecialDerived (also parent's but more like step-parents as interfaces can't specify functionality).

You're confusing mutliple inheritance with an inheritance tree. You can inherit from something other than Object. It's just that Object is sitting way up there at the top of your tree. And someone can inherit your class, but because Object is still up there at the top that class will also inherit from object. Your "Multi-level" inheritance is not multiple inheritance.
Multiple inheritance is when you inherit from two different trees, and .Net actually does support this after a fashion via interfaces.

All classes ultimately derive from Object.
public class A
is implicitly equivalent to
public class A : System.Object
When you derive from another class
public class A : B
where
public class B : System.Object
B becomes the parent class, and Object becomes the grandparent class.
And so on.
So it is the parent, grandparent, great-grandparent (etc) class of all other classes.

One way to look at it is this: C# has an inheritance tree, while C++ (or other muliple-inheritance languages) has an inheritance lattice.

Given below.
public class A : B
{
}
public class B : C
{
public int BProperty { get; set; }
}
public class C
{
public int CProperty { get; set; }
}
public class Test
{
public void TestStuff()
{
A a = new A();
// These are valid.
a.CProperty = 1;
a.BProperty = 2;
}
}
This is valid. Object is a base for C in this case.

In the example, the reason that B can extend A is because A extends Object. A class can only specify one parent class, but that class must either be object or have object as one of its ancestors.

A class inherits from object if you do not specify a base class. Thus:
class C {}
is the same as
class C : Object {}
However, if you specify a base class, it will inherit from that class instead of Object. Thus,
class B : C {}
B directly inherits from C instead of Object. Another example,
class A : B {}
In this case, A inherits from B instead of Object. To summarize, in this hierarchy:
class C {}
class B : C {}
class A : B {}
Class A derives from B, which derives from C. So Class A is indirectly derived from C because B is derived from C. C also derived from Object which in not explicitly specified but it is there by default. So A is indirectly derived from Object too.

A class in C# can only have one parent, but it can have multiple ancestors. You can implement multiple interfaces, but that only means that your class agrees to implement the signatures defined by those interfaces. You don't actually inherit any functionality from those interfaces.

Related

Generics class constraint multi level inheritance

Looking for help to put such structure together.
Have base generic class:
public class A<T>
where T: class
{
public T info { get; set; }
}
Works good for one step inheritance like:
class B : A<BInfoClass>{}
But need same for higher hierarchy members like, but without making all classes generics:
class C : B<CInfoClass>{}
Need possibility to have specific "info" type for each B, C, D etc. ("info" classes derive from one base):
I'd like to suggest to add one more level of hierarchy just to make generic class to be pure generic.
You can put all common code to the AContainer also.
public class AContainer<T> where T : class, InfoA {
public T info { get; set; }
}
public class A : AContainer<InfoA> {}
public class BContainer<T>: AContainer<T> {}
public class B : BContainer<InfoB> {}
public class CContainer<T>: BContainer<T> {}
public class C : CContainer<InfoC> {}
A, B and C classes are empty classes for the without making all classes generics condition (to be used in Unity)
AContainer BContainer and CContainer are added to make generic possible here.
However it does not look like a place to use generics

C# Derive From Generic Base Class (T : U<T>)

I am trying to find a way to derive a class from a generic base class. Say:
sealed public class Final : Base<Something>
{
}
public class Base<T> : T
where T : Anything // <-- Generics do not allow this
{
}
In C# this does not seem to be possible.
Is there any other solution to achieve something similar to this?
I found this StackOverflow question, but it doesn't seem to solve the issue, or at least I do not understand how it should.
EDIT:
The result I'd like to get is to be able to do something like that:
Anything[] anything;
//Assign some Instances to anything
foreach(Final final in anything){
//do something with final
}
The result I'd like to get is to be able to do something like that:
Anything[] anything;
//Assign some Instances to anything
foreach(Final final in anything){
//do something with final
}
Your foreach loop suggests this: class Anything : Final { … }.
This obviously turns around the inheritance hierarchy as you planned and named it. (You cannot have cycles in your inheritance relationships).
public class Base<T> : T where T : Anything { …
Let me elaborate on this part for a bit. I'll reduce your example even further to just class Base<T> : T.
This is not possible, for good reason. Imagine this:
class Base<T> : T
{
public override string Frobble()
{
Fiddle();
return "*" + base.Frobble() + "*";
}
}
class A
{
public sealed string Frobble() { … }
}
class B
{
}
class C
{
public virtual string Frobble() { … }
}
abstract class D
{
public abstract void Fiddle();
public virtual string Frobble() { … }
}
class E
{
public void Fiddle() { … }
public virtual string Frobble() { … }
}
You get all kinds of absurd situations if class Base<T> : T were allowed.
Base<A> would be absurd because Frobble cannot be overridden in a derived class.
Base<B> would be absurd because you cannot override a method that
doesn't exist in the base class.
Base<C> doesn't work because there is no Fiddle method to call.
Base<D> would not work because you cannot call an abstract method.
Only Base<E> would work.
How would the compiler ever know how to correctly compile Base<T> and analyse code that depends on it?
The point is that you cannot derive from a class that is not known at compile-time. T is a parameter, i.e. a variable, a placeholder. So class Base<T> : T is basically like saying, "Base<T> inherits from some (unknown) class". Class inheritance is a type relationship that requires both involved types to be known at compile-time. (Actually, that's not a super-precise statement because you can inherit from a generic type such as class SpecialList<T> : List<T>. But at the very least, the derived class has to know what members (methods, properties, etc.) are available in the base class.)
Is this what you want?
sealed public class Final : Base<int>{
}
public class Base<T> {
}
You could only do this if Final would be a generic class as well, like so:
public sealed class Final<T> : Base<T>
Then you can put a type restraint on T as either a class, to allow only reference types as T, or an instance of Base<T>, to allow only types that derive from Base<T>:
public class Base<T> where T : Base<T>
I don't know the context of this question, but I ran into same question with a project where I had to make it possible to extend the base class which is already derived by many others. Like:
abstract class Base {}
class FinalA : Base {}
class FinalB : Base {}
// Now create extended base class and expect final classes to be extended as well:
class BetterBase : Base {}
The solution was to create common ancestor and connect through properties:
abstract class Foundation {}
abstract class Base : Foundation
{
Foundation Final { get; }
}
class FinalA : Foundation {}
class FinalB : Foundation {}
class FinalC : Foundation
{
Foundation Base { get; }
}
// Here's the desired extension:
class BetterBase : Base {}
Now BetterBase has connection to final class and if needed, the final classes could have connection with (Better)Base also, as shown in FinalC class.

Generic base class with multiple children

I currently have a small object hierarchy that looks like this:
public class BaseClass {
// this class is empty and exists only so the others can extend it and share the
// same base type
}
public class ChildA : BaseClass {
public Subject<AssociatedClassA> Results;
}
public class ChildB : BaseClass {
public Subject<AssociatedClassB> Results;
}
In my design I would like to enforce that every class that extends from BaseClass should contain a Subject<SomeType> called Results. I'm wondering if there is a way that I can move Results into the base class or an interface such that I can supply the generic type for the Subject when constructing the base class. For example, it would be awesome if I could do something like this:
ChildA<AssociatedClassA> instance = new ChildA<AssociatedClassA>();
Or even better since there should really only be one template parameter that matches with ChildA if when I constructed it that could be taken care of for me:
ChildA instance = new ChildA();
// Results is automatically set to Subject<AssociatedClassA>
I'm stuck trying to implement this now as if I try to move Results into the base class the Subject requires a template parameter which I can't necessarily supply. There could potentially be more than 2 derived classes and I don't like the idea that someone extending this system has to know to add Results manually to each child class.
Following the suggestions of the 2 answers below this solves my desire to move Results into the base class, however I've run into another issue in that I was hoping to be able to use BaseClass as a generic parameter to methods such that any of the derived classes could be used. For example:
public void ProcessBaseClass(BaseClass base) {
// base could be ChildA or ChildB here
}
This no longer works since BaseClass now requires a type argument. Is there any way that I can have the best of both worlds here or am I stuck due to my design choices?
If appropriate, you can make the parent generic:
public class BaseClass<T> {
public Subject<T> Results;
}
public class ChildA : BaseClass<AssociatedClassA> {
}
public class ChildB : BaseClass<AssociatedClassB> {
}
You can make the base class itself generic:
public class BaseClass<T> {
public T Results { get; protected set; }
}

C# abstract class static field inheritance

I feel like I skipped a C# class or two, but here's my dilemma:
I have an abstract class from which I derive multiple child classes.
I know for sure that for each of the child classes I will have a constructor that needs a certain static object as a model and this object will be different for each of the child classes.
My first approach was to make a public static object in the abstract parent class and then, before I start creating any instances of the child classes, I would modify it for each of them, but it turns out that this way I actually make only ONE static object, for the abstract class, and each of it's child classes uses it.
How could I solve the problem?
To be more exact, here is the pseudocode:
The parent abstract class:
abstract class AbstractClass
{
static public ModelObject Model;
...
}
One of the child classes:
class Child : AbstractClass
{
...
public Child()
{
this.someField = Model.someField;
}
}
EDIT:
The Model needs to be a member of the "ModelObject" class, it should NOT be a singleton or anything else.
EDIT2:
To be even more exact, i chose this implementation for a game of chess: I have an abstract class for the chess pieces and the child classes represent the concrete pieces of the game: pawns, knights, et cetera.
The abstract class inherits from MeshMatObject, a class that represents generic 3d objects with the basic functionality, like rotations, meshes, materials, textures and so on and it defines abstract methods for chess game pieces, like GetPossibleMoves().
The Model object I was talking about above is a member of the MeshMatObject and, in my opinion, should be defined outside the class just once and then used for all the pieces. I mean: for example all the pawns have the same mesh and texture, so I don't see the point of giving a model as a parameter every time you want to make a pawn.
You can get around the shared static field by making your Abstract class generic. Each generic class will get it's own copy of the static fields.
abstract class AbstractClass<T>
{
static public ModelObject Model;
...
}
Then each child class will use a different instance of the static field.
class Child : AbstractClass<Child>
{
...
public Child()
{
this.someField = Model.someField;
}
}
It doesn't matter that AbstractClass doesn't reference the generic parameter. You are only using it to give each child class a unique instance of the base class.
I tend to use something similar to #shf301's solution. Depending on your needs it may useful to setup the base class as:
abstract class AbstractClass
{
}
abstract class AbstractClass<TModel> : AbstractClass
where TModel : ModelObject
{
static public TModel Model;
...
}
This allows me a common base class that I can work with in non-generic functions. This also allows derived types to choose the exact model type and can cut down on casting.
How about a factory to decouple your classes from an inherited Model:
public static class ModelObjectFactory
{
public static ModelObject GetModel<T>(T obj)
{
// return ModelObject according to type of parameter
}
}
class Child
{
public Child()
{
ModelObject mo = ModelObjectFactory(this);
this.someField = mo.someField;
}
}

Generic contraints on derived classes

I have class A:
public class ClassA<T>
Class B derives from A:
public class ClassB : ClassA<ClassB>
Class C derives from class B:
public class ClassC : ClassB
Now I have a generic method with constraints
public static T Method<T>() where T : ClassA<T>
OK, now I want to call:
ClassC c = Method<ClassC>();
but I get the compile error saying:
Type argument 'ClassC' does not inherit from or implement the constraint type 'ClassA<ClassC>.
Yet, the compiler will allow:
ClassB b = Method<ClassB>();
My understanding is that this fails because ClassC inherits ClassA<ClassB> instead of ClassA<ClassC>
My real question is, is it possible to create a class deriving from ClassB that can be used in some way with the generic method?
This may seem like generics are overused and I would agree. I am trying to create business layer objects deriving from the subsonic data objects in a separate project.
Note: I have put the < T > with extra spaces otherwise they get stripped from the question.
Well, you could change Method to:
public static T Method<T,U>() where T : ClassA<U> where U : T
Does that help at all? It's not much use if you can't change Method of course...
No. You must change or wrap this method.
Here is the reason.
ClassC inherits from ClassB which inherits from ClassA(ClassB)
ClassC does not inherit from ClassA(ClassC)
No child of ClassB will inherit from ClassA(child class), because they instead inherit from ClassB and ClassB does not inherit from ClassA(child class).
Generic types are invariant.
In most cases it is possible to solve this scenario by having a base non-generic abstract class:
public abstract class BasicClassA
{
}
public class ClassA<T> : BasicClassA
{
}
public class ClassB : ClassA<ClassB>
{
}
public class ClassC : ClassB
{
}
public static T Method<T>() where T : BasicClassA
{
return null;
}
Your mileage may vary, though.

Categories

Resources