Skip to main content

Code reviews rule: Invalid access modifier on abstract, override or virtual method

Written by David Martin
Updated today

Invalid access modifier on abstract, override or virtual method

Why is this an issue?

In API versions before 65.0 (Winter '26), the Apex compiler allowed abstract, override, and virtual methods to be declared as private. Starting in API version 65.0, these methods must use protected, public, or global. Declaring them as private is a compilation error.

Logically, declaring a method as both private and inheritable is a contradiction, since all three modifiers require subclass access that private visibility prevents:

  • Abstract methods must be implemented by subclasses

  • Override methods must override a parent method, which itself cannot be private

  • Virtual methods are designed for extension and must be accessible to subclasses

Examples

Example of incorrect code:

public virtual class ParentClass {
// Error: virtual method cannot be private
private virtual void processRecord(Account acc) {
// Implementation
}
}

public abstract class BaseHandler {
// Error: abstract method cannot be private
private abstract void handleEvent();
}

public class ChildClass extends ParentClass {
// Error: override method cannot be private
private override void processRecord(Account acc) {
// Implementation
}
}

Example of correct code:

public virtual class ParentClass {
// Protected allows subclass access
protected virtual void processRecord(Account acc) {
// Implementation
}
}

public abstract class BaseHandler {
// Protected for subclass implementation
protected abstract void handleEvent();
}

public class ChildClass extends ParentClass {
// Override must match or widen access
protected override void processRecord(Account acc) {
// Implementation
}
}

How can I fix violations?

This rule supports autofix, which replaces private with protected as a safe default.

To manually fix violations, you can:

  • Use the protected modifier instead to allow subclass access without exposing the method publicly

  • Use the public modifier if the method should be accessible to all classes

  • Remove the modifier if the method does not need to be abstract, virtual, or override

Resources

Did this answer your question?