我剛開始使用抽象類型。我遇到了一個我無法完全理解的錯誤。下面是我的一些代碼,一些背景在Scala中使用抽象類型的錯誤
abstract class DbfReader(fileName: String)
{
type DBFDataType <:Any
type Key <:Any
type Value <:Any
abstract class FieldMapping
{
type FieldType
def acronym: Key
def longName: Key
def fieldNum: Int
def getField: FieldType
def getFieldLength: Int
}
def fieldMappings: Map[ Key, FieldMapping ]
def getFieldCount: Int
def hasRecord(): Boolean
def getRecord(): DBFDataType
def getFieldVal(fieldName: Key)(rowData: DBFDataType): Value
protected def createFieldMapping(fieldAcro: Key,
fieldLongName: Key,
fieldPosition: Int): FieldMapping
....
}
抽象類DbfReader意味着是一個抽象的包裝不同的DBF(數據庫文件)讀庫我想要的。抽象類有一個FieldMapping的內部類(表元數據有一個抽象類型FieldType
,它意味着數據庫字段的底層庫表示的佔位符,內部類中的例程getField
返回這種類型的引用。
以下是該抽象類的沈志南實現:更背景
class MyDBFReader(fileName: String, fmap: List[(String, String, Int)] ) extends DbfReader(fileName)
{
type DBFDataType = Array[Object]
type Key = String
type Value = String
val dbReader = new jdbf.DBFReader(new java.io.FileInputStream(theFile))
val fieldMappings = addFieldMappings(fmap)(Map())
case class InnerFieldMapping(acronym: Key, longName: Key, fieldNum: Int) extends FieldMapping
{
type FieldType = jdbf.JDBField
override def getField: jdbf.JDBField = dbReader.getField(fieldNum)
def getFieldLength = getField.getLength
}
def getFieldCount = dbReader.getFieldCount
def hasRecord = dbReader.hasNextRecord
def getRecord = dbReader.nextRecord
def createFieldMapping(fieldAcro: String, fieldLongName: String, fieldPosition: Int) = InnerFieldMapping(fieldAcro, fieldLongName, fieldPosition)
def getFieldVal(fieldName: Key)(rowData: DBFDataType) = {
if(fieldMappings.keySet.contains(fieldName)) stringer(rowData(fieldMappings(fieldName).fieldNum - 1))
else
throw new NoSuchElementException("Key " + fieldName + " not Found")
}
private def stringer(r: Object) = r.asInstanceOf[String].trim
}
我遇到麻煩的是,當我嘗試調用從InnerFieldMapping getfield命令它擴展了抽象的字段映射。我正在嘗試這樣的單元測試:
問題出在哪裏發生
class MyDBFSuite extends FunSuite {
val fileName = "/Users/Me/api11bdb.dbf"
val dbf = new MyDBFReader(fileName, DbfReader.SchoolFieldMapping)
test("Dbf should have 150 fields")
{
assert(dbf.getFieldCount === 150)
}
test("Should read a record")
{
assert(dbf.hasRecord === true)
assert(dbf.getRecord.size === 150)
}
test("Should Get a Field")
{
println(dbf.fieldMappings.head._2.getField.getType)
//assert(dbf.fieldMappings.head._2.getField.getType === "S")
}
在最後的測試(或者啓用斷言或println的),每當我試圖訪問的getType這是DBFField
例行這是我所期望從內部類InnerFieldMapping
例程getField。在抽象的玻璃常規指定FieldType
返回類型,這是我在具體的類作爲jdbf.JDBFField
但是編譯器說:的問題
src/test/scala/ChinaDBFTestSuite.scala:23: value getType is not a member of MyDBFSuite.this.dbf.FieldMapping#FieldType
[error] println(dbf.fieldMappings.head._2.getField.getType)
[error] ^
在其他測試中,我打電話外部類例程getRecord在其抽象類中返回抽象類型。編譯器在那裏沒有問題。看看錯誤消息,它似乎期望FieldType符合內部抽象類定義。我的意思是我會執行它來查找MyDBFSuite.this.dbg.InnerFieldMapping.FieldType。我在這裏做了一些固有的錯誤嗎?編輯: 非常感謝您的回答。作爲後續,我還有一個關於壓倒一切的問題?我注意到,在scala書中,返回抽象類型的方法在子類型中被覆蓋,但是我不這樣做,編譯器在實例化子類型時不會抱怨丟失的實現。爲什麼當方法的返回類型是抽象類型(如基類中定義的)時,子類方法中需要使用override標記?
也許你需要調用'getClass'? – 4lex1v