Inheritance: possible to change base reference to something else? - c#

For example I have two classes, Base and Derived as shown below:
class Base
{
public string Name { get; set; }
public Base()
{
}
}
class Derived : Base
{
public Derived(Base b)
{
base = b; // doesn't compile, but is there any way to do something similar?
}
}
So that they behave like this:
Base b = new Base();
b.Name = "Bob";
Derived d = new Derived(b);
d.Name = "John";
// b.Name is now "John" also
Is this possible? I guess one way would be to keep the Base b reference in Derived and override Derived.Name to point to b.Name? Is there an easier way though, for example if I have like 50 properties to override?
class Derived : Base
{
Base b;
public override string Name
{
get { return b.Name; }
set { b.Name = value; }
}
public Derived(Base b)
{
this.b = b;
}
}
EDIT:
I guess another way to say it would be that I am creating a sort of wrapper for class Base. I am given an object of type Base and want to wrap it with class Derived but still keep Base's original public properties/methods/etc. I'm not sure if that makes it more clear or not.

I think from what you seem to be hinting at ( atleast from the edit - "I am creating a sort of wrapper for class Base"), you are looking at using the Decorator pattern:
http://en.wikipedia.org/wiki/Decorator_pattern
The decorator pattern can be used to extend (decorate) the
functionality of a certain object at run-time, independently of other
instances of the same class, provided some groundwork is done at
design time. This is achieved by designing a new decorator class that
wraps the original class.

Guess I'm confused
public BaseClass
{
public string Name { get; set; }
}
public DerivedClass : BaseClass
{
}
DerivedClass d = new DerivedClass();
d.Name = "Test";
BaseClass b = d as BaseClass;
print b.Name;
Output:
Test
The derived object inherits the methods, properties, fields and constructors(to some extend) of the base class, why override them when you can just use them.

Have you heard of the Decorator Pattern? http://en.wikipedia.org/wiki/Decorator_pattern
It's a way of dynamically modifying behavior at runtime by wrapping instances of classes within themselves like Russian Dolls. They all implement the same interface so to the user of the class the wrapped and unwrapped versions appear the same.
Interface IDecorator{
public void foo();
}
public class OuterDecorator:IDecorator{
private IDecorator _inner;
public OuterDecorator(IDecorator inner){
this.__inner = inner;
}
public void foo(){
this._inner.foo();
Console.Writeline("Hello from outer");
}
}
public class InnerDecorator:IDecorator{
public void foo(){
Console.Writeline("Hello from inner");
}
}
You can make a static function be a Factory Method.
public static IDecorator GetDecorator(){
var inner = new InnerDecorator();
var outer = new OuterDecorator(inner);
return outer;
}
And use it like so. The advantage is that the consumer of this class doesn't need to know the implementation details of the concrete class doing the work. Since both InnerDecorator and OuterDecorator implement the same interface they can be used interchangeably.
IDecorator d = OuterDecorator.GetDecorator();
d.foo();
//Output
//Hello from Inner
//Hello from Outer

here's some more information on the decorator pattern:
HeadFirst Design Patterns - start here
DoFactory

Related

Calling an implemented function of child instance from abstract parent class in C#

