继承

时间:2016-05-12 19:20:46

标签: c# oop

如何将功能从返回基类型的基类拉入继承类?

我有一个基类Chapter和一个子类EnhancedChapter,它为Chapter添加了一些功能。

不幸的是,一个基类方法返回类类型。我可以在子类中访问此方法,但由于它返回基类型而不是子类型,因此我无法将其功能引入子类。

这里是基类(Page在其他地方实施,你可以得到图片):

class Chapter
{
    public List<Page> pages;

    public Chapter()
    {
        pages = new List<Page>();
    }

    public Chapter CalculatedChapter(DateTime date)
    {
        pages.ForEach(p => p.CalculatedPage(date));
        return this;
    }
}

这里是儿童班:

class EnhancedChapter : Chapter
{
    public int? PageCount()
    {
        if (pages != null) return pages.Count; else return null;
    }
}

现在,当我想在子类中使用CalculatedChapter()时,我遇到了问题:

EnhancedChapter enhancedChapter;
// won't work, returns Chapter not EnhancedChapter
enhancedChapter = new EnhancedChapter().CalculatedChapter(DateTime.Now);

我想到的一些选项,但这并不适合我:我可以在这里做一个演员,但这似乎容易出错。我还想过以某种方式将CalculatedChapter()的结果提供给子类构造函数,但是无法弄清楚如何做到这一点。

3 个答案:

答案 0 :(得分:1)

认为这样做会......

abstract class ChapterBase<T> where T : ChapterBase<T>
{
    public List<Page> pages;

    public ChapterBase()
    {
        pages = new List<Page>();
    }

    public T CalculatedChapter(DateTime date)
    {
        pages.ForEach(p => p.CalculatedPage(date));
        return (T)this;
    }

}

class Chapter :ChapterBase<Chapter>
{
}

class EnhancedChapter : ChapterBase<EnhancedChapter>
{
    public int? PageCount()
    {
        if (pages != null) return pages.Count; else return null;
    }
}

答案 1 :(得分:0)

如果真的需要像这样做,在考虑了不同的设计选项之后,你可以在EnhancedChapter中定义隐藏方法:

class EnhancedChapter : Chapter
{
    public int? PageCount()
    {
        if (pages != null) return pages.Count; else return null;
    }

    public new EnhancedChapter CalculatedChapter(DateTime date) {
        return (EnhancedChapter)base.CalculatedChapter(date);
    }
}

然后,如果您通过EnhancedChapter引用使用它 - 将调用此方法,否则 - 将调用此方法。

答案 2 :(得分:0)

在这种情况下,您可以使用new关键字隐藏基本实现的方法并提供修改后的版本。在那个新方法中,然后调用基本方法并将其结果转换为EnhancedChapter

因此,对于您提供的示例,您可以像这样修改EnhancedChapter类:

class EnhancedChapter : Chapter {
    public int? PageCount() {
        if (pages != null) return pages.Count; else return null;
    }

    // Note the "new" keyword, hiding the base method implementation, and the changed return type
    public new EnhancedChapter CalculatedChapter(DateTime date) {
        // Just call the method on base and cast the result
        return (EnhancedChapter)base.CalculatedChapter(date);
    }
}

修改

在这种情况下,您不需要担心铸造。这种方法基本上只是使派生类型更舒适。

如果您有其他类型派生自Chapter并使用CalculatedChapter()方法,则有2个选项:

  1. 当类型没有自己的new CalculatedChapter()方法时,基本方法实现被称为返回Chapter
  2. 当类型具有自己的new CalculatedChapter()方法时,该方法称为
  3. 即使你从EnhancedChapter派生出一个新类,它仍然只能使用基本实现(在EnhancedChapter的情况下)或者可以提供自己的实现,隐藏基本实现。

    但值得注意的是,当您在键入为Chapter的字段中使用派生类型时,则不会调用new CalculatedChapter()方法(因为您正在使用Chapter类型)。请参阅以下示例:

    // Create EnhancedChapter            
    EnhancedChapter chapEnhanced = new EnhancedChapter();
    
    // Store the enhanced chapter as Chapter
    Chapter chapEnhancedAsChapter = chapEnhanced;
    
    // This calls the "new" method on EnhancedChapter
    chapEnhanced.CalculatedChapter(DateTime.Now);
    
    // This calls the base method implementation directly
    chapEnhancedAsChapter.CalculatedChapter(DateTime.Now);
    

    在这种情况下,在第二次调用时不会进行强制转换,但这也意味着您无法在该方法中执行特定于派生类型的任何状态更改操作。例如,在向EnhancedChapter添加新属性时,您不应在new CalculatedChapter()方法中更新该属性,因为您无法确保实际使用此方法。

    所以最后这种方法只有在使用它来增加使用派生类型时的舒适度时才有效,但是当你真正改变这些不同方法中的实现细节时,你不能使用它。