gpt4 book ai didi

delphi - Delphi接口(interface)是否在子类中继承

转载 作者:行者123 更新时间:2023-12-03 15:17:39 25 4
gpt4 key购买 nike

如果我在基类上实现接口,它将被其子类继承,我知道函数/过程将是,但是我对是否能够将子类转换为接口然后返回到它更感兴趣。原班。

我希望我能做的是将不同基类的对象传递给一个函数,然后在函数中确定类型并在适当时使用它们。

这可能吗,这是正确的方法吗?

更新资料

为了消除任何混乱(或创建更多混乱),这就是我想做的事情(深入到其核心)。

接口

    IMyInterFace = interface
['{B7203E50-F5CB-4755-9DB1-FB41B7B192C5}']
function MyFunction: Boolean;
end;


基类

   type TMyObject = class(TInterfacedObject,IMyInterFace)


子类

  type TSubMyObject = class(TMyObject)


另一类

  type TMyOtherObject = class(TInterfacedObject,IMyInterFace)


然后的用法

 procedure foo();
var obj:TSubMyObject;
begin
obj := TSubMyObject.Create();
SendInterfaceObject(obj);
end;

procedure bar();
var obj:TMyOtherObject;
begin
obj := TMyOtherObject.Create();
SendInterfaceObject(obj);
end;



procedure SendInterfaceObject(iobj:IMyInterFace);
begin
if (iobj is TSubMyObject) then
begin
//code here
end
else if (iobj is TMyOtherObject) then
begin
//code here
end;
end;


更新2

我已经对代码进行了一些更新,以便更好地展示我的追求。

//此处的代码部分与传递给它的对象没有任何关系,例如,如果此类是TAccounts,并且传递了TEmployee对象,则它可以在那里支付周薪,但是如果它是TInvoice,则它将检查看看是否需要付款,并且仅在截止日期前2天才付款。

TEmployee / TInvoice甚至可能来自外部类,要求付款。

这只是一个例子。

最佳答案

是的,该接口是由子类继承的。

从子类强制转换为接口是完全可以接受的。

但是,如果我读错了您的问题,并且如果“然后再返回其原始类”的意思,则表示歉意。 。 。

您具有接口I,A类和B类。
A可以实现I,而B可以继承A,但实际上不应该从A强制转换为B。

编辑:

您想从B到I再回到B。 。 。但是您已经有了对B的引用,如果B是要传递给函数的内容,那么您不需要从I强制转换为B(除非正在谈论其他对象,否则请不要这样做)

从I到B与从A到B相同,您正在尝试构建继承链,这实际上是您不应该做的。需要这样做是一种代码味道,它告诉您应该尝试以其他方式解决此问题(可能是通过重新设计类(例如,向I添加更多属性/方法),或者只是确定该功能仅能工作)子类-使用子类“ B”将使您可以访问A和I的所有方法)。

您可以编辑问题并添加一些示例代码来说明您要做什么吗?

编辑2

 procedure SendInterfaceObject(iobj:IMyInterFace);
begin
if (iobj is TSubMyObject) then
begin
//code here
end;
end;


其中的“ If”语句有一个不好的主意,并且破坏了OO主体。如果您需要这样做,则可以


接口定义是
不足,您可能要添加一个
将属性输入接口
允许您(如果iObj.SomeProperty
= 1)然后。 。 )
接口根本不是
解决此问题的解决方案,以及
您应该将引用传递为
TSubMyObject。


编辑3:

@mghie:我同意你的观点,我没有很好地解释是SomeProperty包含一些数据,该数据允许函数在此处分支,从而消除了类型检查的依赖性。 SomeProperty不应“简单地”替换类型检查(例如,通过将类名称放入属性中,然后检查类名称),这确实是完全相同的问题。

继承接口的子类之间有一些本质的区别。这种差异应通过以下任一方式表示


公开一些可以
然后用在树枝上


例如

if(item.Color = Red) then 
item.ContrastColor := Blue;
else
item.ContrastColor := Red;



或通过多态性例如


IEmployee定义了CalculatePay方法,TManager和TWorker实现了IEmployee,每个方法在CalculatePay方法中具有不同的逻辑。

如果目的是像第一种情况那样做,那么多态可能就显得过分了(多态不能解决所有问题)。

编辑4

您说“此处的//代码部分与传递给它的对象没有任何关系……”。抱歉,该说法有误,如果您需要支付员工薪水,则需要知道他们的工资1)员工代码2)他们的工资明细3)他们的银行明细等,如果您要收取发票,则需要1)InvoiceNumber 2)发票金额3)要收取的客户代码等。 。 。这是多态的理想场所。

假设使用该界面的函数检查“帐户”是否需要对对象执行某项操作(例如,向员工付款,收取发票等)。因此我们可以调用功能AccountsCheck。内部帐户检查将为每个子类提供特定的逻辑(支付雇员,收取发票...)。这是多态性的理想人选。

在您的界面上(或在另一个界面上,或在子类上作为虚拟方法)定义“ AccountsCheck”方法。然后,每个派生类都会获得自己的Accounts check实现。

该代码从笨拙的单个AccountsCheck函数中移出,并移到每个子类的较小函数中。这使代码


目的更明显(每堂课
包含一些逻辑
帐户检查)
您不太可能破坏SubClass
修复某些东西时B的逻辑
帐户检查C
准确找出更容易
子类别B的AccountsCheck逻辑是什么
是,您只需要检查20行
小型AccountsCheck中的验证码,而不是200
在“一般帐户检查”中)


还有更多的“充分理由”,如果没有人想要编辑/发表评论,请这样做。

如果发现需要在AccountsCheck的实现之间共享一些逻辑,请创建一些实用程序功能,而不要在每个实现中重新实现相同的功能。

多态是解决您的问题的方法。

关于delphi - Delphi接口(interface)是否在子类中继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/515307/

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