Case Classes Inheriting from Abstract Class

Case Classes Inheriting from Abstract Class

I'm currently learning Scala and I have some problems designing my case classes. I need two case classes that have the same properties. So I thought I would be a good idea to inherit from an abstract base class that defines these properties. However this code does not compile

abstract class Resource(val uri : String)

case class File(uri : String) extends Resource(uri)
case class Folder(uri : String) extends Resource(uri)

because uri in the case class constructors would overwrite the uri property of the base class.

What would be the correct way to design this?

I want to be able to do something like this

val arr = Array[Resource](File("test"), Folder("test2"))

arr.foreach { r : Resource => r match {
  case f : File => println("It's a file")
  case f : Folder => println("It's a folder")
} }

The "equivalent" Java code should be something like

abstract class Resource {
   private String uri;

   public Resource(String uri) {
       this.uri = uri
   }

   public String getUri() {
       return uri;
   }
}

// same for Folder
class File extends Resource {
    public File(String uri) {
        super(uri);
    }
}

2 Answers

The correct syntax should be:

abstract class Resource {
   val uri: String
}

case class File(uri : String) extends Resource
case class Folder(uri : String) extends Resource


Stream[Resource](File("test"), Folder("test2")) foreach { 
  r : Resource => r match {
   case f : File => println("It's a file")
   case f : Folder => println("It's a folder")
} }

EDIT

Without case classes:

abstract class Resource(val uri : String)

class File(uri : String) extends Resource(uri) {
   override def toString = "..."
}
object File {
   def apply(uri: String) = new File(uri)
}

class Folder(uri : String) extends Resource(uri) {
   override def toString = "..."
}
object Folder {
   def apply(uri: String) = new Folder(uri)
}
5

Make these two case class extends a common trait which define it interface and it should work.

BTW, you need an identifier before the type clause in case statement.

trait Resource {
    val uri: String
}

case class File(uri : String) extends Resource
case class Folder(uri : String) extends Resource

val arr = Array[Resource](File("test"), Folder("test2"))

arr.foreach { r : Resource => r match {
  case s: File => println("It's a file")
  case s: Folder => println("It's a folder")
}}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling
Author

James H. Sterling

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.