7

Assume we have some interface, abstract class and contrete class:

interface I {
    void foo();
    void bar();
}
abstract class A implements I {
    public void barFoo() {
        bar(); // Compile Failure
        foo(); // Compile Failure
    }
}
class B extends A {
    public void foo() {
        System.debug('foo');
    }
    public void bar() {
        System.debug('bar');
    }
}

The A abstract class won't compile because of:

Compile failure on line x, column y: Method does not exist or incorrect signature: void bar() from the type A

And this is interesting because such code is absolutely valid in JAVA:

interface I {
    void foo();
    void bar();
}

abstract class A implements I {
    public void fooBar() {
        foo();
        bar();
    }
}

class B extends A {
    @Override
    public void foo() {
        System.out.println("foo");
    }

    @Override
    public void bar() {
        System.out.println("bar");
    }
}

public class Program {
    public static void main(String[] args) {
        new B().fooBar(); 
        // foo
        // bar
    }
}

I found out that explicit declaration of the interface methods as abstract within abstract class resolved the compile error:

abstract class A implements I {
    public void barFoo() {
        bar(); // Works
        foo(); // Works
    }
    public abstract void foo();
    public abstract void bar();
}

class B extends A {
    public override void foo() {
        System.debug('foo');
    }
    public override void bar() {
        System.debug('bar');
    }
}

However, I didn't find any information in ApexDocs about such behavior. Is it a bug or (undocumented) intentionally designed behavior? Or maybe I'm missing something?

2
  • 3
    You haven't implemented the interface though... you just called the methods. Jul 26, 2021 at 22:53
  • 1
    Yes, because theoretically, it shouldn't violate the contract defined by the interface, because the barFoo() method can be invoked only on an instance of a class that extends the abstract class and this class must override the interface methods if they have not been overridden before in the abstract class as non-abstract. Jul 27, 2021 at 7:13

1 Answer 1

6

I believe that, when Apex was originally implemented, this wasn't allowed in Java, either, though it's been a couple of decades since I've used Java 1.1. Apex is notorious for leaving out details like this, expecting developers to have experience in other languages, particularly Java, in order to have a pleasant experience in Apex. I'm not sure if I could even find out the history behind this, as the keywords are exceptionally generic. More research on this topic would be interesting.

Note that similar languages, like C#, also require the abstract class to declare the methods, even if they are just abstract function signatures. Here's one such article on the nature of Java versus C#. This is not a bug, but rather a feature of the language. It is working as designed, as far as I can tell.

Not allowing you do shortcut the function signatures may actually be a compiler and/or runtime optimization, as it would otherwise have to do more compilation checks and vtable lookups otherwise, but this is more speculation on my part, as I'm not exactly an expert on compilers, I mostly just know the theory thereof, and haven't implemented by own yet.

You must log in to answer this question.

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