2015-07-05 1 views
0

В зависимости от пути, который зависит от пути, как вы указываете для конкретного объекта-объекта, что этот признак должен поддерживать дополнительную функцию? override trait? Как вы относитесь к исходной черте, которую расширяет вычитание?Как абстрактно расширить зависимую от пути черту: «переопределить признак»?

В частности, я хочу, чтобы переопределить Delta признака в каждом DeltaSet объекта:

trait DeltaSet { 
    type PertainsTo 

    trait Delta { 
    val pertainsTo: PertainsTo 
    } 
    . . . 
} 

В английском языке это

«в том же DeltaSet Каждый Delta должны относиться к тому же рода вещи.» A DeltaSet объект должен иметь возможность добавлять дополнительные атрибуты к значению Delta, например source здесь:

val deltaSet = new DeltaSet { 
    override type PertainsTo = UnorderedPair[TestNode] 

    override trait Delta /* extends DeltaSet.Delta?? */ { // <-- THE MYSTERY 
    val source: TestNode 
    } 
    . . . 
} 

В английском языке это «Каждый Delta для deltaSet также должен обеспечить источник.»

Так, Delta классов для использования с этим DeltaSet объектом должны переопределить атрибут source, например:

case class MakeLinkDelta(fromNode: TestNode, toNode: TestNode) 
    extends deltaSet.Delta 
{ 
    override val pertainsTo = new UnorderedPair(fromNode, toNode) 
    override val source = fromNode 
    . . . 
} 

и аналогично для BreakLinkDelta и других Deltas для deltaSet. (Каждый Delta для этого DeltaSet описывает изменения, которые необходимо внести в график. Другие DeltaSet s содержат изменения совершенно разные виды объектов.)

Я пробовал много вариантов, в том числе trait BaseDelta {...}; type DeltaT <: BaseDelta, и до сих пор ни один из них скомпилирован. Как вы «говорить» в Scala, «Для всего одного DeltaSet, я хочу, чтобы требовать, чтобы каждый Delta обеспечить атрибут source

ответ

0

Продлить DeltaSet и его Delta добавив source атрибут:

trait DeltaSetTN extends DeltaSet { 
    override type PertainsTo = UnorderedPair[TestNode] 
    trait DeltaTN extends Delta { 
    val source: TestNode 
    } 
} 

Тогда:

class MakeLinkDelta(fromNode: TestNode, toNode: TestNode) extends DeltaSetTN { 
    val delta = new DeltaTNImpl() 
    class DeltaTNImpl extends DeltaTN { 
    override val source = fromNode 
    override val pertainsTo = new UnorderedPair[TestNode](fromNode, toNode) 
    } 
} 

Вы можете быть заинтересованы в этом blog post о инъекции зависимостей в Scala и образец торта.

+0

Можете ли вы объясните соответствующий принцип работы здесь? «Вы не можете переопределить зависящую от пути черту в анонимном классе»? «Вы не можете переопределить признак, зависящий от пути, где угодно»? «Каждый объект, зависящий от пути (' Delta'), должен расширять контейнер («DeltaSet')»? Я надеюсь, что последнее не является истинным принципом. –

+0

Мы не можем переопределить черту. Для этого мы расширяем и переопределяем его элементы. Не уверен, что я понимаю ваш последний момент. При создании экземпляра черта не может оставаться признаком. – bjfletcher

+0

Спасибо за «Мы не можем переопределить черту». (Может быть, это может пойти в ответ.) Уточнение последнего момента: в вашем решении класс Delta расширяет черту DeltaSet. Это кажется мне странным, например, сказать, что кубок - это своего рода шкаф. Есть ли какой-то принцип Scala, который требует этого? –

2

Это работает:

(1) Определение базы trait в ограждающей черте, и сделать его верхней границей для абстрактного type.

(2) Создайте контейнерный объект с оператором object, а не оператором val.

(3) Поставьте класс переопределения на object, определяя прилагаемый trait с тем же именем, что и реферат type. Это определение должно распространять базу trait и должно быть не имеет ключевое слово override.


Вот (1), охватывающий черт:

trait DeltaSet { 
    type PertainsTo 

    trait BaseDelta { 
    val pertainsTo: PertainsTo 
    } 

    type Delta <: BaseDelta   // <-- Since this is now a type, we can override it... 
    . . . 
} 

Вот (2), object, который определяет конкретный DeltaSet, и (3), класс коррекция, который определяет Delta:

Я предполагаю, что причина, по которой object компиляции и val не удается, состоит в том, что val не определяет mespace, и нам нужно пространство имен для того, чтобы обратиться к закрытой, переопределен Delta признак, когда мы подклассы его здесь: (. Эта последняя часть не отличается от кода в вопросе)

case class MakeLinkDelta(fromNode: TestNode, toNode: TestNode) 
    extends deltaSet.Delta   // Since deltaSet is a namespace, the dot syntax can refer 
{         // to the Delta trait inside it. 
    override val pertainsTo = new UnorderedPair(fromNode, toNode) 
    override val source = fromNode 
    . . . 
}