实例化一个抽象类?

时间:2012-12-14 02:20:57

标签: c#

public abstract class T
{
    public abstract IEnumerable<T> MakeOneMove();

    public IEnumerable<T> MakeOneMove(string evt)
    {
        List<T> returnList = new List<T>();
        IEnumerable<T> steps = MakeOneMove();
        foreach (T step in steps)
        {
            if (step.Event == evt)
            {
                returnList.Add(step);
            }
        }
        return returnList;
    }

以及其他地方的类使用如下:

            T currentImpl = pendingImpl.Pop();

            IEnumerable<T> nextImpl = currentImpl.MakeOneMove();
            foreach (ConfigurationBase next in nextImpl){

            }

我对两件事感到困惑。看起来T类正在实例化,但T类是一个抽象类。我以为这是不可能的。我认为只有抽象类的非抽象子类才能被实例化。此外,在类中,调用了makeonemove(),但是不是没有被覆盖的参数的版本,因此没有定义?在我看来,这个代码不应该编译,但确实如此。

3 个答案:

答案 0 :(得分:2)

  

我对两件事感到困惑。好像是T级   instanced,但是T类是一个抽象类。我以为这不是   可能。我以为只有子类可以实例化。

abstract class T没有被实例化,而只是指向abstract class的具体实现的指针。

  

另外,在   class,makeonemove()被调用,但不是没有的版本   参数没有被覆盖?在我看来,这样的代码不应该   编译,但确实如此。

这是使用抽象类的好处之一。它允许您提供其成员的“base”实现,可以在派生类中重写。

答案 1 :(得分:0)

不,班级T是抽象的。在方法中调用T currentImpl = pendingImpl.Pop(); T只是意味着返回的对象将是一个派生自T的类型,它有效地建立(声明)名为currentImpl的变量的类型,而不是类型对象本身。

要实例化的对象的实际类型将是pendingImpl.Pop()创建的任何类型。看起来Pop()就是所谓的工厂方法。您必须查看它是如何实现的,以确切地查看实例化和返回的类型。

答案 2 :(得分:0)

不,T只是意味着该类必须可以转换为T(即它可以转换为T并且可以转换为T)。

我建议在这里查看继承: http://www.csharp-station.com/Tutorial/CSharp/lesson08

这里是关于铸造的: http://csharp-station.com/Tutorial/CSharp/Lesson22

基本上如果一个类继承了另一个类,它可以被强制转换为类的一个实例,因此被视为该类的转换。

所以说我创建了一个继承自T的H类,然后将其转换为T,在该演员的持续时间内,H基本上被伪装成T并且你只能访问它从T继承的元素。所以说我给了H一个名为'MakeTwoMoves'的函数,然后创建了一个名为'hi'的H实例(例如H hi = new H();)我可以调用MakeOneMove和MakeTwoMoves。然而,一旦它被转换为T(例如(T)H),你就不再可以访问MakeTwoMoves,因为它没有在T中声明,它是H独有的东西。

这对您的代码意味着,pendingImpl很可能包含从T继承的类的实例数组(如我的示例中的H)。然后将它们转换为pop方法(或者可能更早,即放入内部数组之前)并以T形式出现,因此每个实例可能是一个完全不同的类,但你唯一知道的是它们继承自吨。

我希望稍微清楚一点,T不是最直观的名称。