抽象类中嵌套抽象类的实现方法及其应用

4

我有一个抽象类A和一个抽象方法,该方法的参数又是同一抽象类A中定义的抽象类B。当我将该抽象类A作为另一个类C的一部分进行扩展时,如何实现具有嵌套抽象类参数的方法。

public abstract class A<T, V>
{
    public abstract int GetObject(T t, V v);
    public abstract int GetAnotherObject(B b);
    public abstract class B{}
}

这个类被另一个类C继承

public class C: A<ABC, DEF>
{
        public C()
        {

        }
        public override int GetObject(ABC abc, DEF def)
        {
            return 10;
        }

        public override int GetAnotherObject(B b)
        {
            return 15;
        }
}

如何实现一个带有一些属性的B类,并将其传递给GetAnotherObject方法。请问有人可以帮我吗?

感谢大家帮助我解决这个问题。 - KDKR
3个回答

4

来自ECMA:

在泛型类声明或泛型结构声明(§25.2)中嵌套的任何类本身都是一个泛型类声明,因为必须提供包含类型的类型参数以创建构造类型。

因此,如果不为A提供类型参数,就无法实现嵌套的B

void Main()
{
    var c = new C();
    var result = c.GetAnotherObject(new BImpl<string, int>());
}

public class BImpl<T, V> : A<T, V>.B
{
    public override int BM()
    {
        return 1;
    }
}

// Or you can supply type arguments right here
//public class BImpl : A<string, int>.B
//{
//  public override int BM()
//  {
//      return 1;
//  }
//}

public abstract class A<T, V>
{
    public abstract int GetObject(T t, V v);
    public abstract int GetAnotherObject(B b);
    public abstract class B
    {
        public abstract int BM();
    }
}

public class C : A<string, int>
{
    public C()
    {

    }

    public override int GetObject(string abc, int def)
    {
        return 10;
    }

    public override int GetAnotherObject(B b)
    {
        return b.BM();
    }
}

它抛出一个错误,说类没有实现继承的抽象成员,因为类B在C中从未定义,我想知道如何克服这个问题。 - KDKR
我还有一个疑问,如果在BImpl中定义了一些新属性,并且我想在GetAnotherObject()中访问它们怎么办? - KDKR
@KDKR,如果您不将BImpl类型提供给GetAnotherObject,就无法这么做。或者您可以进行强制转换,但那样的话,使用B抽象又有什么意义呢? - aush
我抽象化B的基本原因是根据不同情况下的需求,向方法GetAnotherObject传递可变数量的参数。 - KDKR
我不认为我理解你的意思。你打算如何通过编程来变化参数数量以抽象B?总的来说,你的代码对我来说有点过于复杂,我不认为你实际上有一个需要如此复杂解决方案的问题,但我不知道你试图解决的问题。也许你应该尝试阐明你想要实现什么,创建一个新的问题并寻求设计解决方案,而不是技术解决方案。 - aush
当然,@aush,我会发布一个新问题。不过还是谢谢你回答我的问题。 - KDKR

2

你已经非常接近了。

public class C<ABC, DEF> : A<ABC, DEF>
{
    public C()
    {

    }
    public override int GetObject(ABC abc, DEF def)
    {
        return 10;
    }

    // since B is a nested class of A, it has no scope outside of A
    // outside of the definition of A, it must always be referred to as A.B
    public override int GetAnotherObject(A<ABC,DEF>.B b)
    {
        return 15;
    }
}

public class D : A<ABC,DEF>.B
{
    // implementation of A.B
}

请记住,C 总是需要精确地使用 A.B。您将永远无法定义一个 A.B 的实现(我们称其为 D),并使 C 的方法签名引用该覆盖。在 A 中定义的 GetAnotherObject 接受一个 A.B,因此必须实现接受任何 A.B,而不是某个特定的 A.B 实现。
关于您在如何在 C 中实现 A.B 的评论:
C 中实现 A.B 没有意义。 C 仍然必须在其方法签名中使用 A.B。但如果您真的必须这样做,出于某种原因。
public class C<ABC, DEF> : A<ABC, DEF> 
{
    // C's implementation of A

    public override int GetAnotherObject(A<ABC,DEF>.B b)
    {
        return 15;
    }

    public class D : A<ABC,DEF>.B
    {
        // implementation of A.B
    }
}

请注意,GetAnotherObject仍然需要一个A.B参数,而不是D

我同意你所说的,但问题在于它抛出了一个错误,说类C没有实现继承的抽象成员。我的主要目标是在传递给GetAnotherObject之前定义一些B的属性。 - KDKR
正如@aush所指出的,A必须始终使用类型参数进行声明。因此,在我的示例中我过于简化了B的定义,实际应为A<ABC,DEF>.B - Richard P

0

怎么样?

public class C<ABC, DEF> : A<ABC, DEF>
{
    public C()
    {

    }
    public override int GetObject(ABC abc, DEF def)
    {
        return 10;
    }

    public override int GetAnotherObject(B b)
    {
        return 15;
    }
}

只需在类名后面加上泛型。


我的关注点是,在实现具有某些属性的抽象成员类B并将其传递到GetAnotherObject方法时,我遇到了一个错误。我想知道如何在类C中准确实现抽象类B,并将其作为参数传递给GetAnotherObject。 - KDKR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接