Proposal for Keyword abstract
This is a proposal for a new keyword, abstract, to allow for incomplete/partially implemented classes.
Introduction
This proposal expands upon #6, #2946, #2947.
Consider the following situation. A user would like to create a base class that shouldn't be instantiated as a template for derived classes. S/he might write something like
classAnimal{publicage : number;publicyearsLeft(){return20-this.age;}publicmakeSound() : string{return"???";}}classCowextendsAnimal{makeSound(){return"Moo";}}classCatextendsAnimal{makeSound(){return"Meow";}}Today, the writer is forced to make a choice: either (i) Animal can be declared an interface, but then yearsLeft cannot have an implementation, or (ii) write the program as above, but then Animal can be instantiated and makeSound has a bogus implementation! Neither of these options is particularly attractive.
We propose abstract as a class declaration modifier to allow the programmer control over whether a class can be instantiated, and as a member function modifier to control whether said member function offers an implementation (and whether the enclosing class is abstract).
Details
The modifier abstract can prepend a class declaration or a member function declaration. Constructors cannot be declared abstract.
- Objects whose type is
typeof C where C is an abstract-declared class (hereafter abstract class) cannot be instantiated via calls to new. - A member function declared
abstract does not have an implementation. - Abstract methods cannot be called within a class member function body via
super.foo() where foo is an abstract method belonging to the parent class. - Abstract methods may be called within a class member function body via
this.foo() where foo is an abstract method belonging to that class. - If a class has any abstract methods, then the class itself must be declared abstract.
- Abstract methods are inherited.
- Abstract methods can be overridden in the derived class, either by an abstract method (effectively a re-declaration) or a function declaration that offers an implementation.
- A method cannot be simultaneously
abstract and static. - A method cannot be simultaneously
abstract and private. - If an abstract member declaration contains an explicit accessibility modifier, then the modifier must precede the
abstract keyword. - Overloads on a member function must be either all abstract or all not abstract.
- Overloads of abstract member functions must be declared adjacent to eachother.
- Objects whose type is the type of an abstract class can only be assigned to other objects whose type is the type of an abstract class. For example,
The following code snippet summarizes valid and invalid usages of the abstract keyword
classA{// ...}abstractclassB{foo(): number{returnbar();}abstractbar() : number;}newB;// errorimportmyB=B;newmyB;// errorvarBB: typeofB=B;varAA: typeofA=BB;// error, AA is not of abstract type.newAA;functionconstructB(Factory : typeofB){newFactory;// error -- Factory is of type typeof C}varBB=B;newBB;// error -- BB is of type typeof Cvarx : any=C;newx;// okay -- undefined behavior at runtimeclassCextendsB{}// error -- not declared abstractabstractclassDextendsB{}// okayclassEextendsB{// okay -- implements abstract methodbar(){return1;}abstractclassFextendsB{abstractfoo() : number;bar(){return2;}}abstractclassF{abstractqux(x : number) : string;abstractqux() : number;y : number;abstractquz(x : number,y : string) : boolean;// error -- declarations must be adjacentabstractnom()boolean;nom(x : number)boolean: // error -- use of modifier abstract must match on all overloads.}classG{// error -- not declared abstractabstractbaz() : number;}Pros
- Allows the programmer to write partial implementations of a class.
- Provides a mechanism for the type system to warn about classes that shouldn't be instantiated.
abstract annotations clarify the role of base classes in various patterns.
Cons
- Increases the complexity of the language.
To Be Discussed
- Should abstract be allowed within class expressions?
Proposed Changes to Grammar
A.6 Classes
ClassDeclaration:
abstractopt class IdentifierTypeParametersoptClassHeritage { ClassBody }
MemberFunctionDeclaration:
MemberFunctionOverloadsoptMemberFunctionImplementation
AbstractMemberFunctionOverloads
AbstractMemberFunctionOverloads:
AbstractMemberFunctionOverload
AbstractMemberFunctionOverloadsAbstractMemberFunctionOverload
AbstractMemberFunctionOverload:
AccessibilityModifieropt abstract PropertyNameCallSignature ;
A.10 Ambients
AmbientClassDeclaration:
abstractopt class IdentifierTypeParametersoptClassHeritage { AmbientClassBody }
AbstractOrStatic:
abstract
static
AmbientPropertyMemberDeclaration:
AccessibilityModifieroptAbstractOrStaticoptPropertyNameCallSignature ;
EDIT: updated to clarify the assignability of objects of "abstract type".
Proposal for Keyword
abstractThis is a proposal for a new keyword,
abstract, to allow for incomplete/partially implemented classes.Introduction
This proposal expands upon #6, #2946, #2947.
Consider the following situation. A user would like to create a base class that shouldn't be instantiated as a template for derived classes. S/he might write something like
Today, the writer is forced to make a choice: either (i) Animal can be declared an interface, but then
yearsLeftcannot have an implementation, or (ii) write the program as above, but then Animal can be instantiated andmakeSoundhas a bogus implementation! Neither of these options is particularly attractive.We propose
abstractas a class declaration modifier to allow the programmer control over whether a class can be instantiated, and as a member function modifier to control whether said member function offers an implementation (and whether the enclosing class is abstract).Details
The modifier
abstractcan prepend a class declaration or a member function declaration. Constructors cannot be declared abstract.typeof CwhereCis anabstract-declared class (hereafter abstract class) cannot be instantiated via calls tonew.abstractdoes not have an implementation.super.foo()wherefoois an abstract method belonging to the parent class.this.foo()wherefoois an abstract method belonging to that class.abstractandstatic.abstractandprivate.abstractkeyword.The following code snippet summarizes valid and invalid usages of the
abstractkeywordPros
abstractannotations clarify the role of base classes in various patterns.Cons
To Be Discussed
Proposed Changes to Grammar
A.6 Classes
ClassDeclaration:
abstractopt class IdentifierTypeParametersoptClassHeritage { ClassBody }
MemberFunctionDeclaration:
MemberFunctionOverloadsoptMemberFunctionImplementation
AbstractMemberFunctionOverloads
AbstractMemberFunctionOverloads:
AbstractMemberFunctionOverload
AbstractMemberFunctionOverloadsAbstractMemberFunctionOverload
AbstractMemberFunctionOverload:
AccessibilityModifieropt abstract PropertyNameCallSignature ;
A.10 Ambients
AmbientClassDeclaration:
abstractopt class IdentifierTypeParametersoptClassHeritage { AmbientClassBody }
AbstractOrStatic:
abstract
static
AmbientPropertyMemberDeclaration:
AccessibilityModifieroptAbstractOrStaticoptPropertyNameCallSignature ;
EDIT: updated to clarify the assignability of objects of "abstract type".