Правильный дизайн класса для разработки системы языковых типов - PullRequest
1 голос
/ 15 февраля 2011

Я создаю язык для своих собственных целей.Он будет состоять из двух объектов: функций и типов.например,

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

В строке 2 оценивается, будет ли объект типа Object1 иметь «+» для Object2 и если да, то результирующий объект будет создан и назначен для Object3.Определения переменных похожи на ключевое слово var в Java Script.

Дизайн, на мой взгляд, похож на создание базового класса «Value» (с такими примитивными операциями, как сложение, вычитание, умножение, деление и т. Д.), Имеющего конкретных потомков, каждый из которых соответствуетк различным типам, которые я планирую использовать в языке.

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 );

Я хочу избавиться от этой вещи с понижением рейтинга.Это можно сделать?Пожалуйста, сообщите.

1 Ответ

0 голосов
/ 28 ноября 2013

Вы можете использовать двойную отправку следующим образом:

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;
   }
}
...