Master Scala Now: 5 Crucial Differences Between Abstract Classes and Traits You Can't Afford to Miss!

0
317
  1. Introduction  
  2. To understand the difference between an abstract class and a trait, we must first define each term. Traits are similar to Java interfaces, but they allow for the implementation of their members. Abstract classes, on the other hand, are created using the `abstract` keyword and can include both abstract and concrete methods.

2. Commonalities  

Identifying the similarities helps clarify the differences. Let’s examine these features.  

A trait that has a declared and implemented method along with a variable:  

scala

trait mytrait { 

  def myMethod(): Unit

  val aVal: Int 

  val myVal = 10 

  def myImpMethod = { println("I am from trait") } 

}

 

An abstract class that contains both an abstract and a concrete method along with a variable:  

scala

abstract class abstClass { 

  def myMethod(): Unit 

  val aVal: Int 

  val myVal = 10 

  def myImpMethod: Unit = { println("I am from abstClass") } 

}

 

In the main method, neither a trait nor an abstract class can be instantiated:  

scala

val myTObj = new mytrait // compilation error

val myAObj = new abstClass() // compilation error

 

Classes that extend a trait or an abstract class must implement the declared methods:  

scala

class myTClass extends mytrait {

  val aVal = 10 

  def myMethod = { println("I am from myTclass") } 

class myAClass extends abstClass {

  val aVal = 10 

  def myMethod = { println("I am from myAclass") } 

}

 

 

3. Distinctions  

3.1 Constructor Parameters  

scala

trait myTraitWithParam(name: String){} 

abstract class abstClassWithParam(name: String){}

 

The `name` serves as a constructor parameter; using a constructor parameter in a trait leads to a compilation error, while it works correctly in an abstract class.

 

3.2 Modifying Object Instances  

scala

trait objectInstanceTrait { 

  def myObjectMethod = { println("I originate from the object instance trait") } 

class myTClass {} 

def main(args: Array[String]): Unit = { 

  val classObjWithTrait = new myTClass with objectInstanceTrait

  classObjWithTrait.myObjectMethod 

 

Output: "I originate from the object instance trait"  

The method `myObjectMethod` from the trait can be accessed through a class instance. An abstract class cannot be mixed into an object instance, resulting in a compilation error.

 

3.3 Multiple Inheritances  

In multiple inheritance, a single class can inherit from more than one superclass, gaining features from all parent classes. While Scala does not allow multiple inheritance with classes, it can be achieved using traits:  

scala

class myClass extends trait1 with trait2{} 

class myNewClass extends abstClass1 with abstClass2{}

 

Using an abstract class for multiple inheritances results in a compilation error. Scala resolves the diamond problem in multiple inheritance through trait linearization, where the rightmost trait takes precedence:  

scala

trait Printer { 

  def print(msg: String) = println(msg) 

trait DelimitWithHyphen extends Printer { 

  override def print(msg: String) = { println("-------------") } 

trait DelimitWithStar extends Printer { 

  override def print(msg: String) = { println("*") } 

 

class CustomPrinter extends Printer with DelimitWithHyphen with DelimitWithStar 

 

new CustomPrinter().print("Hello World!") 

 

Output: "*"  

 

3.4 Stackability  

Stackable traits in Scala allow for the combination of multiple traits that collaboratively modify a method. This involves calling `super.theMethod`:  

scala

trait base { 

  def baseMethod(s: String): Unit = println(s) 

}

 

trait stack1 extends base {

  override def baseMethod(s: String): Unit = println("from stack1") 

 

trait replace1 extends base { 

  abstract override def baseMethod(s: String): Unit = {

    super.baseMethod(s); 

    println("from replace1")

  } 

}

 

class Stackable { 

  this: base => 

  def apply() { 

    println(baseMethod("bottom")) 

  } 

 

(new Stackable with stack1 with replace1)() 

 

Output:  

from stack1  

from replace1  

The invocation starts with `replace1`, which then calls `stack1` via `super.baseMethod(s)`.

 

3.5 Interoperability with Java  

Traits can seamlessly integrate with Java as long as they lack any implementation; abstract classes can be used directly.

 

 

Search
Sponsored
Categories
Read More
Art
Free PDF Quiz Updated RHCE - Red Hat Certified Engineer - RHCE Answers Free
You can totally rely on our RHCE practice questions, RedHat RHCE Upgrade Dumps When you post the...
By Zihumaja Zihumaja 2022-12-30 03:01:43 0 1K
Other
PPC management company in Delhi
Maximizing Clicks and Conversions: The Role of PPC Management Companies in Delhi Delhi, India's...
By Ganesh Arya 2023-10-13 05:59:04 0 1K
Other
Which airlines have no change fees?
  Sometimes, the customers look to change their flight for specific reasons. The process of...
By Jimmy Anderson 2022-09-01 09:15:29 0 2K
Other
Buy Verified PayPal Accounts For Sale
Buy Verified PayPal Accounts PayPal make easier the global transactions worldwide, providing a...
By Sloane Stokes 2024-03-21 16:24:54 0 752
Shopping
Busimart - Website Development & Branding Company in Nassau
Busimart is the No. 1 Website Development Company & Branding Company in Nassau, Bahamas. It...
By John Williams 2021-08-19 07:37:05 0 2K