Here it is:
abstract class IA
{
public virtual void ChangePropertyOfAIChild()
{
b.value = true;
}
}
...
class B:IA
{
bool value;
}
class C:IA
{
bool value;
}
....
///main
IA newBInstance = new B();
newBInstance.ChangePropertyOfAIChild();
IA newCInstance = new C();
newCInstance .ChangePropertyOfAIChild();
/////
What would be a proper way of calliing an already implememnted function in a child's class from the base abstract class and changing it's value?
Thanks!
As #Camilo Terevinto pointed out, you heirarchy is wrong. try:
public abstract class IA
{
public bool value;
public virtual void ChangePropertyOfAIChild()
{
value = true;
}
}
public class B : IA
{ }
public class C : IA
{ }
// in main
IA newBInstance = new B();
newBInstance.ChangePropertyOfAIChild();
IA newCInstance = new C();
newCInstance.ChangePropertyOfAIChild();
///
Your sample code had the base abstract class trying to change the value of a field in a class it doesn't know about:
(b.value = true)
For the base class to be able to do this, the field needs to be declared inside the base class.
I believe you have't got your inheritance quite right.
If this is your class implementation:
public abstract class IA
{
}
public class B : IA
{
public bool value;
}
public class C : IA
{
public bool value;
}
And then if you create an instance of IA like so:
IA newBInstance = new B();
Then compiler goes ahead and creates an instance of IA. Since your IA does NOT have a property called value, you cannot access it.
You have two options, either use the method suggested by CodexNZ in the previous reply, or simply cast your newInstance to B and directly set value. Like this:
IA newBInstance = new B();
((B)newBInstance).value = true;
However this is counter intuitive since if you can do that you might as well create an instance of B in the first place. So I recommend the previous method. This is more to explain why your logic doesn't work.
Please refer to a tutorial like this to learn more. There are tons of more resources on the internet.

Using the constructor of the base class when creating new object of derived class?

Public class A
{
...
}
Public class B:A
{
...
}
Public class Prog
{
public static void Main()
{
A myA = new B();
}
}
If myA is an instance of A class, why I use B constructor, and how it differ from this:
A myA = new A();
also this code may be closer to this issue:
I know this may be very basic question, but I'm really confused.
You don't have to use the B constructor, only if you want an instance of B that inherits A.
You can also setup B so that is calls the constructor of A for you, eg:
public class A
{
public A()
{
}
}
public class B : A
{
public B() : base()
{
}
}
It all entirely depends on the implementation of your A and B classes and what you want to use them for.
Edit:
In light of your image, the reason you are calling like Vehicle c = new Car() is because the object you are actually creating is a Car but you still want or need to use aspects of the base class. Having this base class means you can have common properties between implementing classes.
For example:
public class Vehicle
{
public Vehicle()
{
}
public int NumberOfWheels { get; set; }
}
public class Car : Vehicle
{
public Car() : base()
{
NumberOfWheels = 4;
}
}
public class Motorbike : Vehicle
{
public Motorbike() : base()
{
NumberOfWheels = 2;
}
}
This case allows you to only define NumberOfWheels once and just set the value appropriately for the implementation you are writing. You can do the same thing with methods using virtual methods.
A myA = new B();
This is creating an object of type B. It is not creating an object of type A. However, you are casting the object to A. Casting in layterms essentially means you are saying 'View this object as if it were an A. Ignore the fact that it may be a B. Only show me methods and properties which were defined in the class A).
Note that you can re-cast it back to B, which does not change the object whatsoever:
B myB = (B)myA;
The difference between this:
A myA = new A();
and this:
A myA = new B();
Is that the first statement is creating a physical object of type A. Any overrides or new method/properties/fields defined in B will not be created. The second statement will create a physical object of type B, but to view it (even temporarily) as an A

How to inherit from base class

