2016-03-29 12 views
0

私はクラスRBaseとそれを継承するRIntクラスを持っています。 ベースには3つのインターフェイス機能があります。継承するサブクラスは異なるタイプの値を使用できるため、functionパラメーターはAnyとしてタイプされます。その結果、サブクラスを実装するにはasInstanceOfを使用する必要があります。これは一例です。型パラメータvs任意のスカラー

abstract class RBase(val name:String) 
{ 
    def encode(value:Any) : Array[Byte] 
    def decode(byteArray: Array[Byte]) : Any 

    def check(value:Any) : Boolean 
} 

class RInt extends RBase("int") 
{ 
    override def encode(value: Any) = { 
     val byteValue = value.asInstanceOf[Int] 
     Array[Byte](byteValue.toByte, byteValue.toByte, byteValue.toByte) 
    } 
    override def decode(byteArray: Array[Byte]) : Any = { 
     byteArray.size 
    } 
    override def check(value:Any) : Boolean = { 
     val byteValue = value.asInstanceOf[Int] 
     if (byteValue.toInt > 0) true 
     else false 
    } 
} 


object Main extends App { 
    val b = new RInt 
    println(b.decode(Array[Byte]())) 
    println(b.encode(100).mkString(":")) 
    println(b.check(-1)) 
} 

// uncomment when compile 
Main.main(args) 

私はAnyasInstanceOfは型パラメータを用いて除去することができると思います。これが私の最初の試みです。

abstract class TBase(val name:String) 
{ 
    def encode[T](value:T) : Array[Byte] 
    def decode[T](byteArray: Array[Byte]) : T 
    def check[T](value:T) : Boolean 
} 

class TInt extends TBase("bit") 
{ 
    override def encode[Int](value: Int) = { 
     Array[Byte](value.toByte, value.toByte, value.toByte) 
    } 
    override def decode[Int](byteArray: Array[Byte]) : Int = { 
     byteArray.size 
    } 
    override def check[Int](value:Int) : Boolean = { 
     if (value > 0) true 
     else false 
    } 
} 

object Main extends App { 
    val b = new TInt 
    println(b.decode(Array[Byte]())) 
} 

// uncomment when compile 
Main.main(args) 

残念ながら、次のエラーメッセージがあります。

T.scala:11: error: value toByte is not a member of type parameter Int 
     Array[Byte](value.toByte, value.toByte, value.toByte) 
         ^
T.scala:11: error: value toByte is not a member of type parameter Int 
     Array[Byte](value.toByte, value.toByte, value.toByte) 
             ^
T.scala:11: error: value toByte is not a member of type parameter Int 
     Array[Byte](value.toByte, value.toByte, value.toByte) 
                ^
T.scala:14: error: type mismatch; 
found : scala.Int 
required: Int(in method decode) 
     byteArray.size 
       ^
T.scala:17: error: value > is not a member of type parameter Int 
     if (value > 0) true 
       ^
5 errors found 
  • Q1:どれとasInstanceOfを使用していますRBASEアプローチを改善する方法は?
  • Q2:TBaseの何が問題になっていますか?

答えて

2

あなたはあなたのアイデアに非常に近いです。個々のメソッドの代わりにクラス全体をパラメータ化します。

abstract class TBase[T](val name: String) { 
    def encode(value: T): Array[Byte] 
    def decode(byteArray: Array[Byte]): T 
    def check(value: T): Boolean 
} 

class TInt extends TBase[Int]("bit") { 
    override def encode(value: Int) = { 
    Array[Byte](value.toByte, value.toByte, value.toByte) 
    } 
    override def decode(byteArray: Array[Byte]): Int = { 
    byteArray.size 
    } 
    override def check(value: Int): Boolean = { 
    if (value > 0) true 
    else false 
    } 
} 

EDIT:「Int」という型でメソッドをパラメータ化したため、コードが機能しない理由を回答してください。コンパイラはそれが型の名前(T、U、Int、何でも構いません)だと考えます。その場合、戻り値の型は "実際のInt"ではなく、作成された型です。

関連する問題