scala 从抽象类继承的案例类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7200732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:23:47  来源:igfitidea点击:

Case classes inheriting from abstract class

classscalainheritancecase

提问by Sven Jacobs

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

我目前正在学习 Scala,但在设计案例类时遇到了一些问题。我需要两个具有相同属性的案例类。所以我认为从定义这些属性的抽象基类继承是个好主意。但是这段代码不能编译

abstract class Resource(val uri : String)

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

because uriin the case class constructors would overwrite the uriproperty of the base class.

因为uri在这种情况下,类构造函数会覆盖uri基类的属性。

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

“等效的”Java 代码应该类似于

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);
    }
}

回答by onof

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)
}

回答by Brian Hsu

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

使这两个 case 类扩展一个共同的特征,定义它的接口并且它应该可以工作。

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

顺便说一句,在case语句中的类型子句之前需要一个标识符。

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")
}}