1

I would like to create an Apex class which extends List<Object> so I can add some custom behaviours:

public class CustomList extends List<My_Object__c> {
   // custom behaviour
}

But I get error:

Non-virtual and non-abstract type cannot be extended: List<My_Object__c>

Is there another way to do this using Apex?

2
  • What custom behavior are you trying to add – identigral Aug 23 '20 at 20:14
  • Hey @identigral, thanks for responding, I've used a wrapper class around a list to achieve that I need. So the actual custom behaviour isn't really the point here I don't think. I was more wondering if there was some other feature/interface or something I hadn't been able to find on my own accord... but to actually answer your question, I wanted to add a bunch of checks/validation when getting the next item from the list before returning it... – Robs Aug 23 '20 at 20:25
4

You cannot extend any system library classes (List, Map, PageReference, etc). They are all either abstract or final.

When/if we get custom Parameterized Typing back, it would be fully possible to emulate classes, such as List2<My_Object__c> (that would be the ideal workaround).

For now, you can write a wrapper class or something, but these are pretty much going to be use-case specific, although you could write some custom interfaces to make a flexible system. However, you'd still have to end up implementing Iterable, Iterator, etc.

Basically, there's too many missing language features in the current platform to make anything short of wrapper classes to handle these unique situations.

4
  • "if we get Parameterized Typing back"? Did apex initially support generics in custom code? – Phil W Aug 24 '20 at 6:47
  • 1
    @PhilW Yes, see this and more importantly this. It existed in early builds, was discontinued a few versions later, and then the UI compiler was patched to disallow it (bugs, yay) a few years later. There's currently an idea out there to add generics to Apex. We're not likely to see it, though, but it would be nice. – sfdcfox Aug 24 '20 at 13:39
  • 1
    @PhilW Also, this. It's been a hot request for a while. I think more people need to go vote. I'd love to see this come back. – sfdcfox Aug 24 '20 at 13:42
  • thanks for the citations. You learn something every day! I haven't been using Salesforce long enough to have come across generics in custom code. That said, it's pretty clear a lot of the generics in apex are smoke and mirrors (like how you can implement Batchable against SObject but implement the execute method itself against the specific SObject type of interest) so unsurprising there were issues. I've upvoted and suggested a merge of the two ideas mentioned in the Q&As you referenced. Cheers. – Phil W Aug 24 '20 at 13:55
4

For the use case of "adding checks/validation when getting the next item from the list before returning it", you can implement Iterable and Iterator interfaces. Slightly modified example from docs:

global class AccountList implements Iterable<Account> { 

  global Iterator<Account> iterator() {
       List<Account> accs = 
       [SELECT Id, Name 
       FROM Account 
       WHERE Name = '...']; 
    return new AccountIterator(accs);
  }
}

global class AccountIterator implements Iterator<Account> { 

   private List<Account> accs;
   private Integer i;

   public Accounts(List<Account> accs){ 
      this.accs = accs;
   }   

   global boolean hasNext(){ 
       return (i < accs.size());
   }    

   global Account next(){ 
       if(accs[i].Id != '001...' ) { // validation check
           // do something - throw an exception, skip this item, ...
       }
       return accs[++i-1]; 
   } 
}

And using it:

Iterable<Account> accounts = new AccountList();
Iterator<Account> validatedAccounts = accounts.iterator();
while(validatedAccounts.hasNext()){
   system.debug(validatedAccounts.next());
} 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.