Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

The documentation for access modifiers states the following for protected:

This means that the method or variable is visible to any inner classes in the defining Apex class, and to the classes that extend the defining Apex class.

Makes sense. And, for global:

This means the method or variable can be used by any Apex code that has access to the class, not just the Apex code in the same application.

Also, makes sense.

But what about when global and protected are combined like the following?

global abstract class MyAbcService {

    global void algorithm() {
        // ...do some common pre-processing...
        // ...then call to implementation
        abstractMethod();
    }

    global protected abstract void abstractMethod();

}

Is the global protected abstractMethod only available to subclasses still or can it be seen by all classes, including non-subclasses? If it is only available to subclasses, is it all subclasses or just those in the application? Something else?

Yes, it does compile. :)

share|improve this question
1  
Does that compile? I had always assumed these were mutually exclusive. –  Peter May 8 at 16:35
1  
@Peter - That's what I thought too, but it does compile. –  Peter Knolle May 8 at 17:23

1 Answer 1

up vote 7 down vote accepted

Very interesting! I've tried this out with a managed release of a package.

Here's the Base class (in namespace typetest)

global abstract class Base {

    global void canSomething() {
        //
    }

    global protected abstract void inheritSomething();

    protected void cantSomething() {
        //
    }

}

and the Child class (alongside an install of the above package)

global class Child extends typetest.Base {

    override global void inheritSomething() {
        //
    }

}

Indeed all the code compiles and executes alright. But it looks like the global wins, because if I do this:

Child child = new Child();
child.inheritSomething();

then it compiles and executes, which I wouldn't expect if it were protected. :-)

Further, I noticed protected visibility is only accessible in the same namespace, not to global extendors. So another namespace extending your class will not be able to call protected methods, like this:

//Compile Error: Method is not visible: [typetest.Base].cantSomething()
override global void inheritSomething() {
    super.cantSomething();
}

That last case is where I can fathom an intended behavioural difference; you might legitimately intend:

  • protected to be callable by extendors inside the namespace
  • global protected to be callable by extendors outside the namespace also

but this is not what's happening - protected members are not callable by extendors outside the namespace! Nor even are public members, I tried that too.

share|improve this answer
1  
Thanks! That's the behavioral difference that I was thinking might happen with global protected. I was thinking of the template method pattern. Or, something like Java's abstract Reader class that requires extenders to implement close() and read(...) and no other methods. –  Peter Knolle May 8 at 20:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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