pascal程序员学Golang——Interface(2)

接口的实际使用

现在让我们看一下接口的实际用途。

我们将编写一个简单的程序,根据员工的个人工资计算公司的总费用。为简洁起见,我们假设所有费用均以美元为单位。

package main

import (  
    "fmt"
)

type SalaryCalculator interface {  
    CalculateSalary() int
}

type Permanent struct {  
    empId    int
    basicpay int
    pf       int
}

type Contract struct {  
    empId    int
    basicpay int
}

//salary of permanent employee is the sum of basic pay and pf
func (p Permanent) CalculateSalary() int {  
    return p.basicpay + p.pf
}

//salary of contract employee is the basic pay alone
func (c Contract) CalculateSalary() int {  
    return c.basicpay
}

/*
total expense is calculated by iterating through the SalaryCalculator slice and summing  
the salaries of the individual employees  
*/
func totalExpense(s []SalaryCalculator) {  
    expense := 0
    for _, v := range s {
        expense = expense + v.CalculateSalary()
    }
    fmt.Printf("Total Expense Per Month $%d", expense)
}

func main() {  
    pemp1 := Permanent{
        empId:    1,
        basicpay: 5000,
        pf:       20,
    }
    pemp2 := Permanent{
        empId:    2,
        basicpay: 6000,
        pf:       30,
    }
    cemp1 := Contract{
        empId:    3,
        basicpay: 3000,
    }
    employees := []SalaryCalculator{pemp1, pemp2, cemp1}
    totalExpense(employees)

}

 我们公司有两种员工,由第 11 行和第 17 行中的结构定义。长期雇员的工资是总和,而对于合同雇员来说,这只是基本工资。这在相应的方法中表示,分别在23和28行。通过声明此方法,两者和结构现在都实现了接口。

第 36 行中声明的函数表达了接口的美感。此方法将 SalaryCalculator 接口的一部分作为参数。在第 59 行中,我们将一个包含两者和类型的切片传递给函数。该函数通过调用相应类型的方法来计算费用。这是在排队的情况下完成的,在39行。

这样做的最大优点是可以扩展到任何新员工类型,而无需更改任何代码。假设公司增加了一种具有不同薪酬结构的新型员工。这可以在 slice 参数中传递,甚至不需要对函数进行任何代码更改。此方法将执行它应该执行的操作,也将实现接口:)。

让我们修改此程序并添加新员工Freelancer。Freelancer的工资是每小时工资与总工作时间的乘积。

package main

import (  
    "fmt"
)

type SalaryCalculator interface {  
    CalculateSalary() int
}

type Permanent struct {  
    empId    int
    basicpay int
    pf       int
}

type Contract struct {  
    empId    int
    basicpay int
}

type Freelancer struct {  
    empId       int
    ratePerHour int
    totalHours  int
}

//salary of permanent employee is sum of basic pay and pf
func (p Permanent) CalculateSalary() int {  
    return p.basicpay + p.pf
}

//salary of contract employee is the basic pay alone
func (c Contract) CalculateSalary() int {  
    return c.basicpay
}

//salary of freelancer
func (f Freelancer) CalculateSalary() int {  
    return f.ratePerHour * f.totalHours
}

/*
total expense is calculated by iterating through the SalaryCalculator slice and summing  
the salaries of the individual employees  
*/
func totalExpense(s []SalaryCalculator) {  
    expense := 0
    for _, v := range s {
        expense = expense + v.CalculateSalary()
    }
    fmt.Printf("Total Expense Per Month $%d", expense)
}

