So I have a maybe naive question about object inheritance and constructors. Basically, a class has an object:
public class ParentClass{
protected Parent item;
And the accessor goes as follows:
public Parent ItemValue
{
set
{
item = value;
}
get
{
return item;
}
}
Now I want to inherit the class:
public class ChildClass:ParentClass
{
public new Child item;
}
Now, whenever I access the Child item
through the inherited accessor it, of course, returns the item as the Parent
class instead of Child
class. Is there a way to make it return the item
as Child
class without overwriting the accessor in the ChildClass
?
No, you can't change type of base property to return different (derived) type.
Standard workaround if you don't need inheritance - generic class:
public class ParentClass<T> {
public T ItemValue { get; set; }
...
}
public class ChildClass : ParentClass<ChildClass>
{
...
}
Note that if you just need access to item in its own class you can just have virtual
property:
public class Parent { }
public class Child:Parent { public string ChildProperty; }
public abstract class ParentClass
{
public abstract Parent ItemValue { get; }
}
public class ChildClass : ParentClass
{
Child item;
public override Parent ItemValue { get {return item;} }
public void Method()
{
// use item's child class properties
Console.Write(item.ChildProperty);
}
}
If you are just wanting to have Item of a type defined by your descendent class, you can do this
public class ParentClass<T>{
protected T item;
public T ItemValue
{
set
{
item = value;
}
get
{
return item;
}
}
}
public class ChildClass:ParentClass<Child>
{
// No need to create a new definition of item
}
However depending on your problem, your next question will be how can I add ChildClass1 and ChildClass2 to the same List/Array/Dictionary/etc when they have different T's.
Take a step back for a minute. Does your ParentClass really need to know what item is?
(Ab)Using the Animal example above, your Horse might have a Walk(), Trot(), Canter() or Gallop() methods but a Duck might have a Swim() or Waddle() methods.
Perhaps your logic says something like, iterate my animal collection and tell the swimmers to swim. In this case, you could declare:
using System;
using System.Collections.Generic;
public class Program
{
public class Location {}
public interface ISwimmer{
void SwimTo(Location destination);
}
public class Animal {} // whatever base class properties you need
public class Duck : Animal, ISwimmer
{
public void SwimTo(Location destination)
{
Console.WriteLine("Implement duck's swim logic");
}
}
public class Fish : Animal, ISwimmer
{
public void SwimTo(Location destination)
{
Console.WriteLine("Implement fish's swim logic");
}
}
public class Giraffe : Animal {}
public static void Main()
{
List<Animal> animals = new List<Animal>
{
new Duck(),
new Fish(),
new Giraffe()
};
foreach (Animal animal in animals)
{
ISwimmer swimmer = animal as ISwimmer;
if (swimmer==null) continue; // this one can't swim
swimmer.SwimTo(new Location());
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.