在派生类或任何其他类中是否可以调用抽象类的方法?

5

在派生类或其他类中调用抽象类的方法是否可能?我的代码如下,我想在Program的Main方法中调用Abstr的Describe()方法。这是否可能?如果是,怎么做?

class Program
{
    public void Main()
    {
        //I want to call the Describe() method here, how do i do that
        Console.ReadLine();
    }
}

public abstract class Abstr
{
    public void Describe()
    {
        //do something
    }
}

2
你真的尝试过并遇到了问题吗? - Tigran
2
如果你不断更改示例代码,那么没有人可以帮助你。同时,发布任何出现的错误文本也会有所帮助。这样可以避免我们在寻找答案时跑偏,而你拥有可以提供帮助的信息。 - Bob G
1
这不公平,我没有料到你们的网站会这样。 - Pradeep
@Pradeep - 你究竟期望什么?你有很多问题,所以这不是你第一次寻求帮助。 - Security Hound
6个回答

15

由于你的方法不是静态的,所以你需要从那个抽象类初始化一个变量并从中调用该方法。为此,你可以通过具体类继承抽象类,然后调用该方法。请注意,抽象类不能像Abstr abstr = new Abstr();这样通过构造函数进行初始化是无效的。因此:

public abstract class Abstr
{
    public void Describe()
    {
        //do something
    }
}

public class Concrete : Abstr
{
   /*Some other methods and properties..*/ 
}

class Program
{
    public void Main()
    {
        Abstr abstr = new Concrete();
        abstr.Describe();
        Console.ReadLine();
    }
}

做 Concrete abstr = new Concrete() 不是更有意义吗? - Security Hound
2
@Ramhound:我想向他展示如何初始化\使用“Abstr”实例。 - Jalal Said

4
你应该可以直接使用Abstr.Describe()。它是一个静态方法,因此抽象类不应该影响它的使用。

编辑

现在问题中的代码已被编辑,方法上的static关键字已被移除,因此这个回答不再适用。


如果它是一个非静态类,会怎样? - Pradeep
方法是静态的,因此可以在没有类实例的情况下访问。任何类都可以包含静态方法,但静态类只能包含静态方法而不能包含其他方法。 - Anders Abel
如果Main和Describe都不是静态的 - Pradeep
在您发布的代码中,MainDescribe都有static关键字,因此这些方法是静态的。 - Anders Abel
因此,我的回答已经过时了。如果您需要帮助,请确保您发布相关的代码,最好通过测试并验证您是否获得所描述的错误,然后将该精确代码复制粘贴到这里。 - Anders Abel
@Pradeep:因为我不想这样做。我在这里花费自己的、没有报酬的业余时间来帮助你,因为我喜欢帮助别人。当你改变你的问题时,我已经有足够的了。我不想再帮助你了,所以我不会继续下去。 - Anders Abel

2

问:在派生类中能否调用抽象类的方法?

答:可以,只要该方法是公共的、受保护的(且与同一类或子类相同),或者是内部的(且与同一程序集相同)。

问:其他类呢?

答:也可以,只要该方法是公共的或内部的(且与同一程序集相同)。

好的链接: http://agsmith.wordpress.com/2007/12/15/internal-and-protected/


0

只需要调用它就可以了

编辑:

原帖已更改,因此此答案无效。

 Abstr.Describe();

敬礼。


0

是的,只要超类型中的方法定义对子类型(以及想要调用该方法的代码)可访问。

这里有一些示例代码。在子类型或超类型中调用方法定义取决于如何定义覆盖:

public abstract class AbstractSupertype
{
  public void Alpha()
  {
    Console.WriteLine( "AbstractSupertype.Alpha()" ) ;
    return ;
  }
  public abstract void Bravo() ;
  public virtual  void Charlie()
  {
    Console.WriteLine( "AbstractSupertype.Charlie()" ) ;
    return ;
  }
}

public class ConcreteSubtype : AbstractSupertype
{
  public new void Alpha()
  {
    Console.WriteLine( "ConcreteSubtype.Alpha()" ) ;
  }
  public override void Bravo()
  {
    Console.WriteLine( "ConcreteSubtype.Bravo()" ) ;
  }
  public override void Charlie()
  {
    Console.WriteLine( "ConcreteSubtype.Charlie()" ) ;
  }
}
class Program
{
  static void Main( string[] args )
  {
    ConcreteSubtype   subTypeInstanceReference   = new ConcreteSubtype() ;
    AbstractSupertype superTypeInstanceReference = subTypeInstanceReference ;

    subTypeInstanceReference.Alpha()     ; // invokes subtype's method
    superTypeInstanceReference.Alpha()   ; // invokes supertype's method

    subTypeInstanceReference.Bravo()     ; // invokes subtype's method
    superTypeInstanceReference.Bravo()   ; // invokes subtype's method

    subTypeInstanceReference.Charlie()   ; // invokes subtype's method
    superTypeInstanceReference.Charlie() ; // invokes subtype's method

    return ;
  }
}

你如何调用AbstractSupertype.Charlie? - user90843
在你的子类型中,你使用 base.Charlie()。关键字修饰符 override 意味着你的子类型正在替换(特化)父类型的方法/属性,并且即使实例被向上转型,该特化也存在。相比之下,new 修饰符指定你正在替换(隐藏)父实现,并且在向上转型时,实例应该恢复到父行为。需要注意的是,当一个方法或属性被定义为 override 时,父版本将不再公开可用。 - Nicholas Carey

0

是的,这是可能的代码:这里

这也适用于非静态方法


我们能否使用 new 关键字创建抽象类的实例? :) - Pradeep
不是,但由于我进行了扩展,我可以创建自己的实例并获得所需的功能。 - Osama Javed
所以程序:lol,这样我就可以创建一个已经包含所有lol方法的程序。 - Osama Javed

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