I am designing a language for my own purposes. It will have two entities basically, functions and types. e.g.
Object1 = CreateObject1("param1", "param2", 23 ) //Line 1
Object3 = Object1 + Object2 //Line 2
Evaluate(Object3) //Line 3
Line 2 evaluates if object of type Object1 be "+" to Object2 and if yes then a resultant object will be created and will be assigned to Object3. The variable definitions are like var keyword in Java Script.
The design in my mind is like creating a base "Value" class (having primitive operations like add, subtract, multiply, divide etc) having concrete children each corresponding to dif开发者_运维技巧ferent types which I plan to ingest in the language.
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.
}
}
I can create children classes like that easily but if a function changes the attributes of a object (like a member value be changed of a class) then I need to downcast to it to that type and update the appropriate property.
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)
In the implemenatiob of the function SetX(). I will be doing something like this:
ABC abc = (ABC)ObjectABC; //ObjectABC will be a Value type here.
abc.setX( 1 );
I want to get rid of this down casting thing. Can it be done? Please advise.
You could use double dispatch like so:
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;
}
}
精彩评论