2011-08-26 189 views
17

我目前正在學習Scala,並且在設計我的案例類時遇到了一些問題。我需要兩個具有相同屬性的案例類。所以我認爲從定義這些屬性的抽象基類繼承是一個好主意。但是這個代碼不編譯從抽象類繼承的案例類

abstract class Resource(val uri : String) 

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

因爲uri的情況下類的構造函數將覆蓋基類的uri財產。

什麼是設計這個正確的方法是什麼?

我希望能夠做這樣的事

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

的「當量」的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); 
    } 
} 

回答

25

正確的語法應爲:

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

編輯

不區分類別:

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

但是這會在'File'和'Folder'中複製'uri'屬性和getter。有沒有機會獲得乾淨的代碼,看起來像我的問題中的Java示例? –

+0

那麼你爲什麼使用大小寫類?案例類添加getter和setter。編寫普通類和其伴侶對象。 – onof

+0

因爲這會太多鍋爐代碼? ;-)你能舉個例子嗎? –

5

讓這兩種情況下,類擴展一個共同的特點,其定義它界面,它應該工作。

順便說一句,你需要在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") 
}} 
+1

然而,這uri屬性和getter方法的工作原理存儲在「文件」和「文件夾」(複製)。我希望有一些乾淨的代碼,如上面的Java示例(我已更新我的問題)。 –