Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
    }
}
like image 923
Sven Jacobs Avatar asked Aug 26 '11 06:08

Sven Jacobs


People also ask

Can you inherit from an abstract class?

An abstract class cannot be inherited by structures. It can contain constructors or destructors.

Can case class extend another case class?

Extensibility. A class can extend another class, whereas a case class can not extend another case class (because it would not be possible to correctly implement their equality).

Can a class inherit from a non abstract class?

Yes :) Unless it has the final modifier. Show activity on this post. No it doesn't need to have the word abstract, the word abstract just wont allow you to create an instance of that class directly, if you use the word abstract you can only create an instance of the classes that extend that abstract class.

Can abstract class have child?

Yes you can do it. An abstract class can extend another non final class having at least one non private constructor.


1 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)
}
like image 96
onof Avatar answered Oct 22 '22 06:10

onof