簡體   English   中英

ADA 中通過泛型 mixins 的多類型繼承

[英]Multiple type inheritance in ADA via generic mixins

為了減少測試和重復代碼,我發現了通過通用混合的多重繼承,但我不知道如何實現這一點的最佳方法以及最佳實踐。

具有以下類層次結構示例(使用diagrams.net完成):

類層次結構

這是泛型的規范:

generic
  
  type S is abstract tagged private;

package GenericChild is
  
  type GenericChild_T is abstract new S with private;

  procedure P_SetGenericAttribute (Self : in out GenericChild_T;
                                   i    : Integer);

  function F_GetGenericAttribute (Self : GenericChild_T)
                                  return Integer;

private

  type GenericChild_T is abstract new S with
    record
      GenericAttribute : Integer;
    end record;

end GenericChild;

對於 Child1 中的通用實例化:

with Root;
with GenericChild;

package Child1 is
  
  type Child1_T is new Root.Root_T with private;

private

  package Child1_G is new GenericChild (Root.Root_T);

  type Child1_T is new Child1_G.GenericChild_T with null record;

end package Child1;

我可以毫無問題地使用 Root_T 類上定義的方法,但是,當我嘗試使用通用方法時,我得到了:

no selector "P_SetGenericAttribute" for private type "Child1_T" ...

這是我測試過的 main.adb:

with Child1;

procedure Main is

  Instance : Child1.Child1_T;

begin

  Instance.P_SetRootAttribute(1); --ok
  Instance.P_SetGenericAttribute(1); --illegal

end main;

為什么? 因為我已經封裝了泛型包實例化? 在這種情況下,如何解決它的最佳方法? 在子類中創建公共方法並在方法實現中調用私有通用實例化方法? 因為我想將通用實例化保持為私有。 通過這樣做,我可以設置和獲取泛型的屬性。

這些是對 child1.ads 進行的對我有用的更改:

with Root;
with GenericChild;

package Child1 is
  
  type Child1_T is new Root.Root_T with private;

  procedure P_SetGenericAttribute (Self : in out Child1_T;
                                   i    : Integer);

  function F_GetGenericAttribute (Self : Child1_T)
                                  return Integer;

private

  package Child1_G is new GenericChild (Root.Root_T);

  type Child1_T is new Child1_G.GenericChild_T with null record;

end package Child1;

這是完成它並起作用的 child1.adb,但我不確定這是否是實現它的更好方法,例如重命名或其他方法:

package body Child1 is

  procedure P_SetGenericAttribute (Self : in out Child1_T;
                                   i    : Integer) is
  begin
  
    Child1_G.GenericChild_T(Self).P_SetGenericAttribute (i);

  end P_SetGenericAttribute;

  function F_GetGenericAttribute (Self : Child1_T)
                                  return Integer is
  
    i : Integer;  

  begin

    i := Child1_G.GenericChild_T(Self).F_GetGenericAttribute;
    return i;

  end F_GetGenericAttribute;

end package Child1;

歡迎任何建議和/或最佳實踐。

no selector "P_SetGenericAttribute" for private type "Child1_T" ...

您收到此錯誤的原因是您的實現(GenericChild 實例化的派生)是私有的; 您的客戶根本無法看到類型這樣的派生。


但是你有一個更大的問題:Ada 不像你的圖表那樣做多重繼承。 不過,您可以執行多種interface類型並從中派生。 或者你可以使用generic和靜態多態。 -- 但是直接多重繼承是行不通的。 (正如您所提到的,您也可以使用混入,但這些並不是真正的繼承。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM