Override concrete method with abstract method

I’m trying to overwrite a concrete protected member defined in Java with a subclass defined in Scala.

Here is some example code which does it:

// BaseJava.java

public abstract class BaseJava {
    protected          void fn1() { System.out.println("BaseJava#fn1()"); }
    protected          void fn2() { System.out.println("BaseJava#fn2()"); }
    protected abstract void fn3();
}
// DerivedScala.scala

abstract class DerivedScala extends BaseJava {
  override           def fn1(): Unit // error
  override protected def fn2(): Unit // ok
  override           def fn3(): Unit // ok
}

If you add protected on the subclass side(fn2), no error will occur, but if there is no qualifier(fn1), an error will occur.

When overriding a concrete member that is stronger than protected, isn’t it possible to add a stronger access modifier?

FYI, If the subclass is Java, it will no compile error.

Hi.

It is always helpful to also include the error message you get.

DerivedScala.scala:3:16: overriding method fn1 in class DerivedScala of type ()Unit;
[error]  method fn1 in class BaseJava of type ()Unit has weaker access privileges; it should be public;
[error]  (Note that method fn1 in class DerivedScala of type ()Unit is abstract,
[error]   and is therefore overridden by concrete method fn1 in class BaseJava of type ()Unit)

As the compiler told you, you cannot have weaker access privileges when overriding a method of a base class.

Also note the warning about the behavior when overriding a method with an abstract method (basically has no effect).

Especially note that the extra note in the error message says that because the fn1 in BaseJava has an implementation and the one in DerivedScala is abstract he considers the BaseJava method to be the override, which is kind of confusing. And you can override a protected method with a public method, but not the other way around.

Thank you immediately answer.

It is always helpful to also include the error message you get.

Ah! Sorry, I forgot to give the error message.

[error] method fn1 in class BaseJava of type ()Unit has weaker access privileges; it should be public;
[error] (Note that method fn1 in class DerivedScala of type ()Unit is abstract,
[error] and is therefore overridden by concrete method fn1 in class BaseJava of type ()Unit)

Does it mean that the Base Java overrides the abstract method defined in Derived Scala in the reverse direction in the class hierarchy?

If so, in MoreDerivedScala, which is a concrete subclass of DerivedScala, I expected that implementation would not be necessary because fn2 was overridden by BaseJava.
However, actually that MoreDerivedScala requires the implementation of fn2, so it seems that the abstract method was redefined in DerivedScala and the concrete method was hidden.
Is it overridden by BaseJava but not visible to class of grandchildren?

Here is some example code which does it:

// DerivedScala.scala

abstract class DerivedScala extends BaseJava {
  // override           def fn1(): Unit // error
  override protected def fn2(): Unit // ok
  override           def fn3(): Unit // ok
}
// MoreDerivedScala.scala

class MoreDerivedScala extends DerivedScala {
  override def fn3(): Unit = println("MoreDerivedScala#fn3()")
}
MoreDerivedScala.scala:3: error: class MoreDerivedScala needs to be abstract. No implementation found in a subclass for deferred declaration
override protected def fn2(): Unit (defined in class DerivedScala)
class MoreDerivedScala extends DerivedScala {
      ^