How to inherit from base class - c#

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.

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 write a class that can encompass other related classes?

Is it possible to write a class that acts like the super class of two other classes.
For example I have class A and class B. A and B share similar properties, but since I did not code A or B they do not extend an interface or class. Is it possible for me to create this super class so that when I generalize my code it can handle class A or B.
If this super class could be created this is some of what I would like to do in my class
class A
{
string Name { get; set;}
//does stuff
//I can't change this class
}
class B
{
string Name { get; set;}
//does similar stuff
//I can't change this class either
}
class MyClass
{
//I would like to create a list that can include both class B and class A
List<(pseudo superclass of A and B)> list;
//Both class A and class B have a name, I would like to get the name given a type of A or B
public (pseudo superclass of A and B) GetName((pseudo superclass of A and B) AorB)
{
//Write that name to the console
Console.WriteLine(AorB.Name);
}
}
Is this kind of wrapping possible, or will I need to do more work inside of MyClass (such as overloading methods) in order to accomplish what I need.
I'd suggest,
1 Create an interface:
interface IWrapper
{
string Name { get; set; }
...
}
2 Create wrapper classes:
class WrapperA : IWrapper
{
private A _a;
public WrapperA(A a) { _a = a; }
public Name
{
get { return _a.Name; }
set { _a.Name = value; }
}
// other properties here
}
and likewise for a BWrapper around B.
Then you can create your class as:
class MyClass
{
List<IWrapper> list;
public string GetName(IWrapper aOrB)
{
Console.WriteLine(aOrB.Name);
}
}

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.

Inheritance: possible to change base reference to something else?

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

Categories