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);
}
}
An abstract class cannot be inherited by structures. It can contain constructors or destructors.
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).
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.
Yes you can do it. An abstract class can extend another non final class having at least one non private constructor.
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)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With