Я только начинаю использовать абстрактные типы. Я сталкиваюсь с ошибкой, которую я не могу полностью понять. Вот некоторые из моего кода для некоторого ФОНЕОшибки с использованием абстрактных типов в 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
во внутреннем классе возвращает ссылку этого типа .
Ниже приводится реализация concerete этого абстрактного класса: ДАЖЕ БОЛЬШЕ ФОН
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, который расширяет абстрактное отображение поля. Я пытаюсь сделать это в модульном тесте следующим образом:
ГДЕ ПРОБЛЕМА ПРОИСХОДИТ
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. Я делаю что-то по своей сути неправильно здесь?
EDIT: Большое спасибо за ответ. В качестве продолжения, у меня также есть вопрос об переопределении? Я замечаю, что в книгах Scala методы, возвращающие абстрактные типы, переопределяются в подтипах, однако я не делаю этого здесь, и компилятор не жалуется на недостающие реализации при создании экземпляров подтипов. Почему в методе подкласса требуется переопределяющий тег, когда тип возвращаемого метода является абстрактным (как определено в базовом классе)?
Возможно, вам нужно позвонить 'getClass'? – 4lex1v