세 가지 방법이 있습니다를 사용하여 공분산을 구현 :가상 유형 (추상 유형) 공분산을 보장하기 위해
- 순수 공분산 :
- 이 F-경계를 사용하여 캐스트를 사용하여 오버로드 :
- 공분산을 시뮬레이션하여 에펠 언어, ploymorphism 또는 가상 유형
그래서 가상 유형을 사용하여 솔루션을 테스트하고 있습니다. 다음 예제에서는 초록 유형을 사용합니다.
,- 우리는 3 개 추상 클래스 정의 그래프, 노드, 가장자리를
- 그래프 클래스는이 방법을 정의 attachNode (노드)와 detachNode (노드)
- 는 노드 클래스는이 방법을 정의 attachToGraph (그래프) 및 detachFromGraph()
우리가 서로 다른 도메인에 대해 서로 다른 서브 클래스를 생성합니다 inheretence 사용 : 네트워크 용
- :
class Network extends Graph
및class Host extends Node
.. 화학상
- :
class Molecule extends Graph
및class Atom extends Node
.. 유일한 제약은 예를 들어 원자에 부착하여 "키메라"을 만들지 않도록한다
- ...
회로망. 그래서이 모델은 비교적 간단하다 :
abstract class Graph {
type CompatibleNode <: Node
protected var myNodes = new ArrayBuffer[CompatibleNode]()
def attachNode(node : compatibleNode) = {
....
// Inform the node about the attachement so it can do update
node.attachToGraph(this)
// save the node
myNodes += node
}
}
abstract class Node {
type CompatibleGraph >: scala.Null <: Graph
protected var myGraph : CompatibleGraph = null
def attachToGraph(graph : compatibleGraph) = {
....
// Inform the graph about the attachement so it can do update
graph.attachNode(this)
// save the node
myGraph = graph
}
}
그리고 우리가 가상 종류의 오버라이드 (override) 할 필요가 특별한 그래프 만드는 후
:class Network extends Graph { override type CompatibleNode = Host}
class Host extends Node { override type CompatibleGraph = Network}
class Molecule extends Graph { override type CompatibleNode = Atom}
class Atom extends Node { override type CompatibleGraph = Molecule}
이 잘 (가 NIT 언어로 작동) 작업을해야을하지만 다른했다 오류 : graph.attachNode(this)
를 호출
첫째, 유형 불일치이 발견,
graph.CompatibleNode
를 requiered :Graph
을, 그래서 나는이 캐스팅 :graph.attachNode (this.asInstanceOf [graph.CompatibleNode])를 NIT 언어가 할 것을
참고 암시 적 캐스트.
둘째, detachFromGraph에 대한 그() 메소드 후 :
클래스 노드 {
... def detachFromGraph() = { .... // inform my graph myGraph.detachNode(this.asInstanceOf[myGraph.CompatibleNode]) ... }
}
내가 오류 가지고 : myGraph.compatibleNode : requiered stable identifier
를, 및 검색 후 읽기 사양 내가 찾은 : -> 안정적인 식별자 경로입니다 w en d는 식별자가 ->p.x
이고 경로가 p
이고 경로가 x
이면 안정 멤버 -> 안정 멤버가 ..... 또는 비 휘발성 유형의 값 정의 -> 유형 매개 변수 .... 또는 추상 형식, ....
그래서 요약하면 경로에 추상 형식의 개체를 사용할 수 없습니까? 나는 모른다!
그래서 제안 사항이 있거나 심지어 가상 유형으로 스칼라 추상 유형을 사용할 수있는 경우에도 마찬가지입니다.
def detachFromGraph() {
detachFromThisGraph (myGraph)
}
def detachFromThisGraph (graph : CompatibleGraph) {
graph.detachNode(this.asInstanceOf[graph.CompatibleNode])
}
나는 안정적인 식별자가 조금 생각, 또는 왜 여기에 필요하지 않은 것을 :
나는 에펠는 공분산을 "보장"표시되지 않습니다. 공분산을 다루는 그 방법은 심지어 반공 위치에있을지라도 공변 유형 매개 변수를 허용함으로써 Liskov 대체 원칙을 위반합니다. –
나는 [이 질문] (http://stackoverflow.com/questions/5129943/tightly-coupled-parallel-class-hierarchies-in-c) (나는 비슷한 문제가있다)의 주석을 읽을 수있다. C++에서 이러한 아이디어 중 일부를 구현할 수 있습니다. 아무도 어떻게 알 수 있습니까? –
당신은 어떤 종류의 공분산을 말하고 있습니까? 어쩌면 당신이 당신의 정의를 말할 수 있다면 도움이 될 것입니다. 'attachNode'를 호출하면'this'가'Node' (그리고'attachToGraph'에 대해 vv)와 호환 될 수 없으므로 정의가 불투명합니다. 왜냐하면 당신의 타입 스키마가 호환성 관계를 요구하거나 표현하지 않기 때문입니다 대칭입니다. – gzm0