5

Is there any way I can extend the Set class? I have numerous places in code where if I a set has no items, I want to add all the items in another set, but if it does have items, I want to retain only the items in the other set.

This seemed like a good use case for extending the Set class, but Apex complains about the lack of < following the extending of the set and the declaration of a Set argument in the following code:

public with sharing class CoreSet extends Set {
    public Boolean retainAllIfPopulated(Set other) {
        return this.size() > 0 ? this.retainAll(other)
                               : this.addAll(other);
    }
}

Is it possible to extend the built-in Set class?

2 Answers 2

8

No, it is not possible to extend a class if it is not abstract or virtual. Unlike in Java in Apex all classes are final by default. But you can use "composition (over inheritance)" and write something like this:

public with sharing class SomeClass {
    private Set<Object> objs;

    public SomeClass(Set<Object> objs) {
        this.objs = objs;
    }

    public Boolean retainAllIfPopulated(Set<Object> other) {
        return objs.size() > 0 ? objs.retainAll(other)
                               : objs.addAll(other);
    }
}
2
  • 2
    Unfortunately, due to how Sets work in Apex, Set<Object> is tough to use. You wouldn't be able to pass a Set<Account> into the SomeClass constructor or into retainAllIfPopulated(). Heck, even Set<Object> objSet = new Set<Object>(myAccountSet); doesn't work. This is something I ran into several years ago.
    – Derek F
    Commented Nov 26, 2021 at 20:06
  • 1
    Yeah, you're right, I know that type inference for Set<?> is broken in Apex, but I didn't focus on this topic answering this specific question. Commented Nov 26, 2021 at 20:11
6

No, it is not possible to do this through extending (inheritance) or implementing (interfaces). We'd need generics/templates in the type system, and Apex doesn't provide that.

You can make a class that implements the feature you're looking for but, because of the things I mentioned in my first two sentences, you won't be able to automatically substitute your class somewhere that expects a Set.

The other gotcha here is that because Sets cannot be up-cast nor down-cast (due to a thing called type erasure), you'd need to make a separate class for each individual type that you want to provide this feature for.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .