Apex接口

接口就像一个类,其中没有任何方法 已实现 – 方法签名存在,但每个方法的主体为空。自 使用接口,另一个类必须通过为所有方法提供主体来实现它 包含在接口中。

接口可以为代码提供抽象层。他们分离特定的 从该方法的声明中实现方法。这样你就可以拥有 基于特定应用程序的方法的不同实现。

定义接口类似于定义新类。例如,一家公司可以有 两种类型的采购订单,一种来自客户,另一种来自客户 他们的员工。两者都是一种采购订单。假设您需要一种方法来 提供折扣。折扣金额可能取决于采购订单的类型。

您可以将采购订单的一般概念建模为接口,并具有特定的 为客户和员工实施。在以下示例中,焦点仅为 在采购订单的折扣方面。

下面是接口的定义。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

  1. 自定义迭代器

自定义迭代器

迭代器遍历集合中的每个项。例如,在 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

名字参数返回描述
iteratorIterator 类返回对此接口的迭代器的引用。

该方法必须是 声明为 或 。它创建对迭代器的引用 然后,您可以使用它来遍历数据结构。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){
   }
}