Non-numeric Properties

A Non-numeric Properties contains a non-numeric value (i.e. an object).

Idea 1: the value can be in a field or not If it has a field, the Property can't have a value outside the field (i.e. must have a value from the field).

Idea 2: the field could be defined with sets or regular expressions.

A Non-Numeric Property could or not be limited to some field. We couldn't find useful examples for using regular expressions. So we'll only use sets.

We couldn't find useful examples for using intersections, unions or exclusions of sets to define the field. So we'll only use one set (or none). The set should contain one or more values (i.e. a field is a non-null and non-empty set of distinct non-null Objects).

Implementation:
class NonNumericProperty extends Property
{
  NonNumericProperty( String name, Object value) throws IllegalArgument;
  // IllegalArgument if name or value are null
  // no field

  NonNumericProperty( String name, Object value, Field field);
  // IllegalArgument if name or value or field are null

  void setValue( Object value) throws IllegalArgument;
  // IllegalArgument if null value or not in field

  void noField();

  void addToField( Object value);
  // IllegalArgument if null value
  // no error if value already in the field

  void removeFromField( Object value) throws IllegalArgument;
  // IllegalArgument if null value or current value equals to value
  // no error if value is not in the field
}

// immutable
class Field
{
  Field( Object value) throws IllegalArgument;
  // IllegalArgument if value is null

  Field( Object[] values) throws IllegalArgument;
  // IllegalArgument if values is null or one value is null
  // if multiple occurrences, stores only one

  static Field add( Field field, Object value) throws IllegalArgument;
  // IllegalArgument if value is null
  // no error if value already in the field
  // returns a new Field

  static Field add( Field field, Object[] values);
  // IllegalArgument if values or one value is null
  // no error if a value is already in the field
  // if multiple occurrences, stores only one
  // returns a new Field

  static Field remove( Field field, Object value);
  // IllegalArgument if value is null
  // no error if value is not in the field
  // returns a new Field or null if empty

  static Field remove( Field field, Object[] values);
  // IllegalArgument if values or one value is null
  // no error if value is not in the field
  // returns a new Field or null if empty
}