These are common object-oriented mechanisms. However, they can make code difficult to understand and have unexpected effects. Therefore we will support them, but see them as the exception. By default methods are non-abstract and non-virtual: FUNC funcy(ArgType arg): RetType
# this function cannot be replaced in a subclass
}
FUNC funcy(ArgType arg): RetType @abstract }
The body of this function is not defined and makes the class abstract, it can't be instantiated.
FUNC funcy(ArgType arg): RetType @default
# this function can be replaced in a subclass
}This function provides a default implementation. Replacing it in a subclass is optional. This does not prevent the class from being instantiated. An alternative would be to put the attribute before "FUNC": ABSTRACT FUNC DEFAULT FUNCThis has two problems: - DEFAULT already is used in a SWITCH statement. It would then need to be called VIRTUAL, which does not have an obvious meaning.
- It is harder to read text with several words in capitals.
Methods without "@abstract" or "@default" cannot be replaced in a subclass. This makes it easier to be sure about what method is actually used, no need to check all subclasses if they replace the method. - An abstract function must be defined in a subclass.
- A virtual function can be redefined in a subclass.
- All other functions can't be redefined in a subclass.
The need for @replace and @defineWhen modifying code there is a danger of adding a virtual method to a base class while the subclass already has this method, where there was no intention of replacing the method of the base class. For example, the subclass defines an error() method and the base class doesn't. When a virtual error() method is added to the base class, this would go unnoticed. Even though the error() method in the subclass might need to be adjusted for the changed base class. This leads to hard to track down bugs. Therefore: defining a function from the base class must be marked with the @define attribute to define an abstract method, and @replace to replace a virtual method. CLASS FooBase @abstract
FUNC toString(): string @abstract } PROC error() @default
IO.write("Error!")
}
}
CLASS FooChild EXTENDS FooBase
FUNC toString(): string @define # defining abstract method
RETURN something
}
PROC error() @replace # replacing default method
IO.write("In FooChild: ")
PARENT.error()
}
PROC foo() # new method
...
} }
Also support inheritance for list, dict and tuple. Example:
CLASS SymbolList EXTENDS list<Symbol>
FUNC find(string name, SymbolType type): Symbol
FOR sym IN PARENT
IF sym.name == name && sym.type == type
RETURN sym
}
}
}
}
This has not been implemented yet.
|