1

Suppose I have:

trait A{
    println("A")
}

Now I want to inherit this trait in my Java code:

class B implements A {}

It looks like constructor of trait A is not going to be executed. Is it possible to force constructor of trait A to be executed in scope of class B?

6
  • 1
    Related: Using Scala traits with implemented methods in Java Commented Jul 3, 2015 at 17:40
  • @LuiggiMendoza Related question/answer you've proposed don't cover the case with trait's constructor. I'm interesting particularly in trait's constructor invocation here. Commented Jul 3, 2015 at 17:59
  • To the best of my knowledge, you are not allowed to have constructors in interfaces in Java. I think for the same reason you cannot do what you are asking here. Commented Jul 3, 2015 at 18:11
  • If you read the link in that comment, you will find this: From Java perspective Trait.scala is compiled into Trait interface. Hence implementing Trait in Java is interpreted as implementing an interface - which makes your error messages obvious. Short answer: you can't take advantage of trait implementations in Java, because this would enable multiple inheritance in Java (!). And that answers your question: you cannot do what you want, check for another alternative. Commented Jul 3, 2015 at 19:23
  • @LuiggiMendoza I've read it, and completely understood the topic. This question is about trait's constructor, not any other regular method, which has a name, and I could call it like A$class.something. I suppose, if there is abilities to call trait's regular methods in java's successor, then there should be some way to call a constructor as method as well... Commented Jul 5, 2015 at 7:32

2 Answers 2

3

That would become something like:

public interface A {

}

public abstract class A$class {
    public static void $init$(A $this) {
        Predef..MODULE$.println((Object)"A");
    }
}

using a decompiler. Java speaking, that is:

public class AImpl implements A {}
public class User {
  public User() {
    A a = new AImpl();
    A$class.$init$(a);
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

So, you talking about: move you code in trait's constructor into init method, then call it directly from trait's constructor, and in java's successor as well, right? Because I haven't seen an init method in that trait when was implementing it in java's class.
Yes except... no moving is needed because the Java code I gave above is what Scala compiler would produce with your code. I was just answering your question "Is it possible to force constructor of trait A to be executed in scope of class B" and the code I gave in answer was how to do that. If you can add more Scala code to it, then the other answer (from Alexey) would be the way to go.
Are you sure, compiler produce init method for trait's constuctor? I'm asking because I didn't found that when was trying to write such code...
Did you include the dollar signs? See updated answer where I've expanded on the Java code.
3

The most reasonable way to get a Java class implementing a trait which has a constructor and/or non-abstract members is to extend the trait with a class in Scala, then extend this class in Java:

// AbstractA.scala
abstract class AbstractA extends A 

// B.java
class B extends AbstractA

This way the Scala compiler takes care of all the stuff you have to do manually in Java otherwise, as you can see in bjfletcher's answer.

1 Comment

Good proposition. At least don't have to dance with all of these A$class... stuff in successor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.