Hi My code is as follows
public partial class Class1:InheritBase1
{
public Class1()
{
//Access table1 here
}
}
public class InheritBase2
{
protected DataTable table1{get;set;}
}
I need to access table1 from InheritBase2 class to my class.
As C# doesn't allow multiple inheritance what are the possible ways to achieve this ?
Thank's all.
You could easily solve this using composition instead of inheritance.
Say there's a class A and a class B. A has a B.
public class A
{
public B AssociatedB { get; set; }
}
Why...?
could you please elaborate – kyle
In object-oriented programming there're two approaches to create relationships between objects. Either of them are necessarily hierarchical.
If you end up thinking some object is something, we'll be talking about inheritance. For example, a cat is an animal. That is, a class cat derives from animal.
In the other hand, if you end up thinking some object has a X thing, we'll be talking about composition. For example, a car has an engine.
At the end of the day, if you are using inheritance in order to share a reference to a DataTable, I really encourage you to use composition instead, because your class has a DataTable:
public class A
{
public DataTable Table { get; set; }
}
public class B
{
public DataTable Table { get; set; }
}
DataTable someTable = new DataTable();
// Both class instances share the same DataTable
// because you set the same object to both
// class properties
A someA = new A();
someA.Table = someTable;
B someB = new B();
someB.Table = someTable;
You can benefit form the composition.
class A : B {
}
can be replaced as
class A {
B b
}
If you want that A and B can be used in the same contenxt you need to intruduce a interface.
The interface allow you to define abstract functionality and have various implementations for it.
interface ISampleInterface
{
void SampleMethod();
}
In case when we have
class B : ISampleInterface
{
void SampleMethod() {
//Do some action
}
}
Now your class A can or inherit form B in odrder to access to sample method or use composition.
class A : ISampleInterface {
B b;
void SampleMethod() {
b.SampleMethod();
}
}
Then i code you can use this like
ISampleInterface sa = new A();
ISampleInterface sb = new B();
sa.SampleMethod(); //Call B through A
sb.SampleMethod(); //Call B
This is only bired description for more you should follow a tutorial about Object Oriented Programming.

Is it possibly to impose type constraints on a generic member of a class in an inheritance hierarchy?

