codekingpro/portable-devtools
114k
1*vim9class.txt* For Vim version 9.2. Last change: 2026 Mar 072 3 4 VIM REFERENCE MANUAL by Bram Moolenaar5 6 7Vim9 classes, objects, interfaces, types and enums. *vim9-class*8 91. Overview |Vim9-class-overview|102. A simple class |Vim9-simple-class|113. Class variables and methods |Vim9-class-member|124. Using an abstract class |Vim9-abstract-class|135. Using an interface |Vim9-using-interface|146. More class details |Vim9-class|157. Type definition |Vim9-type|168. Enum |Vim9-enum|17 189. Rationale1910. To be done later20 21==============================================================================22 231. Overview *Vim9-class-overview*24 25The fancy term is "object-oriented programming". You can find lots of study26material on this subject. Here we document what |Vim9| script provides,27assuming you know the basics already. Added are helpful hints about how to28use this functionality effectively. Vim9 classes and objects cannot be used29in legacy Vim scripts and legacy functions.30 31The basic item is an object:32- An object stores state. It contains one or more variables that can each33 have a value.34- An object provides functions that use and manipulate its state. These35 functions are invoked "on the object", which is what sets it apart from the36 traditional separation of data and code that manipulates the data.37- An object has a well defined interface, with typed member variables and38 methods.39- Objects are created from a class and all objects have the same interface.40 This does not change at runtime, it is not dynamic.41 42An object can only be created by a class. A class provides:43- A new() method, the constructor, which returns an object for the class.44 This method is invoked on the class name: MyClass.new().45- State shared by all objects of the class: class variables (class members).46- A hierarchy of classes, with super-classes and sub-classes, inheritance.47 48An interface is used to specify properties of an object:49- An object can declare several interfaces that it implements.50- Different objects implementing the same interface can be used the same way.51 52The class hierarchy allows for single inheritance. Otherwise interfaces are53to be used where needed.54 55Class modeling ~56 57You can model classes any way you like. Keep in mind what you are building,58don't try to model the real world. This can be confusing, especially because59teachers use real-world objects to explain class relations and you might think60your model should therefore reflect the real world. It doesn't! The model61should match your purpose.62 63Keep in mind that composition (an object contains other objects) is often64better than inheritance (an object extends another object). Don't waste time65trying to find the optimal class model. Or waste time discussing whether a66square is a rectangle or that a rectangle is a square. It doesn't matter.67 68 69==============================================================================70 712. A simple class *Vim9-simple-class*72 73Let's start with a simple example: a class that stores a text position (see74below for how to do this more efficiently): >75 76 class TextPosition77 var lnum: number78 var col: number79 80 def new(lnum: number, col: number)81 this.lnum = lnum82 this.col = col83 enddef84 85 def SetLnum(lnum: number)86 this.lnum = lnum87 enddef88 89 def SetCol(col: number)90 this.col = col91 enddef92 93 def SetPosition(lnum: number, col: number)94 this.lnum = lnum95 this.col = col96 enddef97 endclass98< *object* *Object*99You can create an object from this class with the new() method: >100 101 var pos = TextPosition.new(1, 1)102<103The object variables "lnum" and "col" can be accessed directly: >104 105 echo $'The text position is ({pos.lnum}, {pos.col})'106< *E1317* *E1327* *:this*107If you have been using other object-oriented languages you will notice that in108Vim, within a class definition, the declared object members are consistently109referred to with the "this." prefix. This is different from languages like110Java and TypeScript. The naming convention makes the object members easy to111spot. Also, when a variable does not have the "this." prefix you know it is112not an object variable.113 *E1411*114From outside the class definition, access an object's methods and variables by115using the object name followed by a dot following by the member: >116 117 pos.lnum118 pos.SetCol(10)119<120 *E1405* *E1406*121A class name cannot be used as an expression. A class name cannot be used in122the left-hand-side of an assignment.123 124Object variable write access ~125 *read-only-variable*126Now try to change an object variable directly: >127 128 pos.lnum = 9129< *E1335*130This will give you an error! That is because by default object variables can131be read but not set. That's why the TextPosition class provides a method for132it: >133 134 pos.SetLnum(9)135 136Allowing to read but not set an object variable is the most common and safest137way. Most often there is no problem using a value, while setting a value may138have side effects that need to be taken care of. In this case, the SetLnum()139method could check if the line number is valid and either give an error or use140the closest valid value.141 *:public* *public-variable* *E1331*142If you don't care about side effects and want to allow the object variable to143be changed at any time, you can make it public: >144 145 public var lnum: number146 public var col: number147 148Now you don't need the SetLnum(), SetCol() and SetPosition() methods, setting149"pos.lnum" directly above will no longer give an error.150 *E1326*151If you try to set an object variable that doesn't exist you get an error: >152 pos.other = 9153< E1326: Member not found on object "TextPosition": other ~154 155 *E1376*156A object variable cannot be accessed using the class name.157 158Protected variables ~159 *protected-variable* *E1332* *E1333*160On the other hand, if you do not want the object variables to be read directly161from outside the class or its sub-classes, you can make them protected. This162is done by prefixing an underscore to the name: >163 164 var _lnum: number165 var _col: number166 167Now you need to provide methods to get the value of the protected variables.168These are commonly called getters. We recommend using a name that starts with169"Get": >170 171 def GetLnum(): number172 return this._lnum173 enddef174 175 def GetCol(): number176 return this._col177 enddef178 179This example isn't very useful, the variables might as well have been public.180It does become useful if you check the value. For example, restrict the line181number to the total number of lines: >182 183 def GetLnum(): number184 if this._lnum > this._lineCount185 return this._lineCount186 endif187 return this._lnum188 enddef189<190Protected methods ~191 *protected-method* *E1366*192If you want object methods to be accessible only from other methods of the193same class and not used from outside the class, then you can make them194protected. This is done by prefixing the method name with an underscore: >195 196 class SomeClass197 def _Foo(): number198 return 10199 enddef200 def Bar(): number201 return this._Foo()202 enddef203 endclass204<205Accessing a protected method outside the class will result in an error (using206the above class): >207 208 var a = SomeClass.new()209 a._Foo()210<211Simplifying the new() method ~212 *new()* *constructor*213See also |default-constructor| and |multiple-constructors|.214 215Many constructors take values for the object variables. Thus you very often216see this pattern: >217 218 class SomeClass219 var lnum: number220 var col: number221 222 def new(lnum: number, col: number)223 this.lnum = lnum224 this.col = col225 enddef226 endclass227<228 *E1390*229Not only is this text you need to write, it also has the type of each230variable twice. Since this is so common a shorter way to write new() is231provided: >232 233 def new(this.lnum, this.col)234 enddef235 236The semantics are easy to understand: Providing the object variable name,237including "this.", as the argument to new() means the value provided in the238new() call is assigned to that object variable. This mechanism comes from the239Dart language.240 241Putting together this way of using new() and making the variables public242results in a much shorter class definition than what we started with: >243 244 class TextPosition245 public var lnum: number246 public var col: number247 248 def new(this.lnum, this.col)249 enddef250 251 def SetPosition(lnum: number, col: number)252 this.lnum = lnum253 this.col = col254 enddef255 endclass256 257The sequence of constructing a new object is:2581. Memory is allocated and cleared. All values are zero/false/empty.2592. For each declared object variable that has an initializer, the expression260 is evaluated and assigned to the variable. This happens in the sequence261 the variables are declared in the class.2623. Arguments in the new() method in the "this.name" form are assigned.2634. The body of the new() method is executed.264 265If the class extends a parent class, the same thing happens. In the second266step the object variables of the parent class are initialized first. There is267no need to call "super()" or "new()" on the parent.268 269 *E1365*270When defining the new() method the return type should not be specified. It271always returns an object of the class.272 273The new() method can be made a protected method by using "_new()". This can274be used to support the singleton design pattern.275 276 *E1386*277When invoking an object method, the method name should be preceded by the278object variable name. An object method cannot be invoked using the class279name.280 281==============================================================================282 2833. Class Variables and Methods *Vim9-class-member*284 285 *:static* *E1329* *E1337* *E1338* *E1368*286Class members are declared with "static". They are used by the name without a287prefix in the class where they are defined: >288 289 class OtherThing290 var size: number291 static var totalSize: number292 293 def new(this.size)294 totalSize += this.size295 enddef296 endclass297< *E1340* *E1341*298Since the name is used as-is, shadowing the name by a method argument name299or local variable name is not allowed.300 301 *E1374* *E1375* *E1384* *E1385*302To access a class member outside of the class where it is defined, the class303name prefix must be used. A class member cannot be accessed using an object.304 305Just like object members the access can be made protected by using an306underscore as the first character in the name, and it can be made public by307prefixing "public": >308 309 class OtherThing310 static var total: number # anybody can read, only class can write311 static var _sum: number # only class can read and write312 public static var result: number # anybody can read and write313 endclass314<315 *class-method*316Class methods are also declared with "static". They can use the class317variables but they have no access to the object variables, they cannot use the318"this" keyword:319>320 class OtherThing321 var size: number322 static var totalSize: number323 324 # Clear the total size and return the value it had before.325 static def ClearTotalSize(): number326 var prev = totalSize327 totalSize = 0328 return prev329 enddef330 endclass331 332Inside the class, the class method can be called by name directly, outside the333class, the class name must be prefixed: `OtherThing.ClearTotalSize()`. Also,334the name prefix must be used for public class methods in the special contexts335of class variable initializers and of lambda expressions and nested functions:336>337 class OtherThing338 static var name: string = OtherThing.GiveName()339 340 static def GiveName(): string341 def DoGiveName(): string342 return OtherThing.NameAny()343 enddef344 345 return DoGiveName()346 enddef347 348 static def NameAny(): string349 return "any"350 enddef351 endclass352<353 354Just like object methods the access can be made protected by using an355underscore as the first character in the method name: >356 357 class OtherThing358 static def _Foo()359 echo "Foo"360 enddef361 def Bar()362 _Foo()363 enddef364 endclass365<366 *E1370*367Note that constructors cannot be declared as "static". They are called like a368static but execute as an object method; they have access to "this".369 370To access the class methods and class variables of a super class in an371extended class, the class name prefix should be used just as from anywhere372outside of the defining class: >373 374 vim9script375 class Vehicle376 static var nextID: number = 1000377 static def GetID(): number378 nextID += 1379 return nextID380 enddef381 endclass382 class Car extends Vehicle383 var myID: number384 def new()385 this.myID = Vehicle.GetID()386 enddef387 endclass388<389Class variables and methods are not inherited by a child class. A child class390can declare a static variable or a method with the same name as the one in the391super class. Depending on the class where the member is used the392corresponding class member will be used. The type of the class member in a393child class can be different from that in the super class.394 395The double underscore (__) prefix for a class or object method name is396reserved for future use.397 398 *object-final-variable* *E1409*399The |:final| keyword can be used to make a class or object variable a400constant. Examples: >401 402 class A403 final v1 = [1, 2] # final object variable404 public final v2 = {x: 1} # final object variable405 static final v3 = 'abc' # final class variable406 public static final v4 = 0z10 # final class variable407 endclass408<409A final variable can be changed only from a constructor function. Example: >410 411 class A412 final v1: list<number>413 def new()414 this.v1 = [1, 2]415 enddef416 endclass417 var a = A.new()418 echo a.v1419<420Note that the value of a final variable can be changed. Example: >421 422 class A423 public final v1 = [1, 2]424 endclass425 var a = A.new()426 a.v1[0] = 6 # OK427 a.v1->add(3) # OK428 a.v1 = [3, 4] # Error429<430 *E1408*431Final variables are not supported in an interface. A class or object method432cannot be final.433 434 *object-const-variable*435The |:const| keyword can be used to make a class or object variable and the436value a constant. Examples: >437 438 class A439 const v1 = [1, 2] # const object variable440 public const v2 = {x: 1} # const object variable441 static const v3 = 'abc' # const class variable442 public static const v4 = 0z10 # const class variable443 endclass444<445A const variable can be changed only from a constructor function. Example: >446 447 class A448 const v1: list<number>449 def new()450 this.v1 = [1, 2]451 enddef452 endclass453 var a = A.new()454 echo a.v1455<456A const variable and its value cannot be changed. Example: >457 458 class A459 public const v1 = [1, 2]460 endclass461 var a = A.new()462 a.v1[0] = 6 # Error463 a.v1->add(3) # Error464 a.v1 = [3, 4] # Error465<466 *E1410*467Const variables are not supported in an interface. A class or object method468cannot be a const.469 470==============================================================================471 4724. Using an abstract class *Vim9-abstract-class*473 474An abstract class forms the base for at least one sub-class. In the class475model one often finds that a few classes have the same properties that can be476shared, but a class with these properties does not have enough state to create477an object from. A sub-class must extend the abstract class and add the478missing state and/or methods before it can be used to create objects for.479 480For example, a Shape class could store a color and thickness. You cannot481create a Shape object, it is missing the information about what kind of shape482it is. The Shape class functions as the base for a Square and a Triangle483class, for which objects can be created. Example: >484 485 abstract class Shape486 var color = Color.Black487 var thickness = 10488 endclass489 490 class Square extends Shape491 var size: number492 493 def new(this.size)494 enddef495 endclass496 497 class Triangle extends Shape498 var base: number499 var height: number500 501 def new(this.base, this.height)502 enddef503 endclass504<505An abstract class is defined the same way as a normal class, except that it506does not have any new() method. *E1359*507 508 *abstract-method* *E1371* *E1372*509An abstract method can be defined in an abstract class by using the "abstract"510prefix when defining the method: >511 512 abstract class Shape513 abstract def Draw()514 endclass515<516A static method in an abstract class cannot be an abstract method.517 518 *E1404*519An interface method cannot be an abstract method.520 521 *E1373*522A non-abstract class extending the abstract class must implement all the523abstract methods. The signature (arguments, argument types and return type)524must be exactly the same. If the return type of a method is a class, then525that class or one of its subclasses can be used in the extended method.526 527 *E1431*528An abstract method in an abstract super class cannot be invoked.529 530==============================================================================531 5325. Using an interface *Vim9-using-interface*533 534The example above with Shape, Square and Triangle can be made more useful if535we add a method to compute the surface of the object. For that we create the536interface called HasSurface, which specifies one method Surface() that returns537a number. This example extends the one above: >538 539 abstract class Shape540 var color = Color.Black541 var thickness = 10542 endclass543 544 interface HasSurface545 def Surface(): number546 endinterface547 548 class Square extends Shape implements HasSurface549 var size: number550 551 def new(this.size)552 enddef553 554 def Surface(): number555 return this.size * this.size556 enddef557 endclass558 559 class Triangle extends Shape implements HasSurface560 var base: number561 var height: number562 563 def new(this.base, this.height)564 enddef565 566 def Surface(): number567 return this.base * this.height / 2568 enddef569 endclass570<571 *E1348* *E1349* *E1367* *E1382* *E1383*572If a class declares to implement an interface, all the items specified in the573interface must appear in the class, with the same types.574 575The interface name can be used as a type: >576 577 var shapes: list<HasSurface> = [578 Square.new(12),579 Triangle.new(8, 15),580 ]581 for shape in shapes582 echo $'the surface is {shape.Surface()}'583 endfor584<585 *E1378* *E1379* *E1380* *E1387*586An interface can contain only object methods and read-only object variables.587An interface cannot contain read-write or protected object variables,588protected object methods, class variables and class methods.589 590An interface can extend another interface using "extends". The sub-interface591inherits all the instance variables and methods from the super interface.592 593An interface cannot be defined inside a function. *E1436*594 595==============================================================================596 5976. More class details *Vim9-class* *Class* *class*598 599Defining a class ~600 *:class* *:endclass* *:abstract*601A class is defined between `:class` and `:endclass`. The whole class is602defined in one script file. It is not possible to add to a class later.603 604A class can only be defined in a |Vim9| script file. *E1316*605A class cannot be defined inside a function. *E1429*606 607It is possible to define more than one class in a script file. Although it608usually is better to export only one main class. It can be useful to define609types, enums and helper classes though.610 611The `:abstract` keyword may be prefixed and `:export` may be used. That gives612these variants: >613 614 class ClassName615 endclass616 617 export class ClassName618 endclass619 620 abstract class ClassName621 endclass622 623 export abstract class ClassName624 endclass625<626 *E1314*627The class name should be CamelCased. It must start with an uppercase letter.628That avoids clashing with builtin types.629 *E1315*630After the class name these optional items can be used. Each can appear only631once. They can appear in any order, although this order is recommended: >632 extends ClassName633 implements InterfaceName, OtherInterface634 specifies SomeInterface635<636The "specifies" feature is currently not implemented.637 638 *E1355* *E1369*639Each variable and method name can be used only once. It is not possible to640define a method with the same name and different type of arguments. It is not641possible to use a public and protected member variable with the same name. An642object variable name used in a super class cannot be reused in a child class.643 644Object Variable Initialization ~645 646 *E1430*647If the type of a variable is not explicitly specified in a class, then it is648set to "any" during class definition. When an object is instantiated from the649class, then the type of the variable is set.650 651The following reserved keyword names cannot be used as an object or class652variable name: "super", "this", "true", "false", "null", "null_blob",653"null_channel", "null_class", "null_dict", "null_function", "null_job",654"null_list", "null_object", "null_partial" and "null_string".655 656Extending a class ~657 *extends*658A class can extend one other class. *E1352* *E1353* *E1354*659The basic idea is to build on top of an existing class, add properties to it.660 661The extended class is called the "base class" or "super class". The new class662is called the "child class".663 664Object variables from the base class are all taken over by the child class.665It is not possible to override them (unlike some other languages).666 667 *E1356* *E1357* *E1358*668Object methods of the base class can be overruled. The signature (arguments,669argument types and return type) must be exactly the same. If the return type670of a method is a class, then that class or one of its subclasses can be used671in the extended method. The method of the base class can be called by672prefixing "super.".673 674 *E1377*675The access level of a method (public or protected) in a child class should be676the same as the super class.677 678Other object methods of the base class are taken over by the child class.679 680Class methods, including methods starting with "new", can be overruled, like681with object methods. The method on the base class can be called by prefixing682the name of the class (for class methods) or "super.".683 684Unlike other languages, the constructor of the base class does not need to be685invoked. In fact, it cannot be invoked. If some initialization from the base686class also needs to be done in a child class, put it in an object method and687call that method from every constructor().688 689If the base class did not specify a new() method then one was automatically690created. This method will not be taken over by the child class. The child691class can define its own new() method, or, if there isn't one, a new() method692will be added automatically.693 694 695A class implementing an interface ~696 *implements* *E1346* *E1347* *E1389*697A class can implement one or more interfaces. The "implements" keyword can698only appear once *E1350* . Multiple interfaces can be specified, separated by699commas. Each interface name can appear only once. *E1351*700 701A class defining an interface ~702 *specifies*703A class can declare its interface, the object variables and methods, with a704named interface. This avoids the need for separately specifying the705interface, which is often done in many languages, especially Java.706TODO: This is currently not implemented.707 708Items in a class ~709 *E1318* *E1325* *E1388*710Inside a class, in between `:class` and `:endclass`, these items can appear:711- An object variable declaration: >712 var _protectedVariableName: memberType713 var readonlyVariableName: memberType714 public var readwriteVariableName: memberType715- A class variable declaration: >716 static var _protectedClassVariableName: memberType717 static var readonlyClassVariableName: memberType718 public static var readwriteClassVariableName: memberType719- A constructor method: >720 def new(arguments)721 def newName(arguments)722- A class method: >723 static def SomeMethod(arguments)724 static def _ProtectedMethod(arguments)725- An object method: >726 def SomeMethod(arguments)727 def _ProtectedMethod(arguments)728 729For the object variable the type must be specified. The best way is to do730this explicitly with ": {type}". For simple types you can also use an731initializer, such as "= 123", and Vim will see that the type is a number.732Avoid doing this for more complex types and when the type will be incomplete.733For example: >734 var nameList = []735This specifies a list, but the item type is unknown. Better use: >736 var nameList: list<string>737The initialization isn't needed, the list is empty by default.738 *E1330*739Some types cannot be used, such as "void", "null" and "v:none".740 741Builtin Object Methods ~742 *builtin-object-methods*743Some of the builtin functions like |empty()|, |len()| and |string()| can be744used with an object. An object can implement a method with the same name as745these builtin functions to return an object-specific value.746 747 *E1412*748The following builtin methods are supported:749 *object-empty()*750 empty() Invoked by the |empty()| function to check whether an object is751 empty. If this method is missing, then true is returned. This752 method should not accept any arguments and must return a boolean.753 *object-len()*754 len() Invoked by the |len()| function to return the length of an755 object. If this method is missing in the class, then an error is756 given and zero is returned. This method should not accept any757 arguments and must return a number.758 *object-string()*759 string() Invoked by the |string()| function to get a textual760 representation of an object. Also used by the |:echo| command761 for an object. If this method is missing in the class, then a762 built-in default textual representation is used. This method763 should not accept any arguments and must return a string.764 765 *E1413*766A class method cannot be used as a builtin method.767 768Defining an interface ~769 *interface* *Interface* *:interface* *:endinterface*770An interface is defined between `:interface` and `:endinterface`. It may be771prefixed with `:export`: >772 773 interface InterfaceName774 endinterface775 776 export interface InterfaceName777 endinterface778< *E1344*779An interface can declare object variables, just like in a class but without780any initializer.781 *E1345*782An interface can declare methods with `:def`, including the arguments and783return type, but without the body and without `:enddef`. Example: >784 785 interface HasSurface786 var size: number787 def Surface(): number788 endinterface789 790An interface name must start with an uppercase letter. *E1343*791The "Has" prefix can be used to make it easier to guess this is an interface792name, with a hint about what it provides.793An interface can only be defined in a |Vim9| script file. *E1342*794An interface cannot "implement" another interface but it can "extend" another795interface. *E1381*796 797null object ~798 799When a variable is declared to have the type of an object, but it is not800initialized, the value is null. When trying to use this null object Vim often801does not know what class was supposed to be used. Vim then cannot check if802a variable name is correct and you will get a "Using a null object" error,803even when the variable name is invalid. *E1360* *E1362*804 805Default constructor ~806 *default-constructor*807In case you define a class without a new() method, one will be automatically808defined. This default constructor will have arguments for all the object809variables, in the order they were specified. Thus if your class looks like: >810 811 class AutoNew812 var name: string813 var age: number814 var gender: Gender815 endclass816 817Then the default constructor will be: >818 819 def new(this.name = v:none, this.age = v:none, this.gender = v:none)820 enddef821 822The "= v:none" default values make the arguments optional. Thus you can also823call `new()` without any arguments. No assignment will happen and the default824value for the object variables will be used. This is a more useful example,825with default values: >826 827 class TextPosition828 var lnum: number = 1829 var col: number = 1830 endclass831 832If you want the constructor to have mandatory arguments, you need to write it833yourself. For example, if for the AutoNew class above you insist on getting834the name, you can define the constructor like this: >835 836 def new(this.name, this.age = v:none, this.gender = v:none)837 enddef838<839When using the default new() method, if the order of the object variables in840the class is changed later, then all the callers of the default new() method841need to change. To avoid this, the new() method can be explicitly defined842without any arguments.843 844 *E1328*845Note that you cannot use another default value than "v:none" here. If you846want to initialize the object variables, do it where they are declared. This847way you only need to look in one place for the default values.848 849All object variables will be used in the default constructor, including850protected access ones.851 852If the class extends another one, the object variables of that class will come853first.854 855 856Multiple constructors ~857 *multiple-constructors*858Normally a class has just one new() constructor. In case you find that the859constructor is often called with the same arguments you may want to simplify860your code by putting those arguments into a second constructor method. For861example, if you tend to use the color black a lot: >862 863 def new(this.garment, this.color, this.size)864 enddef865 ...866 var pants = new(Garment.pants, Color.black, "XL")867 var shirt = new(Garment.shirt, Color.black, "XL")868 var shoes = new(Garment.shoes, Color.black, "45")869 870Instead of repeating the color every time you can add a constructor that871includes it: >872 873 def newBlack(this.garment, this.size)874 this.color = Color.black875 enddef876 ...877 var pants = newBlack(Garment.pants, "XL")878 var shirt = newBlack(Garment.shirt, "XL")879 var shoes = newBlack(Garment.shoes, "9.5")880 881Note that the method name must start with "new". If there is no method called882"new()" then the default constructor is added, even though there are other883constructor methods.884 885Using variable type "any" for an Object~886 *obj-var-type-any*887You can use a variable declared with type "any" to hold an object. e.g.888>889 vim9script890 class A891 var n = 10892 def Get(): number893 return this.n894 enddef895 endclass896 897 def Fn(o: any)898 echo o.n899 echo o.Get()900 enddef901 902 var a = A.new()903 Fn(a)904<905In this example, Vim cannot determine the type of the parameter "o" for906function Fn() at compile time. It can be either a |Dict| or an |Object|907value. Therefore, at runtime, when the type is known, the object member908variable and method are looked up. This process is not efficient, so it is909recommended to use a more specific type whenever possible for better910efficiency.911 912Compiling methods in a Class ~913 *class-compile*914The |:defcompile| command can be used to compile all the class and object915methods defined in a class: >916 917 defcompile MyClass # Compile class "MyClass"918 defcompile # Compile the classes in the current script919<920==============================================================================921 9227. Type definition *typealias* *Vim9-type* *:type*923 924 *E1393* *E1395* *E1396* *E1397* *E1398*925A type definition is giving a name to a type specification. This is also926known as a "type alias". The type alias can be used wherever a built-in type927can be used. Example: >928 929 type ListOfStrings = list<string>930 var s: ListOfStrings = ['a', 'b']931 932 def ProcessStr(str: ListOfStrings): ListOfStrings933 return str934 enddef935 echo ProcessStr(s)936<937 *E1394*938A type alias name must start with an upper case character. Only existing939types can be aliased.940 941 *E1399*942A type alias can be created only at the script level and not inside a943function. A type alias can be exported and used across scripts.944 945 *E1400* *E1401* *E1402* *E1403* *E1407*946A type alias cannot be used as an expression. A type alias cannot be used in947the left-hand-side of an assignment.948 949For a type alias name, the |typename()| function returns the type that is950aliased: >951 952 type ListOfStudents = list<dict<any>>953 echo typename(ListOfStudents)954 typealias<list<dict<any>>>955<956==============================================================================957 9588. Enum *Vim9-enum* *:enum* *:endenum*959 960 *enum* *E1418* *E1419* *E1420*961An enum is a type that can have one of a list of values. Example: >962 963 enum Color964 White,965 Red,966 Green, Blue, Black967 endenum968<969 *enumvalue* *E1422* *E1428*970The enum values are separated by commas. More than one enum value can be971listed in a single line. The final enum value should not be followed by a972comma. Duplicate enum values are not allowed.973 974An enum value is accessed using the enum name followed by the value name: >975 976 var a: Color = Color.Blue977<978Enums are treated as classes, where each enum value is essentially an instance979of that class. Unlike typical object instantiation with the |new()| method,980enum instances cannot be created this way.981 982An enum can only be defined in a |Vim9| script file. *E1414*983An enum cannot be defined inside a function. *E1435*984 985 *E1415*986An enum name must start with an uppercase letter. The name of an enum value987in an enum can start with an upper or lowercase letter.988 989 *E1416*990An enum can implement an interface but cannot extend a class: >991 992 enum MyEnum implements MyIntf993 Value1,994 Value2995 996 def SomeMethod()997 enddef998 endenum999<1000 *enum-constructor*1001The enum value objects in an enum are constructed like any other objects using1002the |new()| method. Arguments can be passed to the enum constructor by1003specifying them after the enum value name, just like calling a function. The1004default constructor doesn't have any arguments.1005 1006 *E1417*1007An enum can contain class variables, class methods, object variables and1008object methods. The methods in an enum cannot be |:abstract| methods.1009 1010The following example shows an enum with object variables and methods: >1011 1012 vim9script1013 enum Planet1014 Earth(1, false),1015 Jupiter(95, true),1016 Saturn(146, true)1017 1018 var moons: number1019 var has_rings: bool1020 def GetMoons(): number1021 return this.moons1022 enddef1023 endenum1024 echo Planet.Jupiter.GetMoons()1025 echo Planet.Earth.has_rings1026<1027 *E1421* *E1423* *E1424* *E1425*1028Enums and their values are immutable. They cannot be utilized as numerical or1029string types. Enum values can declare mutable instance variables.1030 1031 *enum-name* *E1427*1032Each enum value object has a "name" instance variable which contains the name1033of the enum value. This is a readonly variable.1034 1035 *enum-ordinal* *E1426*1036Each enum value has an associated ordinal number starting with 0. The ordinal1037number of an enum value can be accessed using the "ordinal" instance variable.1038This is a readonly variable. Note that if the ordering of the enum values in1039an enum is changed, then their ordinal values will also change.1040 1041 *enum-values*1042All the values in an enum can be accessed using the "values" class variable1043which is a List of the enum objects. This is a readonly variable.1044 1045Example: >1046 enum Planet1047 Mercury,1048 Venus,1049 Earth1050 endenum1051 1052 echo Planet.Mercury1053 echo Planet.Venus.name1054 echo Planet.Venus.ordinal1055 for p in Planet.values1056 # ...1057 endfor1058<1059An enum is a class with class variables for the enum value objects and object1060variables for the enum value name and the enum value ordinal: >1061 1062 enum Planet1063 Mercury,1064 Venus1065 endenum1066<1067The above enum definition is equivalent to the following class definition: >1068 1069 class Planet1070 public static final Mercury: Planet = Planet.new('Mercury', 0)1071 public static final Venus: Planet = Planet.new('Venus', 1)1072 1073 public static const values: list<Planet> = [Planet.Mercury, Planet.Venus]1074 1075 public const name: string1076 public const ordinal: number1077 endclass1078<1079A enum can contain object variables and methods just like a regular class: >1080 1081 enum Color1082 Cyan([0, 255, 255]),1083 Magenta([255, 0, 255]),1084 Gray([128, 128, 128])1085 1086 var rgb_values: list<number>1087 1088 def Get_RGB(): list<number>1089 return this.rgb_values1090 enddef1091 endenum1092 echo Color.Magenta.Get_RGB()1093<1094==============================================================================1095 10969. Rationale1097 1098Most of the choices for |Vim9| classes come from popular and recently1099developed languages, such as Java, TypeScript and Dart. The syntax has been1100made to fit with the way Vim script works, such as using `endclass` instead of1101using curly braces around the whole class.1102 1103Some common constructs of object-oriented languages were chosen very long ago1104when this kind of programming was still new, and later found to be1105sub-optimal. By this time those constructs were widely used and changing them1106was not an option. In Vim we do have the freedom to make different choices,1107since classes are completely new. We can make the syntax simpler and more1108consistent than what "old" languages use. Without diverting too much, it1109should still mostly look like what you know from existing languages.1110 1111Some recently developed languages add all kinds of fancy features that we1112don't need for Vim. But some have nice ideas that we do want to use.1113Thus we end up with a base of what is common in popular languages, dropping1114what looks like a bad idea, and adding some nice features that are easy to1115understand.1116 1117The main rules we use to make decisions:1118- Keep it simple.1119- No surprises, mostly do what other languages are doing.1120- Avoid mistakes from the past.1121- Avoid the need for the script writer to consult the help to understand how1122 things work, most things should be obvious.1123- Keep it consistent.1124- Aim at an average size plugin, not at a huge project.1125 1126 1127Using new() for the constructor ~1128 1129Many languages use the class name for the constructor method. A disadvantage1130is that quite often this is a long name. And when changing the class name all1131constructor methods need to be renamed. Not a big deal, but still a1132disadvantage.1133 1134Other languages, such as TypeScript, use a specific name, such as1135"constructor()". That seems better. However, using "new" or "new()" to1136create a new object has no obvious relation with "constructor()".1137 1138For |Vim9| script using the same method name for all constructors seemed like1139the right choice, and by calling it new() the relation between the caller and1140the method being called is obvious.1141 1142No overloading of the constructor ~1143 1144In Vim script, both legacy and |Vim9| script, there is no overloading of1145methods. That means it is not possible to use the same method name with1146different types of arguments. Therefore there also is only one new()1147constructor.1148 1149With |Vim9| script it would be possible to support overloading, since1150arguments are typed. However, this gets complicated very quickly. Looking at1151a new() call one has to inspect the types of the arguments to know which of1152several new() methods is actually being called. And that can require1153inspecting quite a bit of code. For example, if one of the arguments is the1154return value of a method, you need to find that method to see what type it is1155returning.1156 1157Instead, every constructor has to have a different name, starting with "new".1158That way multiple constructors with different arguments are possible, while it1159is very easy to see which constructor is being used. And the type of1160arguments can be properly checked.1161 1162No overloading of methods ~1163 1164Same reasoning as for the constructor: It is often not obvious what type1165arguments have, which would make it difficult to figure out what method is1166actually being called. Better just give the methods a different name, then1167type checking will make sure it works as you intended. This rules out1168polymorphism, which we don't really need anyway.1169 1170Single inheritance and interfaces ~1171 1172Some languages support multiple inheritance. Although that can be useful in1173some cases, it makes the rules of how a class works quite complicated.1174Instead, using interfaces to declare what is supported is much simpler. The1175very popular Java language does it this way, and it should be good enough for1176Vim. The "keep it simple" rule applies here.1177 1178Explicitly declaring that a class supports an interface makes it easy to see1179what a class is intended for. It also makes it possible to do proper type1180checking. When an interface is changed any class that declares to implement1181it will be checked if that change was also changed. The mechanism to assume a1182class implements an interface just because the methods happen to match is1183brittle and leads to obscure problems, let's not do that.1184 1185Using "this.variable" everywhere ~1186 1187The object variables in various programming languages can often be accessed in1188different ways, depending on the location. Sometimes "this." has to be1189prepended to avoid ambiguity. They are usually declared without "this.".1190That is quite inconsistent and sometimes confusing.1191 1192A very common issue is that in the constructor the arguments use the same name1193as the object variable. Then for these variables "this." needs to be prefixed1194in the body, while for other variables this is not needed and often omitted.1195This leads to a mix of variables with and without "this.", which is1196inconsistent.1197 1198For |Vim9| classes the "this." prefix is always used for declared methods and1199variables. Simple and consistent. When looking at the code inside a class1200it's also directly clear which variable references are object variables and