【问题标题】:C# accessors and object class inheritanceC# 访问器和对象类继承
【发布时间】:2018-04-10 00:02:24
【问题描述】:

所以我有一个关于对象继承和构造函数的问题可能很幼稚。基本上,一个类有一个对象:

public class ParentClass{
protected Parent item;

访问器如下:

public Parent ItemValue
{
    set
    {
        item = value;
    }
    get
    {
        return item;
    }
}

现在我想继承类:

public class ChildClass:ParentClass
    {
    public new Child item;
    }

现在,每当我通过继承的访问器访问Child item 时,它当然会将项目作为Parent 类而不是Child 类返回。有没有办法让它将item 作为Child 类返回而不覆盖ChildClass 中的访问器?

【问题讨论】:

  • 无意冒犯,但您的条款全错了。例如,返回子类是什么意思?
  • 如果您必须知道ItemValueChild 而不是Parent,那么您的OOP 操作不正确。请说明你到底想做什么
  • 希望我修好了;我的意思是我想通过ChildClass继承访问器访问item并将其作为Child类对象返回,而不是Parent类对象
  • 也许,但没有“我为什么需要”这似乎是一个奇怪的问题。例如狗类,继承自动物。为什么你想让Dog.Speak 做任何狗不会做的事情?
  • 您是否正在尝试做多态性,不同实现的类似方法?

标签: c# inheritance accessor


【解决方案1】:

不,您不能更改基本属性的类型以返回不同的(派生)类型。

如果您不需要继承的标准解决方法 - 泛型类:

public class ParentClass<T> {
      public T ItemValue { get; set; }
...
}

public class ChildClass : ParentClass<ChildClass> 
{
  ...
}

请注意,如果您只需要访问它自己的类中的项目,您只需拥有virtual 属性:

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);
    }
}

【讨论】:

  • 好的,我想这回答了我的问题。
【解决方案2】:

如果您只想拥有由后代类定义的类型的 Item,您可以这样做

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
}

但是,根据您的问题,您的下一个问题是当 ChildClass1 和 ChildClass2 有不同的 T 时,如何将它们添加到同一个 List/Array/Dictionary/etc 中。

退后一分钟。您的 ParentClass 真的需要知道什么是项目吗?

(Ab)使用上面的 Animal 示例,您的 Horse 可能有 Walk()、Trot()、Canter() 或 Gallop() 方法,但 Duck 可能有 Swim() 或 Waddle() 方法。

也许你的逻辑是这样的,迭代我的动物收藏并告诉游泳者游泳。在这种情况下,您可以声明:

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());
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多