共分散を確保するには、次の 3 つの方法があります。
- 純粋な共分散: Eiffel 言語を使用して、
- 共分散のシミュレーション: キャストとオーバーロードの使用
- F-bounded 多態性 OR 仮想型の使用
したがって、次の例で scala Abstract 型を使用して、仮想型でソリューションをテストしています。
- 3 つの抽象クラスを定義します: Graph、Node、Edge
- Graph クラスは 2 つのメソッドを定義します: attachNode(Node) と detachNode(Node)
- Node クラスは 2 つのメソッドを定義します: attachToGraph(Graph) と detachFromGraph()
継承を使用して、異なるドメインに対して異なるサブクラスを作成します。
- ネットワークの場合:
class Network extends Graph
、およびclass Host extends Node
.. - 化学の場合:
class Molecule extends Graph
、およびclass Atom extends Node
、.. - ...
唯一の制約は、たとえば Atom をネットワークに接続することによって「キメラ」を作成しないようにすることです。したがって、モデルは比較的単純です。
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
}
}
そして、特別なグラフを作成した後は、仮想タイプをオーバーライドするだけです:
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)
この requieredgraph.CompatibleNode
、 found :を呼び出すときに型が一致し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
、仕様を検索して読んだ後、次のことがわかりました:->安定した識別子は識別子で終わるパスです->パスであり、安定したメンバーであるp.x
場合->安定したメンバーは.. ... または非揮発性型の値定義 -> 揮発性型: 型パラメーターまたは抽象型、....p
x
簡単に言えば、 path で抽象型のオブジェクトを使用できないのはなぜですか? 知らない!
そのため、提案がある場合、または scala 抽象型を仮想型として使用できる場合でも。