func main() {  
    pemp1 := Permanent{
        empId:    1,
        basicpay: 5000,
        pf:       20,
    }
    pemp2 := Permanent{
        empId:    2,
        basicpay: 6000,
        pf:       30,
    }
    cemp1 := Contract{
        empId:    3,
        basicpay: 3000,
    }
    freelancer1 := Freelancer{
        empId:       4,
        ratePerHour: 70,
        totalHours:  120,
    }
    freelancer2 := Freelancer{
        empId:       5,
        ratePerHour: 100,
        totalHours:  100,
    }
    employees := []SalaryCalculator{pemp1, pemp2, cemp1, freelancer1, freelancer2}
    totalExpense(employees)

}

 现在看delphi如何实现的:

program InterfaceTest2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, ArrayHelper, System.Generics.Collections;

type
    int = Integer;
    ISalaryCalculator = interface
      ['{EFFAFB71-7508-48E3-BB1E-3372B436043A}']
      function CalculateSalary: Integer;
    end;


 TPermanent = class(TInterfacedObject, ISalaryCalculator)
 private
      empId    ,
      basicpay ,
      pf       :int;
 public
    function CalculateSalary: Integer;
    constructor Create(AempId, Abasicpay , Apf: int);
 end;

  TContract = class(TInterfacedObject, ISalaryCalculator)
  private
      empId    ,
      basicpay: int;
  public
      function CalculateSalary: Integer;
      constructor Create(AempId, Abasicpay: int);
  end;

  TFreelancer= class(TInterfacedObject, ISalaryCalculator)
  private
    empId,
    ratePerHour,
    totalHours:  int;
  public
      function CalculateSalary: Integer;
      constructor Create(AempId, AratePerHour, AtotalHours: int);
  end;
//salary of permanent employee is the sum of basic pay and pf
constructor TPermanent.Create(AempId, Abasicpay , Apf: int);
begin
  empId    := AempId;
  basicpay := Abasicpay;
  pf       := Apf;
end;

function TPermanent.CalculateSalary: int;
begin
    Result := basicpay + pf
end;

//salary of contract employee is the basic pay alone
constructor TContract.Create(AempId, Abasicpay: int);
begin
  empId    := AempId;
  basicpay := Abasicpay;
end;

function TContract.CalculateSalary: int;
begin
    Result := basicpay
end;

//salary of freelancer
constructor TFreelancer.Create(AempId, AratePerHour, AtotalHours: int);
begin
   empId := AempId;
   ratePerHour := AratePerHour;
   totalHours := AtotalHours
end;

function TFreelancer.CalculateSalary: int;
begin
    result := ratePerHour * totalHours
end;
(*
total expense is calculated by iterating through the SalaryCalculator slice and summing
the salaries of the individual employees
*)
procedure totalExpense(s: TArray<ISalaryCalculator>);
var
   expense: int;
   v: ISalaryCalculator;
begin
    expense := 0;
    for v in  s do
    begin
        expense := expense + v.CalculateSalary()
    end;
    Writeln(Format('Total Expense Per Month $%d', [expense]))
end;

procedure main();
var
  pemp1, pemp2, cemp1, freelancer1, freelancer2: ISalaryCalculator;
  employees: TArray<ISalaryCalculator>;
begin
    pemp1 := TPermanent.Create(1, 5000, 20);
    pemp2 := TPermanent.Create(2, 6000, 30);
    cemp1 := TContract.Create(3, 3000);
    freelancer1 := TFreelancer.Create(4, 70, 120);

    freelancer2 := TFreelancer.Create(5, 100, 100);
    employees := nil;
    TArray.Insert<ISalaryCalculator>(employees, 0, pemp1);
    TArray.Add<ISalaryCalculator>(employees, pemp2);
    TArray.Add<ISalaryCalculator>(employees, cemp1);
    TArray.Add<ISalaryCalculator>(employees, freelancer1);
    TArray.Add<ISalaryCalculator>(employees, freelancer2);
    totalExpense(employees);
    SetLength(employees, 0);
end;

begin
  try
    main{ TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

 不得不承认,delphi的代码要冗长很多,而且用到一个开源的单元文件:ArrayHelper,才有Add方法可用。

输出是一样的

Total Expense Per Month $14050
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值