接口就像一个类,其中没有任何方法 已实现 – 方法签名存在,但每个方法的主体为空。自 使用接口,另一个类必须通过为所有方法提供主体来实现它 包含在接口中。
接口可以为代码提供抽象层。他们分离特定的 从该方法的声明中实现方法。这样你就可以拥有 基于特定应用程序的方法的不同实现。
定义接口类似于定义新类。例如,一家公司可以有 两种类型的采购订单,一种来自客户,另一种来自客户 他们的员工。两者都是一种采购订单。假设您需要一种方法来 提供折扣。折扣金额可能取决于采购订单的类型。
您可以将采购订单的一般概念建模为接口,并具有特定的 为客户和员工实施。在以下示例中,焦点仅为 在采购订单的折扣方面。
下面是接口的定义。PurchaseOrder
// An interface that defines what a purchase order looks like in general
public interface PurchaseOrder {
// All other functionality excluded
Double discount();
}
此类实现接口 用于客户采购订单。PurchaseOrder
// One implementation of the interface for customers
public class CustomerPurchaseOrder implements PurchaseOrder {
public Double discount() {
return .05; // Flat 5% discount
}
}
此类实现接口 用于员工采购订单。PurchaseOrder
// Another implementation of the interface for employees
public class EmployeePurchaseOrder implements PurchaseOrder {
public Double discount() {
return .10; // It’s worth it being an employee! 10% discount
}
}
请注意有关该示例的以下信息:
- 接口已定义 作为通用原型。接口中定义的方法无权访问 修饰符,并且只包含它们的签名。PurchaseOrder
- 班级 实现此接口;因此,它必须为方法提供定义。任何类 实现接口必须定义接口中包含的所有方法。CustomerPurchaseOrderdiscount
定义新接口时,就是在定义新的数据类型。您可以使用 接口名称:在任何地方都可以使用其他数据类型名称。分配给 interface 类型的变量必须是实现该接口的类的实例, 或子接口数据类型。
另请参见类和强制转换。
注意
在类之后,无法将方法添加到全局接口 在托管 – 已发布的包版本中上传。
版本化行为更改
在 API 版本 50.0 及更高版本中,范围和可访问性规则在 Apex 上强制执行 用 注释的变量、方法、内部类和接口。对于可访问性 注意事项,请参阅 NamespaceAccessible 注释。有关基于命名空间的可见性的详细信息,请参阅基于命名空间的可见性 适用于第二代软件包中的 Apex 类。@namespaceAccessible
- 自定义迭代器
自定义迭代器
迭代器遍历集合中的每个项。例如,在 Apex 的循环中,您定义了一个 退出循环的条件,并且您必须提供一些遍历 集合,即迭代器。while在此示例中,每次循环 执行。
count
while (count < 11) {
System.debug(count);
count++;
}
使用该界面,您可以创建自定义集 的指令,用于通过循环遍历列表。迭代器对数据很有用 存在于 Salesforce 之外的源中,您通常会定义其范围 使用语句。迭代器也可以是 如果有多个语句,则使用。IteratorSELECTSELECT
使用自定义 迭代器
自 使用自定义迭代器时,必须创建一个实现接口的 Apex 类。Iterator该接口具有以下实例 方法:
Iterator
名字 | 参数 | 返回 | 描述 |
---|---|---|---|
hasNext | 布尔 | 如果出现以下情况,则返回 否则,集合中还有另一个项目正在遍历。truefalse | |
next | 任何类型 | 返回集合中的下一项。 |
接口中的所有方法都必须声明为 或 。Iteratorglobalpublic您只能在循环中使用自定义迭代器。为 例:
while
IterableString x = new IterableString('This is a really cool test.');
while(x.hasNext()){
system.debug(x.next());
}
循环中目前不支持迭代器。
for
将自定义迭代器与 Iterable 一起使用
如果 您不想将自定义迭代器与列表一起使用,而是希望创建 自己的数据结构,可以使用接口生成数据结构。Iterable该接口具有以下方法:
Iterable
名字 | 参数 | 返回 | 描述 |
---|---|---|---|
iterator | Iterator 类 | 返回对此接口的迭代器的引用。 |
该方法必须是 声明为 或 。它创建对迭代器的引用 然后,您可以使用它来遍历数据结构。iteratorglobalpublicIn the following example a custom iterator iterates through a collection:
public class CustomIterator
implements Iterator<Account>{
private List<Account> accounts;
private Integer currentIndex;
public CustomIterator(List<Account> accounts){
this.accounts = accounts;
this.currentIndex = 0;
}
public Boolean hasNext(){
return currentIndex < accounts.size();
}
public Account next(){
if(hasNext()) {
return accounts[currentIndex++];
} else {
throw new NoSuchElementException('Iterator has no more elements.');
}
}
}
public class CustomIterable implements Iterable<Account> {
public Iterator<Account> iterator(){
List<Account> accounts =
[SELECT Id, Name,
NumberOfEmployees
FROM Account
LIMIT 10];
return new CustomIterator(accounts);
}
}
下面是一个批处理作业,它使用 迭 代:
public class BatchClass implements Database.Batchable<Account>{
public Iterable<Account> start(Database.BatchableContext info){
return new CustomIterable();
}
public void execute(Database.BatchableContext info, List<Account> scope){
List<Account> accsToUpdate = new List<Account>();
for(Account acc : scope){
acc.Name = 'changed';
acc.NumberOfEmployees = 69;
accsToUpdate.add(acc);
}
update accsToUpdate;
}
public void finish(Database.BatchableContext info){
}
}