如何使用接口和c#重写一个用抽象类编写的程序?

本文关键字:抽象类 一个 程序 接口 何使用 重写 | 更新日期: 2023-09-27 18:14:48

下面的c#程序是使用抽象类编写的:

dBase.cs

using System;
namespace nmsD
{
    public abstract class dBase
    {
        protected string s_dBase { get; set; }
        protected abstract void methodX();
        public dBase()
        {
            Console.WriteLine("Construc_dBase");
        }
        public void Dq1 ()
        {
            string s = s_dBase;
            Console.WriteLine("Dq1" + " : " + s);
            methodX();
        }
    }
}

bBase.cs

using System;
using nmsD;
namespace nmsB 
{
    public abstract class bBase: dBase
    {
        public bBase()
        {
            s_dBase = "Prop.bBase.01";
            Console.WriteLine("Construc_bBase");
        }
        protected override void methodX(){
            Console.WriteLine("--->bBase_methodX (NOT SHOW)");
        }
    }
}

bRegular01

using System;
using nmsD;
namespace nmsB 
{
    public class bRegular01 : bBase
    {
        public bRegular01()
        {
            Console.WriteLine("Construc_bRegular01");
            //s_dBase = "Prop.bRegular02.02";
        }
        protected override void methodX()
        {
            Console.WriteLine("--->bRegular01_methodX (OK)");
        }
    }
}

bRegular02

using System;
using nmsD;
namespace nmsB 
{
    public class bRegular02 : bBase
    {
        public bRegular02()
        {
            Console.WriteLine("Construc_bRegular02");
            s_dBase = "Prop.bRegular02.02";
        }
        protected override void methodX()
        {
            Console.WriteLine("--->bRegular02_methodX (OK)");
        }
    }
}

Program.cs

using System;
using nmsB;
namespace nmsApp
{
    class Program
    {
        static void Main(string[] args)
        {
            nmsB.bRegular01 br01 = new nmsB.bRegular01();
            br01.Dq1();
            nmsB.bRegular02 br02 = new nmsB.bRegular02();
            br02.Dq1();
            Console.ReadKey();
        }
    }
}

输出为:

    Construc_dBase
    Construc_bBase
    Construc_bRegular01
    Dq1 : Prop.bBase.01
    --->bRegular01_methodX (OK)
    Construc_dBase
    Construc_bBase
    Construc_bRegular02
    Dq1 : Prop.bRegular02.02
    --->bRegular02_methodX (OK)

问题是:

如果可能的话,如何使用接口实现相同的行为?获得这个结果的最佳方法是什么?,为什么?

编辑:

非常感谢你的回答。基于第一个答案,为了更好地理解,主要目标是:当从Dq1调用methodX()方法时。输出必须只显示以下行:

--->bRegular01_methodX (OK)
or
--->bRegular02_methodX (OK)

和not必须show de line:

--->bBase_methodX (NOT SHOW)

如何使用接口和c#重写一个用抽象类编写的程序?

抽象类和接口不是一回事,所以你不可能有完全相同的行为。

接口只是一个契约,强制要求继承者必须拥有指定的方法和属性。接口不能有任何实现细节。

抽象类是不能被实例化的类,因此必须从它继承才能成为一个实际的对象。如果你想让基类中的函数不需要在子类中显式覆盖就能工作,那么你就不能使用接口。

最明显的例子就是构造函数。接口不定义方法的实现,所以如果不显式地编写控制台,从接口继承的东西将无法输出"Construc_dBase"行。在每个类的构造函数中使用WriteLine语句。

使用您提供的代码,最接近的方法是创建以下接口:

public interface ISomeInterface
{
    void methodX();
    string s_dBase { get; set; }
}

. .然后在每个子类(不是基类)上继承该接口。

首先我将解释为什么,然后我将解释为什么它是不受欢迎的。

原因:

抽象方法在行为上与接口方法相同。它们定义了一个没有实现的签名,并且要求重写签名,否则程序将无法编译。你发布的代码中唯一符合模板的部分是methodX函数和string属性。因此,您可以将它们拉到一个接口中。但是,一旦这样做了,就必须在每个需要能够被解释为ISomeInterface的类上实现它们(即需要能够在不知道实现的情况下调用methodX)。继承基类上的接口意味着基类必须自己实际实现它们,这看起来是你不想做的。

为什么不受欢迎?

您现在不仅要继承基类,还要继承接口,以确保完全的互操作性。如果这对你来说不是太麻烦,那么你可以这么做,但这似乎是不必要的。此外,不再保证nmsD也是一个ISomeInterface,除非您在nmsD类上显式地提供methodX和s_dBase的实现,而这似乎正是您不想做的。此外,接口不定义可访问性约束(public、private、protectec、internal),而抽象类可以。

为什么有争议?

做事有不同的方法,每种方法都有其优点和缺点。抽象类将您束缚在单一的基实现上,而接口则不然。接口根本不能提供实现细节,而抽象类可以。

这可能会进入一个非常偏离主题和非常冗长的讨论,所以我将在这里结束。

接口可以定义方法和属性签名,但没有实现。您可以将抽象类的签名更改为接口,将所有实现移动到继承的具体类。

抽象类和接口为两个不同的问题提供了解决方案,对于每个给定的场景,一个不可能和另一个一样好。如果你需要更多的帮助,请提供更多的信息。

下面是所提供的类的实现,使用接口和程序的输出。我尽量不弄乱类的命名。

输出:

Construc_bRegular01
Dq1: Prop.bRegular01.01
--->bRegular01_methodX (OK)
Construc_bRegular02
Dq1: Prop.bRegular02.02
--->bRegular02_methodX (OK)

代码:

namespace nmsD
{
    public interface IdBase
    {
        string s_dBase { get; set; }
        void methodX( );
        void Dq1( );
    }
}
namespace nmsB
{
    using nmsD;
    public class bRegular01 : IdBase
    {
        public bRegular01( )
        {
            Console.WriteLine( "Construc_bRegular01" );
            s_dBase = "Prop.bRegular01.01";
        }
        public string s_dBase { get; set; }
        public void methodX( )
        {
            Console.WriteLine( "--->bRegular01_methodX (OK)" );
        }
        public void Dq1( )
        {
            Console.WriteLine( "Dq1: {0}", s_dBase );
            methodX( );
        }
    }
    public class bRegular02 : IdBase
    {
        public bRegular02( )
        {
            Console.WriteLine( "Construc_bRegular02" );
            s_dBase = "Prop.bRegular02.02";
        }
        public string s_dBase { get; set; }
        public void methodX( )
        {
            Console.WriteLine( "--->bRegular02_methodX (OK)" );
        }
        public void Dq1( )
        {
            Console.WriteLine( "Dq1: {0}", s_dBase );
            methodX( );
        }
    }
}

namespace nmsApp
{
    internal class Program
    {
        private static void Main( string[ ] args )
        {
            nmsB.bRegular01 br01 = new nmsB.bRegular01( );
            br01.Dq1( );
            nmsB.bRegular02 br02 = new nmsB.bRegular02( );
            br02.Dq1( );
            Console.ReadKey( );
        }
    }
}