2011-02-15 69 views
1

我正在为我自己的目的设计一种语言。它基本上有两个实体,功能和类型。例如用于设计语言类型系统的正确的类设计

Object1 = CreateObject1("param1", "param2", 23) //Line 1 
Object3 = Object1 + Object2 //Line 2 
Evaluate(Object3) //Line 3 

第2行的计算结果,如果类型的对象Object1是“+”至Object2的,并且如果然后所得对象将被创建并且是将被分配到Object3。变量定义就像Java脚本中的var关键字。

我脑海中的设计就像创建一个基本的“价值”类(具有像加,减,乘,除等基本操作)具有具体的孩子,每个孩子对应我计划用语言摄入的不同类型。

class Value{ 
Value add(Value value) 
.. 
} 

class Integer extends Value{ 
Value add(Value value){ 
    //if value is compatible to add with Integer type then return the appropriate  
    //resultant object else throw exception. 
} 
} 

我可以轻松地创建孩子类这样的,但如果一个函数变化的对象的属性(如一个部件值被改变的类的),然后我需要向下转换到它于该类型,更新相应的属性。

class ABC extends Value{ 
Value add(Value value){ 
// 
} 

private int X; 
private int Y; 
private int Z; 
private string XYZ; 

public setX(int x){ 
    this.X = x; 
} 
. 
. 
} 

ObjectABC = GetABC(); 
SetX(ObjectABC, 1) 

在函数SetX()的实现中。我会做这样的事情:

ABC abc = (ABC)ObjectABC; //ObjectABC will be a Value type here. 
abc.setX(1); 

我想摆脱这倒下来铸造的东西。可以做到吗?请指教。

+0

通常有办法消除铸造,但我认为你需要提供正是你在做什么的更多信息。例如,谁定义了ABC对象?这是用你的语言定义还是用Java定义的?至少,试着用你的语言展示一个完整的示例程序。 – 2011-04-02 01:24:00

回答

0

你可以使用双调度像这样:

abstract class Value { 
    Value add(Value v) { throw new InvalidArgumentException("add", getClass(), v); } 
    Value addInteger(Integer i); 

    Value divide(Value) { throw new InvalidArgumentException("divide", getClass(), v); } 
    Value divideIntegerReversed(Integer i); 

} 

class Integer extends Value { 
    @Override 
    Value add(Value v) { 
    return v.addInteger(this); 
    } 

    @Override  
    Value addInteger(Integer other) { 
     // note the argument reversal but not worries because addition is commutative 
     return whtvr; 
    } 

    @Override 
    Value divide(Value v) { 
    return v.divideIntegerReversed(this); 
    } 

    @Override 
    Value divideIntegerReversed(Integer nom) { 
    // note that we now want `nom/this` and not `this/nom` 
    return wthvr; 
    } 
}