Ada:标记类型---从父包继承

时间:2012-08-27 07:05:50

标签: inheritance ada

我正在尝试理解标记类型和代码扩展以及重用。我首先创建一个程序conventional_method_number_of_averages,它实现了一种计算方法。然后我使用标记类型的扩展并创建第二个程序alternative_method_number_of_averages,它实现了解决相同问题的不同方法。不同的是,现在我有一个名为parameter的{​​{1}}。这是一个简单的程序,第一个方法overlap_fraction可以正常工作:

  1. number_of_averages.ads

    conventional_method_number_of_averages
  2. conventional_method_number_of_averages.ads

    with Conventional_Method_Number_Of_Averages;
    package Number_Of_Averages renames Conventional_Method_Number_Of_Averages;
    
  3. conventional_method_number_of_averages.adb

    package Conventional_Method_Number_Of_Averages is
    
    type First_Method is tagged private;
    
    procedure Count_Averages (Any_Method : in out First_Method; Sampling_Frequency, FFT_Size, Time_Recorded: in Float);
    
    function Average_Is (Any_Method : in First_Method) return Float;
    
    private
    type First_Method is tagged
      record
         Number_Of_Averages : Float :=0.0;
       end record;
    
    end Conventional_Method_Number_Of_Averages;
    
  4. 和测试文件 test_number_of_averages.adb

    package body Conventional_Method_Number_Of_Averages is
    
    procedure Count_Averages (Any_Method : in out First_Method; Sampling_Frequency, FFT_Size, Time_Recorded: in Float) is
    begin
        Any_Method.Number_Of_Averages := (((Sampling_Frequency * Time_Recorded) - FFT_Size)*(2.0/FFT_Size)) + 1.0;
    end Count_Averages;
    
    function Average_Is (Any_Method : in First_Method) return Float is
    begin
        return Any_Method.Number_Of_Averages;
    end;
    
    end Conventional_Method_Number_Of_Averages;
    
  5. 以上工作正常。

    现在,如果我为同一计算创建一个替代方法,我有:

    1. 其规格 alternative_method_number_of_averages.ads

      with Ada.Float_Text_IO;
      with Ada.Text_IO; use Ada.Text_IO;
      
      with Number_Of_Averages;
      with Conventional_Method_Number_Of_Averages;
      use type Number_Of_Averages.First_Method;
      procedure Test_Number_Of_Averages is
      
      Fs, Time_Duration, NFFT    : Float := 0.0;
      Averages                   : Float := 0.0;
      
      Good_Method : Conventional_Method_Number_Of_Averages.First_Method;
      
      begin
         Ada.Text_IO.Put("Enter the sampling frequency ");
         Ada.Float_Text_IO.Get (Item => Fs);
         Ada.Text_IO.New_Line (1);
         Ada.Text_IO.Put("Enter the time recorded ");
         Ada.Float_Text_IO.Get (Item => Time_Duration);
         Ada.Text_IO.New_Line (1);
         Ada.Text_IO.Put("Enter the FFT size ");
         Ada.Float_Text_IO.Get (Item => NFFT);
         Ada.Text_IO.Put_Line (Ada.Text_IO.Get_Line);
      
         Ada.Text_IO.New_Line(1);
         Ada.Text_IO.Put("Number of averages = ");
         Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration);
      
         Averages := Conventional_Method_Number_Of_Averages.Average_Is(Good_Method);
         Ada.Float_Text_IO.Put (Item => Averages, Fore => 3, Aft  => 5, Exp  => 0);
      
      end Test_Number_Of_Averages;
      
      1. 其正文 alternative_method_number_of_averages.adb

        with Conventional_Method_Number_Of_Averages;
        use Conventional_Method_Number_Of_Averages;
        
        package Alternative_Method_Number_Of_Averages is
        
        type Second_Method is new First_Method with private;
        
        --override this function
        procedure Count_Averages (Any_Method : in out Second_Method; Sampling_Frequency, FFT_Size, Time_Recorded, Overlap_Fraction: in Float);
        
        
        private
        type Second_Method is new First_Method with
          record
             Overlap_Fraction : Float :=0.5;
          end record;
        
        end Alternative_Method_Number_Of_Averages;
        
      2. 然后在编译规范文件时,我收到错误消息:

        alternative_method_number_of_averages.ads:在alternative_method_of_averages.ads中定义的类型“Second_Method”没有选择器“number_of_averages”。罪魁祸首是:

        package body Alternative_Method_Number_Of_Averages is
        
        --override this function
        procedure Count_Averages (Any_Method : in out Second_Method; Sampling_Frequency, FFT_Size, Time_Recorded, Overlap_Fraction: in Float) is
        begin
           Any_Method.Number_Of_Averages := ((Sampling_Frequency * Time_Recorded) - FFT_Size) / (FFT_Size - Overlap_Fraction * FFT_Size) + 1.0;
        end Count_Averages;
        
        
        end Alternative_Method_Number_Of_Averages;
        

        那么如何解决这个问题?

        最后,我希望能够有类似的东西:

             Any_Method.Number_Of_Averages := ((Sampling_Frequency * Time_Recorded) - FFT_Size) / (FFT_Size - Overlap_Fraction * FFT_Size) + 1.0;
        

        在测试文件 test_number_of_averages.adb 中,与工作代码类似

             Number_Of_Averages.Count_Averages(Alternative_Method, Fs, NFFT, Time_Duration, Overlap_fraction);
        

        非常感谢...

        更新

        现在,对于替代方法实现,我已将 Alternative_Method_Number_Of_Averages.ads/adb 重命名为 Conventional_Method_Number_Of_Averages-Alternative_Method_Number_Of_Averages.ads/adb 。测试文件是:

             Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration);
        

        当Fs = 48000,Time_Duration = 60,NFFT = 8192时,两种方法都返回702.125。但是第二种方法总是返回702.125而不管 with Ada.Float_Text_IO; with Ada.Text_IO; use Ada.Text_IO; with Number_Of_Averages; with Conventional_Method_Number_Of_Averages; use type Number_Of_Averages.First_Method; with Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages; procedure Test_Number_Of_Averages is Fs, Time_Duration, NFFT : Float := 0.0; Averages1 : Float := 0.0; Averages2 : Float := 0.0; Good_Method : Conventional_Method_Number_Of_Averages.First_Method; Alternative_Method : Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages.Second_Method; begin Ada.Text_IO.Put("Enter the sampling frequency "); Ada.Float_Text_IO.Get (Item => Fs); Ada.Text_IO.New_Line (1); Ada.Text_IO.Put("Enter the time recorded "); Ada.Float_Text_IO.Get (Item => Time_Duration); Ada.Text_IO.New_Line (1); Ada.Text_IO.Put("Enter the FFT size "); Ada.Float_Text_IO.Get (Item => NFFT); Ada.Text_IO.Put_Line (Ada.Text_IO.Get_Line); Ada.Text_IO.New_Line(1); Ada.Text_IO.Put("Number of averages = "); Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration); Averages1 := Conventional_Method_Number_Of_Averages.Average_Is(Good_Method); Ada.Float_Text_IO.Put (Item => Averages1, Fore => 3, Aft => 5, Exp => 0); Ada.Text_IO.New_Line(1); Ada.Text_IO.Put("Number of averages = "); Number_Of_Averages.Alternative_Method_Number_Of_Averages.Count_Averages(Alternative_Method, Fs, NFFT, Time_Duration); Averages2 := Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages.Average_Is(Alternative_Method); Ada.Float_Text_IO.Put (Item => Averages2, Fore => 3, Aft => 5, Exp => 0); end Test_Number_Of_Averages; 参数。如何在调用函数中指定Overlap_Fraction,同时仍保持私有使用,即让函数使用存储在记录中的Overlap_Fraction值。

1 个答案:

答案 0 :(得分:3)

Alternative_Method_Number_Of_Averages的正文中,您尝试使用Number_Of_Averages,它是父类型的私有成员。因为它是私人的, 你没有它的可见性。

当您使用包时,您只能看到规范的公共部分。

子包将在其公共部分中显示父项的公共部分,并且可以在其私有部分中查看父项的私有部分。

还有私人孩子,它们在自己的规范中可以看到整个父母

要获得Number_Of_Averages的可见性,您可以将完整类型声明移至公共部分,也可以使Alternative_Method_Number_Of_Averages成为Conventional_Method_Number_Of_Average的子包。

有关详细信息,请查看: http://en.wikibooks.org/wiki/Ada_Programming/Packages

另一方面,仅当类型扩展实现具有与父级中相同的精确参数配置文件的子程序时才会发生覆盖。在您的示例中,Second_Method正在重载Count_Averages,即添加具有相同名称但不同配置文件的新子程序。 Count_Averages仍然使用较短的参数配置文件从父级继承。