I'm writing an application in C#, and am wrestling with its implementation of generics. I have an inheritance hierarchy that is mirrored by another inheritance hierarchy (Models and View Models) like so:
class A_Content { }
class B_Content : A_Content
{
public string Bar;
}
class C_Content : A_Content
{
public string Foo;
}
class A { public A_Content content; }
class B : A { }
class C : A { }
public class Test
{
IList<A> A_Collection = new List<A>();
public Test()
{
B b = new B();
C c = new C();
b.content = new B_Content();
c.content = new C_Content();
A_Collection.Add(b);
A_Collection.Add(c);
}
}
This works well enough, but doesn't enforce any type constraints on content, which leaves me casting it to the proper derived class every time I want to use it. I'd like to coax the compiler into enforcing the constraint that B objects only have B_Content content. My first cut at that was:
class A_Content { }
class B_Content : A_Content
{
public string Bar;
}
class C_Content : A_Content
{
public string Foo;
}
class A { }
class B : A { B_Content content; }
class C : A { C_Content content; }
public class Test
{
IList<A> A_Collection = new List<A>();
public Test()
{
B b = new B();
C c = new C();
A_Collection.Add(b);
A_Collection.Add(c);
}
}
This works nicely, but means that I can't access the common elements of content when all I have is a collection of As. What I'd really like to do is something like:
abstract class A_Content { }
class B_Content : A_Content
{
public string Bar;
}
class C_Content : A_Content
{
public string Foo;
}
abstract class A<T> { T content; }
class B : A<B_Content> { }
class C : A<C_Content> { }
public class Test {
IList<A<A_Content>> A_Collection = new List<A<A_Content>>();
public Test()
{
B b = new B();
C c = new C();
A_Collection.Add(b);
A_Collection.Add(c);
}
}
This, however, produces an error complaining that B cannot be implicitly converted into an A. I've tried adding an explicit cast to no avail. Is there some way to express the constraints I'm looking for more elegantly than the second model?
It's not entirely clear what you're after. Are you trying to make it so that every instance of A has a Content property whose type is A_Content, every B has a Content property that's a B_Content, and so on? If so, you can't do that and have B/C/etc. inherit from A. (not in a non-smelly way, anyway). The signature of A says that the Content property should be able to get (and, presumably, set) any valid value of A_Content. You cannot change the return type of a function or the type of a property or field in a derived class. You could use generics to basically defer the typing of the property all the way down to the usage of the class, but that syntax will be ugly and I'm not certain what it gets you.
For example, you could do this:
public class A<TContent> where TContent : A_Content
{
public TContent Content { get; set; }
}
public class B<TContent> : A<TContent> where TContent : B_Content
{
// nothing here, as the property is already defined above in A
}
public class C<TContent> : A<TContent> where TContent : C_Content
{
// nothing here, as the property is already defined above in A
}
But this means two things:
Anywhere you use A, B, or C you must specify the actual type of TContent (so A_Content, B_Content, etc.). Which is a pain
There is absolutely nothing stopping you from doing something like A<B_Content> (which is, in fact, essentially what B is in this case, since we've added nothing to the class).
In short, I think you need to drop back and punt and come up with a new design.
By the way
The reason your second example doesn't fly (with the List) is because you've told the list that it needs to contain A<A_Content>. Since B<B_Content> doesn't satisfy that, it won't work. This is a typical variance question and it confuses a lot of people. But consider this scenario (this code will not compile; it's intended to be demonstrative of the underlying reason):
List<A<A_Content>> list = new List<A<A_Content>>();
list.Add(new B()); // this seems OK so far, right?
A<A_Content> foo = list[0];
foo.content = new A_Content():
This would obviously break, since foo in reality is a B<B_Content>, so the runtime wouldn't let you set content equal to anything other than an instance of B_Content (or something that inherits from it), but the signature of the class means you should be able to assign anything that'sA_Content` or inherits from it.
You can use an interface for this, along with explicit implementation of the interface's member(s):
abstract class A_Content {}
class B_Content : A_Content {}
class C_Content : A_Content {}
interface IA
{
A_Content content { get; }
}
abstract class A<T> : IA
where T : A_Content
{
T content;
A_Content.content { get { return this.content; } }
}
class B : A<B_Content> {}
class C : A<C_Content> {}
Then you can make a List<IA> to hold a homogeneous collection of B and C objects.
In fact, with C# 4 and higher, you could make the interface generic and covariant; then you can implement the interface implicitly (as long as you use a property rather than a field):
interface IA<out T>
{
T content { get; }
}
abstract class A<T> : IA<T>
where T : A_Content
{
T content { get; set; }
}
class B : A<B_Content> {}
class C : A<C_Content> {}
Now, B still cannot be converted to A<A_Content>, but it can be converted to IA<A_Content>, so you can use a List<IA<A_Content>> to hold your homogeneous collection of objects.
Well, compiler produces an error, because indeed B cannot be converted into A<A_Content>.
This is because A<A_Content> is not a superclass of B. The parent class of B class is A<B_Content>.
I am afraid you need to stick to casting. It is needed here, because you have list of As.
If you really want to avoid casting (I am not sure why you would like to), you can try with dynamic dispatch.
You can try creating a List<dynamic> instead of List<A>.
You will need at least C# 4.0, though.
Hope I right undertsood your intention, so
having a collection like this
IList<A> means that you would like to have a collection of A objects with different implementation scenarios.
That property if the property of a base type. That means that base type has to expose methods/properties => so state and behavior primitives which the child classes has to make a concrete implementation.
Something like this:
class A_Content { public virtual string Bar {get;set;} }
class B_Content : A_Content
{
public override string Bar {get;set;};
}
class C_Content : A_Content
{
public override string Bar {get;set};
}
and somewhere in the code:
public Test()
{
B b = new B();
C c = new C();
A_Collection.Add(b);
A_Collection.Add(c);
//so
A_Collection[0].Bar // B::Bar
A_Collection[1].Bar //C::Bar
}
And you do not need to cast to real object. Simple OOP approach.

I would like to override a method in C#, but I have a different signature

The base class user should access the original method
class A
public init()
The derived class user should aceess ONLY the derived method.
class B
public init(int info)
I cannot use "override" bc there's a different signature.
What options do I have so that the derived class user does not see two methods.
Notes.
All in all I just need two classes that share some code. Inheritance is not a must.
But simplicity for the user of B is a priority.
This is a big code smell (and violates some basic OOP tenets) and, to the best of my knowledge, can not be done in any language. In OOP, an instance of B is an instance of A; this is polymorphism. So if A has a public method named init accepting no parameters, then so does B.
What are you trying to do this for?
Edit: Now that you've added the edit that states that inheritance is not a must, just use composition to share code. Give B a private instance of A, for example.
According to the Liskov principle you simply cannot do that, because it would violate this principle. The best thing you can to is override init() in the derived class and make it throw an exception every time it's invoked, stating that the user should use init(int info) and rely on the test to catch the errors.
Why you can't simple replace the init() method or even make it protected?
The Liskov principle states (rephrased) that where an instance of class A is required, an isntance of class B extends A can be passed.
If a method expects A and wants to call init() on it and you pass B (which extends A) to it with a protected init() the method will fail. This is the reason why the code will not even compile.
What you're asking for is impossible, due to the nature of the type system. Any instance of B can be thought of as an A, so you can call any of A's methods (including Init()). The best you can do is overload Init() in B and throw an exception to catch this at runtime.
public class B
{
void Init()
{
throw new NotSupportedException();
}
}
Contrary to some answers/comments here, what you are asking for would have a real use if it existed:
class Derived : Base
{
This can be seen by considering the workaround:
class Derived
{
private Base _base = new Base();
In other words, it's not really a base class at all, but a hidden part of the implementation.
The downside with this workaround is: what Base has an abstract method that you have to supply? You have to write this:
class Derived
{
class ActualDerived : Base
{
// override abstract method(s)
}
private Base _base = new ActualDerived();
This is the whole point of private inheritance (as found in C++) - it's for situations when you want to inherit the implementation but not the "interface" (in the informal sense).
But in C#, it's not available.
Presumabely A and B have something in common. Can you factor that out into a different base class?
public class Base
{
... common stuff ...
}
public class A : Base
{
public void Init()
{
}
}
public class B : Base
{
public void Init(int info)
{
}
}
if you need polymorphism then references to Base or, better yet, Thomas' interface are the way to go.
Instead of inheritance, use an interface as a "middle man":
public interface IAllThatYouNeed
{
public void DoSomeStuff();
}
public class A : IAllThatYouNeed
{
public void Init() {
// do stuff
}
}
public class B : IAllThatYouNeed
{
public void Init(int info) {
// do stuff
}
}
it looks like it's not yet possible
i tried to do something like this:
public class B : A
{
private override void Init() { }
public void Init(int x)
{ }
}
but Init() it's still visible from the A class
There is no perfect solution here. Some possible ways to do it:
An approach would be to make A.Init() virtual, override it in B and make it throw a NotImplementedException/InvalidOperationException.
Init() stays visible, but the user finds out very quickly that it is not to be used (make it explicit that Init(int info) is to be used in the XML documentation and in the message of the exception).
If you don't care about the inheritance part and just want to use the functionalities of class A in class B, don't have B deriving from A and make B instantiate A and use its functionalities.
Edit:
You can use an interface implementing the common operations in order to retain inheritance while avoiding to implement Init() in B:
public interface IOperations
{
void DoStuff();
void Foo();
}
public class A : IOperations
{
public void Init()
{
// Do class A init stuff
}
#region IOperations Members
public void DoStuff()
{
// ...
}
public void Foo()
{
// ...
}
#endregion
}
public class B : IOperations
{
A _operations = new A();
public void Init(int initData)
{
_operations.Init();
// Do class B init stuff
}
#region IOperations Members
public void DoStuff()
{
_operations.DoStuff();
}
public void Foo()
{
_operations.Foo();
}
#endregion
}
This can be made even better by using a factory:
public static class OperationsFactory
{
public static IOperations CreateOperations()
{
A result = new A();
result.Init();
return result;
}
public static IOperations CreateOperations(int initData)
{
B result = new B();
result.Init(initData);
return result;
}
}
This way instantiation code is well encapsulated, the difference between the two Init() methods is hidden from the user code.

Categories