Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8774585
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T18:36:21+00:00 2026-06-13T18:36:21+00:00

In Scala, a val can override a def , but a def cannot override

  • 0

In Scala, a val can override a def, but a def cannot override a val.

So, is there an advantage to declaring a trait e.g. like this:

trait Resource {
  val id: String
}

rather than this?

trait Resource {
  def id: String
}

The follow-up question is: how does the compiler treat calling vals and defs differently in practice and what kind of optimizations does it actually do with vals? The compiler insists on the fact that vals are stable — what does in mean in practice for the compiler? Suppose the subclass is actually implementing id with a val. Is there a penalty for having it specified as a def in the trait?

If my code itself does not require stability of the id member, can it be considered good practice to always use defs in these cases and to switch to vals only when a performance bottleneck has been identified here — however unlikely this may be?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T18:36:22+00:00Added an answer on June 13, 2026 at 6:36 pm

    Short answer:

    As far as I can tell, the values are always accessed through the accessor method. Using def defines a simple method, which returns the value. Using val defines a private [*] final field, with an accessor method. So in terms of access, there is very little difference between the two. The difference is conceptual, def gets reevaluated each time, and val is only evaluated once. This can obviously have an impact on performance.

    [*] Java private

    Long answer:

    Let’s take the following example:

    trait ResourceDef {
      def id: String = "5"
    }
    
    trait ResourceVal {
      val id: String = "5"
    }
    

    The ResourceDef & ResourceVal produce the same code, ignoring initializers:

    public interface ResourceVal extends ScalaObject {
        volatile void foo$ResourceVal$_setter_$id_$eq(String s);
        String id();
    }
    
    public interface ResourceDef extends ScalaObject {
        String id();
    }
    

    For the subsidiary classes produced (which contain the implementation of the methods), the ResourceDef produces is as you would expect, noting that the method is static:

    public abstract class ResourceDef$class {
        public static String id(ResourceDef $this) {
            return "5";
        }
    
        public static void $init$(ResourceDef resourcedef) {}
    }
    

    and for the val, we simply call the initialiser in the containing class

    public abstract class ResourceVal$class {
        public static void $init$(ResourceVal $this) {
            $this.foo$ResourceVal$_setter_$id_$eq("5");
        }
    }
    

    When we start extending:

    class ResourceDefClass extends ResourceDef {
      override def id: String = "6"
    }
    
    class ResourceValClass extends ResourceVal {
      override val id: String = "6"
      def foobar() = id
    }
    
    class ResourceNoneClass extends ResourceDef
    

    Where we override, we get a method in the class which just does what you expect. The def is simple method:

    public class ResourceDefClass implements ResourceDef, ScalaObject {
        public String id() {
            return "6";
        }
    }
    

    and the val defines a private field and accessor method:

    public class ResourceValClass implements ResourceVal, ScalaObject {
        public String id() {
            return id;
        }
    
        private final String id = "6";
    
        public String foobar() {
            return id();
        }
    }
    

    Note that even foobar() doesn’t use the field id, but uses the accessor method.

    And finally, if we don’t override, then we get a method which calls the static method in the trait auxiliary class:

    public class ResourceNoneClass implements ResourceDef, ScalaObject {
        public volatile String id() {
            return ResourceDef$class.id(this);
        }
    }
    

    I’ve cut out the constructors in these examples.

    So, the accessor method is always used. I assume this is to avoid complications when extending multiple traits which could implement the same methods. It gets complicated really quickly.

    Even longer answer:

    Josh Suereth did a very interesting talk on Binary Resilience at Scala Days 2012, which covers the background to this question. The abstract for this is:

    This talk focuses on binary compatibility on the JVM and what it means
    to be binary compatible. An outline of the machinations of binary
    incompatibility in Scala are described in depth, followed by a set of rules and guidelines that will help developers ensure their own
    library releases are both binary compatible and binary resilient.

    In particular, this talk looks at:

    • Traits and binary compatibility
    • Java Serialization and anonymous classes
    • The hidden creations of lazy vals
    • Developing code that is binary resilient
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In Scala, I'd like to do: class Identifier(val str: String) { override def toString():
How can I override toString to make this Scala code acts like the following
I had a Scala class as follows: class ClassA(val name: String) { println(this is
given e.g: scala> def pipes(strings:String*) = strings.toList.mkString(|) which I can call normally: scala> pipes(foo,
While playing around with regexps in Scala I wrote something like this: scala> val
scala> val l = List((1,2), (2,3)) l: List[(Int, Int)] = List((1,2), (2,3)) I can
Here's a seq of tuples in Scala val t = Seq((1,2,3),(4,5,6)) I like to
scala> class A (s: String*) { val l: ListBuffer[String] = ListBuffer[String](s) } <console>:8: error:
New to scala and can't seem to find a reference on this situation. I'm
Possible Duplicate: Can anyone explain how the symbol “=>” is used in Scala val

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.