gpt4 book ai didi

c# - 基类实现基本接口(interface),而派生/混凝土类实现扩展接口(interface),为什么呢?

转载 作者:太空狗 更新时间:2023-10-29 23:08:11 27 4
gpt4 key购买 nike

我正在看一本书,即《使用C#进行.NET域驱动的设计》。

问题基于以下类图中所示的方案:

数字:
http://screencast.com/t/a9UULJVW0

在此图中,

A)IRepository接口(interface)由(抽象基类)RepositoryBase实现,而

B)IRepository接口(interface)也由接口(interface)ICompanyRepository扩展(ICompanyRepository : IRepository)。

C)ICompanyRepository由CompanyRepository实现,该CompanyRepository派生自SQLRepositoryBase,SQLRepositoryBase派生自RepositoryBase(;如A点所述,该方法实现了IRepository,如果ICompanyRepository为父级,则为父级)。

D)我创建了接口(interface)ICompanyRepository的变量,该变量引用了clas CompanyRepository的对象,如下所示:

ICompanyRepository comRep = new Company Repository();

现在,如果我使用ICompanyRepository变量comRep调用Add()函数。
comRep.Add(); 

然后调用RepositoryBase类(它是CompanyRepository的父级)中的Add()函数。

我的问题:
由于调用了(抽象库)类“RepositoryBase”中的Add()函数,因此发生了确切的基础面向对象的规则/机制?为了方便起见,我在下面说明两种可能的机制:(请告诉我以下所述的两种机制中的哪一种是正确的基础机制)

机制1
是否由于“RepositoryBase”实现了IRepoitory而在基类“RepositoryBase”中调用了此Add()函数? (因此,必须强制RepositoryBase类实现IRepository才能调用Add())



机制2:
之所以调用基类“RepositoryBase”中的Add()函数,是因为CompanyRepository实现了ICompanyRepository,该公司实现了IRepository,该IRepository包含Add()函数的定义,这样,当调用ICompanyRepository(带有变量ICompanyRepository)时,它首先会找到定义在ICompanyRepository中添加,然后在父接口(interface)IRepository中添加,然后跳转到CompanyRepository类以查找Add()函数的实现,而没有找到Add()函数的定义,它向上遍历到父类SQLRepositoryBase以查找Add()函数,依此类推,并在RepositoryBase类中找到函数Add(),因此它将在RepositoryBase中调用Add()函数。这意味着,如果它将在RepositoryBase的任何派生类中找到Add()函数,则它不会进一步向上移动(在父类中)。所有这些还意味着,为了在类链中从派生类遍历到父类只是为了查找Add()函数,RepositoryBase类真的不需要直接从IRepository继承吗?

我的问题还有其他问题,如下所述,我无法理解哪种OO-Rule适用于我的情况:

在我的问题中,有两个接口(interface),一个是父级,即IRepository,另一个在扩展它,即ICompanyRepository。父接口(interface)IRepository包含Add()函数的定义,但不包含子接口(interface)ICopmanyRepository。

类层次结构“CompanyRepository”的链中的最后一个派生类实现ICompanyRepository(CompanyRepository不实现IRepository接口(interface)的Add()函数),而根(最高父级)(抽象基)类(即RepositoryBase)实现Add()函数。

因此,结构类似于 http://screencast.com/t/a9UULJVW0中显示的图像。

现在,如果我调用Add()函数:
code ICompanyRepository lastDerived = new CompanyRepository();
ICompanyRepository-> Add(); code
然后根据您在回答中指出的OO-Rule,查找将从CompanyRepository类开始,并期望CompanyRepository将已实现Add()函数为 code IRepository.Add(){
}//根据[link] http://www.codeproject.com/Articles/18743/Interfaces-in-C-For-Beginners[link] code中的P17和P18推导

但是,在我的案例中,CompanyRepository类没有实现IRepository.Add(){},尽管控制流(在跟踪时)成功跳转到了基类中的Add()函数(并且代码运行正常)。我不明白哪个OO-Rule在这里适用?

如果您需要我用代码显示上述情况,请告诉我。

最佳答案

好多话。我要重申一下我认为您要问的问题,然后回答该问题。如果我没有能力,请告诉我。

When invoking a method through an interface, does it matter if that interface is explicitly declared again as being implemented on a more derived type in the type hierarchy?



是的,这称为“接口(interface)重新实现”,它会更改方法的映射方式。 C#语言规范(第13.4.6节“接口(interface)重新实现”)对此进行了更详细的介绍,但是要点是,指定该接口(interface)的最派生类型是查找的起点。
interface ICreature
{
void Speak();
}

class Animal : ICreature
{
public void Speak() { Console.WriteLine("Rawr"); }
}

class Duck:Animal
{
public void Speak() { Console.WriteLine("Quack"); }
}

class Human : Animal, ICreature
{
public void Speak() { Console.WriteLine("Hello"); }
}

如果执行以下操作,它将打印出“Rawr”和“Hello”。
ICreature duck = new Duck();
ICreature human = new Human();
duck.Speak();
human.Speak();

这是因为在Duck层次结构中,指定ICreature接口(interface)的最派生类型为Animal,因此它将打印出“Rawr”。

在人员层次结构中,指定ICreature接口(interface)的最派生类型是人员(人员声明了实现),因此它将打印出“Hello”。如果Human类型没有声明实现,则它还将打印“Rawr”。

更新

在您的特定情况下,将应用完全相同的规则。让我们逐步进行操作。
  • ICompanyRepository继承自IRepository
  • CompanyRepository声明它实现了ICompanyRepository
  • CompanyRepository现在隐式声明它实现了IRepository,因为ICompanyRepository继承自IRepository

  • 然后,调用链将遵循以下步骤。
  • 通过键入ICompanyRepository接口(interface)的实例调用Add()方法。
  • 明确声明已实现IRepository的最派生类型现在是CompanyRepository,因此查找从此处开始。
  • CompanyRepository不会直接实现Add()方法,因此将检查其父类。
  • 已检查
  • SQLRepositoryBase,它没有直接实现该方法,因此要检查其父类。
  • 已检查
  • RepositoryBase,它确实实现了该方法,因此将被调用该方法。
  • 关于c# - 基类实现基本接口(interface),而派生/混凝土类实现扩展接口(interface),为什么呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18990184/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com