元类和“类过程”
元类主要涉及“类过程”。从一个基本的class
开始:
type
TAlgorithm = class
public
class procedure DoSomething;virtual;
end;
因为DoSomething
是一个类方法
,我们可以不需要TAlgorithm的实例就调用它(它像任何其他全局过程一样)。我们可以这样做:
TAlgorithm.DoSomething
一旦我们完成了这个设置,我们可能会创建一些替代算法,所有这些算法都共享基础算法的一些部分。就像这样:
type
TAlgorithm = class
protected
class procedure DoSomethingThatAllDescendentsNeedToDo;
public
class procedure DoSomething;virtual;
end;
TAlgorithmA = class(TAlgorithm)
public
class procedure DoSomething;override;
end;
TAlgorithmB = class(TAlgorithm)
public
class procedure DoSomething;override;
end;
我们现在有一个基础类和两个派生类。以下代码是完全有效的,因为我们将方法声明为“class”方法:
TAlgorithm.DoSomething;
TAlgorithmA.DoSomething;
TAlgorithmB.DoSomething;
让我们介绍一下 "class of" 类型:
type
TAlgorithmClass = class of TAlgorithm;
procedure Test;
var X:TAlgorithmClass;
begin
X := TAlgorithm;
X := TAlgorithmA;
X := TAlgorithmB;
end;
TAlgorithmClass是一种数据类型,可以像其他数据类型一样使用,可以存储在变量中,作为函数的参数传递。换句话说,我们可以这样做:
procedure CrunchSomeData(Algo:TAlgorithmClass);
begin
Algo.DoSomething;
end;
CrunchSomeData(TAlgorithmA);
在这个例子中,CrunchSomeData过程可以使用任何算法变种,只要它是TAlgorithm的后代。
以下是该行为在实际应用程序中的示例:想象一个类似于工资单的应用程序,其中一些数字需要根据法律规定的算法进行计算。由于法律有时会更改,因此这个算法可能会随之改变。我们的应用程序需要使用最新版本的计算器来计算当年的工资,并使用较旧版本的算法来计算其他年份的工资。下面是具体实现的方式:
TTaxDeductionCalculator = class
public
class function ComputeTaxDeduction(Something, SomeOtherThing, ThisOtherThing):Currency;virtual;
end;
function GetTaxDeductionCalculator(Year:Integer):TTaxDeductionCalculator;
begin
case Year of
2001: Result := TTaxDeductionCalculator_2001;
2006: Result := TTaxDeductionCalculator_2006;
else Result := TTaxDeductionCalculator_2010;
end;
end;
procedure Compute;
begin
Taxes := (NetSalary - GetTaxDeductionCalculator(Year).ComputeTaxDeduction(...)) * 0.16;
end;
虚拟构造函数
Delphi中的构造函数就像一个"类函数";如果我们有一个元类,并且该元类知道一个虚构造函数,那么我们就可以创建后代类型的实例。TCollection的IDE编辑器在您按下"添加"按钮时使用此功能来创建新项目。TCollection只需要获取TCollectionItem的元类即可使其正常工作。