blob: d2f43aefb2b3aa9332b2833859693cb993d6a7a3 [file] [log] [blame]
Hirohito Higashi31b78cc2025-04-21 19:39:15 +02001*vim9class.txt* For Vim version 9.1. Last change: 2025 Apr 21
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00002
3
4 VIM REFERENCE MANUAL by Bram Moolenaar
5
6
Yegappan Lakshmanan49cdd622023-12-24 11:01:23 +01007Vim9 classes, objects, interfaces, types and enums. *vim9-class*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00008
91. Overview |Vim9-class-overview|
102. A simple class |Vim9-simple-class|
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200113. Class variables and methods |Vim9-class-member|
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000124. 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|
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000017
189. Rationale
1910. To be done later
20
21==============================================================================
22
231. Overview *Vim9-class-overview*
24
25The fancy term is "object-oriented programming". You can find lots of study
Bram Moolenaarbe4e0162023-02-02 13:59:48 +000026material on this subject. Here we document what |Vim9| script provides,
27assuming you know the basics already. Added are helpful hints about how to
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +020028use this functionality effectively. Vim9 classes and objects cannot be used
29in legacy Vim scripts and legacy functions.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000030
31The basic item is an object:
32- An object stores state. It contains one or more variables that can each
33 have a value.
Bram Moolenaarbe4e0162023-02-02 13:59:48 +000034- An object provides functions that use and manipulate its state. These
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000035 functions are invoked "on the object", which is what sets it apart from the
36 traditional separation of data and code that manipulates the data.
37- An object has a well defined interface, with typed member variables and
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -070038 methods.
Bram Moolenaarbe4e0162023-02-02 13:59:48 +000039- Objects are created from a class and all objects have the same interface.
40 This does not change at runtime, it is not dynamic.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000041
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().
Bram Moolenaarbe4e0162023-02-02 13:59:48 +000045- State shared by all objects of the class: class variables (class members).
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000046- 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 are
53to be used where needed.
54
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000055Class 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 because
59teachers use real-world objects to explain class relations and you might think
60your model should therefore reflect the real world. It doesn't! The model
61should match your purpose.
62
Bram Moolenaarbe4e0162023-02-02 13:59:48 +000063Keep in mind that composition (an object contains other objects) is often
64better than inheritance (an object extends another object). Don't waste time
65trying to find the optimal class model. Or waste time discussing whether a
66square is a rectangle or that a rectangle is a square. It doesn't matter.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000067
68
69==============================================================================
70
712. A simple class *Vim9-simple-class*
72
Bram Moolenaarbe4e0162023-02-02 13:59:48 +000073Let's start with a simple example: a class that stores a text position (see
74below for how to do this more efficiently): >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000075
76 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +010077 var lnum: number
78 var col: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000079
80 def new(lnum: number, col: number)
81 this.lnum = lnum
82 this.col = col
83 enddef
84
85 def SetLnum(lnum: number)
86 this.lnum = lnum
87 enddef
88
89 def SetCol(col: number)
90 this.col = col
91 enddef
92
93 def SetPosition(lnum: number, col: number)
94 this.lnum = lnum
95 this.col = col
96 enddef
97 endclass
Bram Moolenaar7db29e42022-12-11 15:53:04 +000098< *object* *Object*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +000099You can create an object from this class with the new() method: >
100
101 var pos = TextPosition.new(1, 1)
errael1d4fcfe2023-12-21 08:34:15 -0800102<
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700103The object variables "lnum" and "col" can be accessed directly: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000104
105 echo $'The text position is ({pos.lnum}, {pos.col})'
Christian Brabandt6c1afa32024-01-01 20:50:51 +0100106< *E1317* *E1327* *:this*
errael1d4fcfe2023-12-21 08:34:15 -0800107If you have been using other object-oriented languages you will notice that in
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300108Vim, within a class definition, the declared object members are consistently
109referred to with the "this." prefix. This is different from languages like
110Java and TypeScript. The naming convention makes the object members easy to
111spot. Also, when a variable does not have the "this." prefix you know it is
112not an object variable.
errael1d4fcfe2023-12-21 08:34:15 -0800113 *E1411*
114From outside the class definition, access an object's methods and variables by
115using the object name followed by a dot following by the member: >
116
117 pos.lnum
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300118 pos.SetCol(10)
errael1d4fcfe2023-12-21 08:34:15 -0800119<
120 *E1405* *E1406*
121A class name cannot be used as an expression. A class name cannot be used in
122the left-hand-side of an assignment.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000123
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700124Object variable write access ~
Ernie Rael03042a22023-11-11 08:53:32 +0100125 *read-only-variable*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700126Now try to change an object variable directly: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000127
128 pos.lnum = 9
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000129< *E1335*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700130This will give you an error! That is because by default object variables can
131be read but not set. That's why the TextPosition class provides a method for
132it: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000133
134 pos.SetLnum(9)
135
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700136Allowing to read but not set an object variable is the most common and safest
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000137way. Most often there is no problem using a value, while setting a value may
138have 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 use
140the closest valid value.
Ernie Rael03042a22023-11-11 08:53:32 +0100141 *:public* *public-variable* *E1331*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700142If you don't care about side effects and want to allow the object variable to
143be changed at any time, you can make it public: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000144
Aliaksei Budavei0aed99a2023-12-29 01:08:24 +0300145 public var lnum: number
146 public var col: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000147
148Now you don't need the SetLnum(), SetCol() and SetPosition() methods, setting
149"pos.lnum" directly above will no longer give an error.
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200150 *E1326*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700151If you try to set an object variable that doesn't exist you get an error: >
Bram Moolenaarf1dcd142022-12-31 15:30:45 +0000152 pos.other = 9
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200153< E1326: Member not found on object "TextPosition": other ~
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000154
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200155 *E1376*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700156A object variable cannot be accessed using the class name.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000157
Ernie Rael03042a22023-11-11 08:53:32 +0100158Protected variables ~
159 *protected-variable* *E1332* *E1333*
160On the other hand, if you do not want the object variables to be read directly
161from outside the class or its sub-classes, you can make them protected. This
162is done by prefixing an underscore to the name: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000163
Doug Kearns74da0ee2023-12-14 20:26:26 +0100164 var _lnum: number
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300165 var _col: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000166
Ernie Rael03042a22023-11-11 08:53:32 +0100167Now you need to provide methods to get the value of the protected variables.
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000168These are commonly called getters. We recommend using a name that starts with
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000169"Get": >
170
171 def GetLnum(): number
172 return this._lnum
173 enddef
174
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300175 def GetCol(): number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000176 return this._col
177 enddef
178
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700179This example isn't very useful, the variables might as well have been public.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000180It does become useful if you check the value. For example, restrict the line
181number to the total number of lines: >
182
183 def GetLnum(): number
184 if this._lnum > this._lineCount
185 return this._lineCount
186 endif
187 return this._lnum
188 enddef
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200189<
Ernie Rael03042a22023-11-11 08:53:32 +0100190Protected methods ~
191 *protected-method* *E1366*
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +0200192If you want object methods to be accessible only from other methods of the
193same class and not used from outside the class, then you can make them
Ernie Rael03042a22023-11-11 08:53:32 +0100194protected. This is done by prefixing the method name with an underscore: >
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +0200195
196 class SomeClass
197 def _Foo(): number
198 return 10
199 enddef
200 def Bar(): number
201 return this._Foo()
202 enddef
203 endclass
204<
Ernie Rael03042a22023-11-11 08:53:32 +0100205Accessing a protected method outside the class will result in an error (using
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +0200206the above class): >
207
208 var a = SomeClass.new()
209 a._Foo()
210<
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000211Simplifying the new() method ~
Yegappan Lakshmanan413f8392023-09-28 22:46:37 +0200212 *new()* *constructor*
errael92feeaf2023-12-27 10:07:09 -0800213See also |default-constructor| and |multiple-constructors|.
214
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700215Many constructors take values for the object variables. Thus you very often
216see this pattern: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000217
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000218 class SomeClass
Doug Kearns74da0ee2023-12-14 20:26:26 +0100219 var lnum: number
220 var col: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000221
222 def new(lnum: number, col: number)
223 this.lnum = lnum
224 this.col = col
225 enddef
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000226 endclass
h-eastdb385522023-09-28 22:18:19 +0200227<
228 *E1390*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700229Not only is this text you need to write, it also has the type of each
Dominique Pellé17dca3c2023-12-14 20:36:32 +0100230variable twice. Since this is so common a shorter way to write new() is
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700231provided: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000232
233 def new(this.lnum, this.col)
234 enddef
235
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700236The semantics are easy to understand: Providing the object variable name,
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000237including "this.", as the argument to new() means the value provided in the
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700238new() call is assigned to that object variable. This mechanism comes from the
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000239Dart language.
240
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700241Putting together this way of using new() and making the variables public
242results in a much shorter class definition than what we started with: >
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000243
244 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100245 public var lnum: number
246 public var col: number
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000247
248 def new(this.lnum, this.col)
249 enddef
250
251 def SetPosition(lnum: number, col: number)
252 this.lnum = lnum
253 this.col = col
254 enddef
255 endclass
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000256
257The sequence of constructing a new object is:
2581. Memory is allocated and cleared. All values are zero/false/empty.
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07002592. For each declared object variable that has an initializer, the expression
260 is evaluated and assigned to the variable. This happens in the sequence
261 the variables are declared in the class.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00002623. Arguments in the new() method in the "this.name" form are assigned.
2634. The body of the new() method is executed.
264
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000265If the class extends a parent class, the same thing happens. In the second
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700266step the object variables of the parent class are initialized first. There is
267no need to call "super()" or "new()" on the parent.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000268
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200269 *E1365*
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +0200270When defining the new() method the return type should not be specified. It
271always returns an object of the class.
272
Yegappan Lakshmanan7e898002025-02-11 22:07:05 +0100273The new() method can be made a protected method by using "_new()". This can
274be used to support the singleton design pattern.
275
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200276 *E1386*
277When invoking an object method, the method name should be preceded by the
Dominique Pellé17dca3c2023-12-14 20:36:32 +0100278object variable name. An object method cannot be invoked using the class
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200279name.
280
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000281==============================================================================
282
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002833. Class Variables and Methods *Vim9-class-member*
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000284
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200285 *:static* *E1337* *E1338* *E1368*
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000286Class members are declared with "static". They are used by the name without a
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200287prefix in the class where they are defined: >
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000288
289 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +0100290 var size: number
291 static var totalSize: number
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000292
293 def new(this.size)
294 totalSize += this.size
295 enddef
296 endclass
297< *E1340* *E1341*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700298Since the name is used as-is, shadowing the name by a method argument name
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000299or local variable name is not allowed.
300
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200301 *E1374* *E1375* *E1384* *E1385*
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200302To access a class member outside of the class where it is defined, the class
303name prefix must be used. A class member cannot be accessed using an object.
304
Ernie Rael03042a22023-11-11 08:53:32 +0100305Just like object members the access can be made protected by using an
306underscore as the first character in the name, and it can be made public by
307prefixing "public": >
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000308
309 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +0100310 static var total: number # anybody can read, only class can write
311 static var _sum: number # only class can read and write
312 public static var result: number # anybody can read and write
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000313 endclass
314<
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200315 *class-method*
316Class methods are also declared with "static". They can use the class
317variables but they have no access to the object variables, they cannot use the
h_eastba77bbb2023-10-03 04:47:13 +0900318"this" keyword:
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200319>
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000320 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +0100321 var size: number
322 static var totalSize: number
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000323
324 # Clear the total size and return the value it had before.
325 static def ClearTotalSize(): number
326 var prev = totalSize
327 totalSize = 0
328 return prev
329 enddef
330 endclass
331
Aliaksei Budavei95740222024-04-04 23:05:33 +0300332Inside the class, the class method can be called by name directly, outside the
333class, the class name must be prefixed: `OtherThing.ClearTotalSize()`. Also,
334the name prefix must be used for public class methods in the special contexts
335of class variable initializers and of lambda expressions and nested functions:
336>
337 class OtherThing
338 static var name: string = OtherThing.GiveName()
339
340 static def GiveName(): string
341 def DoGiveName(): string
342 return OtherThing.NameAny()
343 enddef
344
345 return DoGiveName()
346 enddef
347
348 static def NameAny(): string
349 return "any"
350 enddef
351 endclass
352<
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000353
Ernie Rael03042a22023-11-11 08:53:32 +0100354Just like object methods the access can be made protected by using an
355underscore as the first character in the method name: >
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +0200356
357 class OtherThing
358 static def _Foo()
359 echo "Foo"
360 enddef
361 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200362 _Foo()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +0200363 enddef
364 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +0200365<
366 *E1370*
Ernie Rael4e286312023-12-24 11:03:31 +0100367Note that constructors cannot be declared as "static". They are called like a
368static but execute as an object method; they have access to "this".
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +0200369
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200370To access the class methods and class variables of a super class in an
371extended class, the class name prefix should be used just as from anywhere
372outside of the defining class: >
373
374 vim9script
375 class Vehicle
Doug Kearns74da0ee2023-12-14 20:26:26 +0100376 static var nextID: number = 1000
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200377 static def GetID(): number
378 nextID += 1
379 return nextID
380 enddef
381 endclass
382 class Car extends Vehicle
Doug Kearns74da0ee2023-12-14 20:26:26 +0100383 var myID: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200384 def new()
385 this.myID = Vehicle.GetID()
386 enddef
387 endclass
388<
389Class variables and methods are not inherited by a child class. A child class
390can declare a static variable or a method with the same name as the one in the
391super class. Depending on the class where the member is used the
392corresponding class member will be used. The type of the class member in a
393child class can be different from that in the super class.
394
Yegappan Lakshmananff6f0d52023-12-21 16:46:18 +0100395The double underscore (__) prefix for a class or object method name is
396reserved for future use.
397
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +0100398 *object-final-variable* *E1409*
399The |:final| keyword can be used to make a class or object variable a
400constant. Examples: >
401
402 class A
403 final v1 = [1, 2] # final object variable
404 public final v2 = {x: 1} # final object variable
405 static final v3 = 'abc' # final class variable
406 public static final v4 = 0z10 # final class variable
407 endclass
408<
409A final variable can be changed only from a constructor function. Example: >
410
411 class A
412 final v1: list<number>
413 def new()
414 this.v1 = [1, 2]
415 enddef
416 endclass
417 var a = A.new()
418 echo a.v1
419<
420Note that the value of a final variable can be changed. Example: >
421
422 class A
423 public final v1 = [1, 2]
424 endclass
425 var a = A.new()
426 a.v1[0] = 6 # OK
427 a.v1->add(3) # OK
428 a.v1 = [3, 4] # Error
429<
430 *E1408*
431Final variables are not supported in an interface. A class or object method
432cannot be final.
433
434 *object-const-variable*
435The |:const| keyword can be used to make a class or object variable and the
436value a constant. Examples: >
437
438 class A
439 const v1 = [1, 2] # const object variable
440 public const v2 = {x: 1} # const object variable
441 static const v3 = 'abc' # const class variable
442 public static const v4 = 0z10 # const class variable
443 endclass
444<
445A const variable can be changed only from a constructor function. Example: >
446
447 class A
448 const v1: list<number>
449 def new()
450 this.v1 = [1, 2]
451 enddef
452 endclass
453 var a = A.new()
454 echo a.v1
455<
456A const variable and its value cannot be changed. Example: >
457
458 class A
459 public const v1 = [1, 2]
460 endclass
461 var a = A.new()
462 a.v1[0] = 6 # Error
463 a.v1->add(3) # Error
464 a.v1 = [3, 4] # Error
465<
466 *E1410*
467Const variables are not supported in an interface. A class or object method
468cannot be a const.
469
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000470==============================================================================
471
4724. Using an abstract class *Vim9-abstract-class*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000473
474An abstract class forms the base for at least one sub-class. In the class
475model one often finds that a few classes have the same properties that can be
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000476shared, but a class with these properties does not have enough state to create
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000477an object from. A sub-class must extend the abstract class and add the
478missing state and/or methods before it can be used to create objects for.
479
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000480For example, a Shape class could store a color and thickness. You cannot
481create a Shape object, it is missing the information about what kind of shape
482it is. The Shape class functions as the base for a Square and a Triangle
483class, for which objects can be created. Example: >
484
485 abstract class Shape
Doug Kearns74da0ee2023-12-14 20:26:26 +0100486 var color = Color.Black
487 var thickness = 10
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000488 endclass
489
490 class Square extends Shape
Doug Kearns74da0ee2023-12-14 20:26:26 +0100491 var size: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000492
493 def new(this.size)
494 enddef
495 endclass
496
497 class Triangle extends Shape
Doug Kearns74da0ee2023-12-14 20:26:26 +0100498 var base: number
499 var height: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000500
501 def new(this.base, this.height)
502 enddef
503 endclass
504<
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000505An abstract class is defined the same way as a normal class, except that it
506does not have any new() method. *E1359*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000507
h_east596a9f22023-11-21 21:24:23 +0900508 *abstract-method* *E1371* *E1372*
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +0200509An abstract method can be defined in an abstract class by using the "abstract"
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700510prefix when defining the method: >
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +0200511
512 abstract class Shape
513 abstract def Draw()
514 endclass
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200515<
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +0100516A static method in an abstract class cannot be an abstract method.
517
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200518 *E1373*
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300519A non-abstract class extending the abstract class must implement all the
520abstract methods. The signature (arguments, argument types and return type)
521must be exactly the same. If the return type of a method is a class, then
522that class or one of its subclasses can be used in the extended method.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000523
524==============================================================================
525
Bram Moolenaarbe4e0162023-02-02 13:59:48 +00005265. Using an interface *Vim9-using-interface*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000527
528The example above with Shape, Square and Triangle can be made more useful if
529we add a method to compute the surface of the object. For that we create the
530interface called HasSurface, which specifies one method Surface() that returns
531a number. This example extends the one above: >
532
533 abstract class Shape
Doug Kearns74da0ee2023-12-14 20:26:26 +0100534 var color = Color.Black
535 var thickness = 10
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000536 endclass
537
538 interface HasSurface
539 def Surface(): number
540 endinterface
541
542 class Square extends Shape implements HasSurface
Doug Kearns74da0ee2023-12-14 20:26:26 +0100543 var size: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000544
545 def new(this.size)
546 enddef
547
548 def Surface(): number
549 return this.size * this.size
550 enddef
551 endclass
552
553 class Triangle extends Shape implements HasSurface
Doug Kearns74da0ee2023-12-14 20:26:26 +0100554 var base: number
555 var height: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000556
557 def new(this.base, this.height)
558 enddef
559
560 def Surface(): number
561 return this.base * this.height / 2
562 enddef
563 endclass
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200564<
565 *E1348* *E1349* *E1367* *E1382* *E1383*
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000566If a class declares to implement an interface, all the items specified in the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200567interface must appear in the class, with the same types.
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000568
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000569The interface name can be used as a type: >
570
571 var shapes: list<HasSurface> = [
572 Square.new(12),
573 Triangle.new(8, 15),
574 ]
575 for shape in shapes
576 echo $'the surface is {shape.Surface()}'
577 endfor
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200578<
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200579 *E1378* *E1379* *E1380* *E1387*
580An interface can contain only object methods and read-only object variables.
Ernie Rael03042a22023-11-11 08:53:32 +0100581An interface cannot contain read-write or protected object variables,
582protected object methods, class variables and class methods.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000583
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200584An interface can extend another interface using "extends". The sub-interface
585inherits all the instance variables and methods from the super interface.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000586
587==============================================================================
588
Bram Moolenaarbe4e0162023-02-02 13:59:48 +00005896. More class details *Vim9-class* *Class* *class*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000590
591Defining a class ~
592 *:class* *:endclass* *:abstract*
593A class is defined between `:class` and `:endclass`. The whole class is
594defined in one script file. It is not possible to add to a class later.
595
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000596A class can only be defined in a |Vim9| script file. *E1316*
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200597A class cannot be defined inside a function. *E1429*
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000598
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000599It is possible to define more than one class in a script file. Although it
600usually is better to export only one main class. It can be useful to define
601types, enums and helper classes though.
602
603The `:abstract` keyword may be prefixed and `:export` may be used. That gives
604these variants: >
605
606 class ClassName
607 endclass
608
609 export class ClassName
610 endclass
611
612 abstract class ClassName
613 endclass
614
615 export abstract class ClassName
616 endclass
617<
618 *E1314*
619The class name should be CamelCased. It must start with an uppercase letter.
620That avoids clashing with builtin types.
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000621 *E1315*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000622After the class name these optional items can be used. Each can appear only
623once. They can appear in any order, although this order is recommended: >
624 extends ClassName
625 implements InterfaceName, OtherInterface
626 specifies SomeInterface
Yegappan Lakshmanan44831e42025-02-16 16:15:50 +0100627<
628The "specifies" feature is currently not implemented.
629
630 *E1355* *E1369*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700631Each variable and method name can be used only once. It is not possible to
632define a method with the same name and different type of arguments. It is not
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300633possible to use a public and protected member variable with the same name. An
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700634object variable name used in a super class cannot be reused in a child class.
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000635
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700636Object Variable Initialization ~
Ernie Rael03042a22023-11-11 08:53:32 +0100637
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700638If the type of a variable is not explicitly specified in a class, then it is
639set to "any" during class definition. When an object is instantiated from the
640class, then the type of the variable is set.
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200641
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +0200642The following reserved keyword names cannot be used as an object or class
643variable name: "super", "this", "true", "false", "null", "null_blob",
Yegappan Lakshmanan8daae6f2025-04-05 16:00:22 +0200644"null_channel", "null_class", "null_dict", "null_function", "null_job",
645"null_list", "null_object", "null_partial" and "null_string".
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200646
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000647Extending a class ~
648 *extends*
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000649A class can extend one other class. *E1352* *E1353* *E1354*
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000650The basic idea is to build on top of an existing class, add properties to it.
651
652The extended class is called the "base class" or "super class". The new class
653is called the "child class".
654
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700655Object variables from the base class are all taken over by the child class. It
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000656is not possible to override them (unlike some other languages).
657
658 *E1356* *E1357* *E1358*
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +0200659Object methods of the base class can be overruled. The signature (arguments,
Yegappan Lakshmanan26e8f7b2023-10-06 10:24:10 -0700660argument types and return type) must be exactly the same. If the return type
661of a method is a class, then that class or one of its subclasses can be used
662in the extended method. The method of the base class can be called by
663prefixing "super.".
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000664
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200665 *E1377*
Ernie Rael03042a22023-11-11 08:53:32 +0100666The access level of a method (public or protected) in a child class should be
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200667the same as the super class.
668
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000669Other object methods of the base class are taken over by the child class.
670
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700671Class methods, including methods starting with "new", can be overruled, like
672with object methods. The method on the base class can be called by prefixing
673the name of the class (for class methods) or "super.".
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000674
675Unlike other languages, the constructor of the base class does not need to be
676invoked. In fact, it cannot be invoked. If some initialization from the base
677class also needs to be done in a child class, put it in an object method and
678call that method from every constructor().
679
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700680If the base class did not specify a new() method then one was automatically
681created. This method will not be taken over by the child class. The child
682class can define its own new() method, or, if there isn't one, a new() method
683will be added automatically.
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000684
685
686A class implementing an interface ~
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200687 *implements* *E1346* *E1347* *E1389*
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000688A class can implement one or more interfaces. The "implements" keyword can
689only appear once *E1350* . Multiple interfaces can be specified, separated by
690commas. Each interface name can appear only once. *E1351*
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000691
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000692A class defining an interface ~
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000693 *specifies*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700694A class can declare its interface, the object variables and methods, with a
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000695named interface. This avoids the need for separately specifying the
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000696interface, which is often done in many languages, especially Java.
Yegappan Lakshmanan44831e42025-02-16 16:15:50 +0100697TODO: This is currently not implemented.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000698
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000699Items in a class ~
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200700 *E1318* *E1325* *E1388*
Bram Moolenaardd60c362023-02-27 15:49:53 +0000701Inside a class, in between `:class` and `:endclass`, these items can appear:
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700702- An object variable declaration: >
Doug Kearns74da0ee2023-12-14 20:26:26 +0100703 var _protectedVariableName: memberType
704 var readonlyVariableName: memberType
705 public var readwriteVariableName: memberType
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700706- A class variable declaration: >
Doug Kearns74da0ee2023-12-14 20:26:26 +0100707 static var _protectedClassVariableName: memberType
708 static var readonlyClassVariableName: memberType
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300709 public static var readwriteClassVariableName: memberType
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000710- A constructor method: >
Bram Moolenaar938ae282023-02-20 20:44:55 +0000711 def new(arguments)
712 def newName(arguments)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200713- A class method: >
714 static def SomeMethod(arguments)
Ernie Rael03042a22023-11-11 08:53:32 +0100715 static def _ProtectedMethod(arguments)
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000716- An object method: >
Bram Moolenaar938ae282023-02-20 20:44:55 +0000717 def SomeMethod(arguments)
Ernie Rael03042a22023-11-11 08:53:32 +0100718 def _ProtectedMethod(arguments)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200719
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700720For the object variable the type must be specified. The best way is to do
721this explicitly with ": {type}". For simple types you can also use an
722initializer, such as "= 123", and Vim will see that the type is a number.
723Avoid doing this for more complex types and when the type will be incomplete.
724For example: >
Doug Kearns74da0ee2023-12-14 20:26:26 +0100725 var nameList = []
Bram Moolenaarf1dcd142022-12-31 15:30:45 +0000726This specifies a list, but the item type is unknown. Better use: >
Doug Kearns74da0ee2023-12-14 20:26:26 +0100727 var nameList: list<string>
Bram Moolenaarf1dcd142022-12-31 15:30:45 +0000728The initialization isn't needed, the list is empty by default.
729 *E1330*
730Some types cannot be used, such as "void", "null" and "v:none".
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000731
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +0100732Builtin Object Methods ~
733 *builtin-object-methods*
734Some of the builtin functions like |empty()|, |len()| and |string()| can be
735used with an object. An object can implement a method with the same name as
736these builtin functions to return an object-specific value.
737
Yegappan Lakshmanan44831e42025-02-16 16:15:50 +0100738 *E1412*
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +0100739The following builtin methods are supported:
Yegappan Lakshmanan44831e42025-02-16 16:15:50 +0100740 *object-empty()*
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +0100741 empty() Invoked by the |empty()| function to check whether an object is
742 empty. If this method is missing, then true is returned. This
743 method should not accept any arguments and must return a boolean.
Yegappan Lakshmanan44831e42025-02-16 16:15:50 +0100744 *object-len()*
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +0100745 len() Invoked by the |len()| function to return the length of an
746 object. If this method is missing in the class, then an error is
747 given and zero is returned. This method should not accept any
748 arguments and must return a number.
Yegappan Lakshmanan44831e42025-02-16 16:15:50 +0100749 *object-string()*
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +0100750 string() Invoked by the |string()| function to get a textual
751 representation of an object. Also used by the |:echo| command
752 for an object. If this method is missing in the class, then a
753 built-in default textual representation is used. This method
754 should not accept any arguments and must return a string.
755
Yegappan Lakshmanan44831e42025-02-16 16:15:50 +0100756 *E1413*
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +0100757A class method cannot be used as a builtin method.
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000758
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000759Defining an interface ~
Christian Brabandt6c1afa32024-01-01 20:50:51 +0100760 *Interface* *:interface* *:endinterface*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000761An interface is defined between `:interface` and `:endinterface`. It may be
762prefixed with `:export`: >
763
764 interface InterfaceName
765 endinterface
766
767 export interface InterfaceName
768 endinterface
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000769< *E1344*
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700770An interface can declare object variables, just like in a class but without
771any initializer.
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000772 *E1345*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000773An interface can declare methods with `:def`, including the arguments and
774return type, but without the body and without `:enddef`. Example: >
775
776 interface HasSurface
Doug Kearns74da0ee2023-12-14 20:26:26 +0100777 var size: number
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000778 def Surface(): number
779 endinterface
780
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000781An interface name must start with an uppercase letter. *E1343*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000782The "Has" prefix can be used to make it easier to guess this is an interface
783name, with a hint about what it provides.
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000784An interface can only be defined in a |Vim9| script file. *E1342*
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200785An interface cannot "implement" another interface but it can "extend" another
786interface. *E1381*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000787
Bram Moolenaar938ae282023-02-20 20:44:55 +0000788null object ~
789
Bram Moolenaardd60c362023-02-27 15:49:53 +0000790When a variable is declared to have the type of an object, but it is not
Bram Moolenaar938ae282023-02-20 20:44:55 +0000791initialized, the value is null. When trying to use this null object Vim often
792does not know what class was supposed to be used. Vim then cannot check if
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300793a variable name is correct and you will get a "Using a null object" error,
h_eastba77bbb2023-10-03 04:47:13 +0900794even when the variable name is invalid. *E1360* *E1362*
Bram Moolenaar938ae282023-02-20 20:44:55 +0000795
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000796Default constructor ~
Yegappan Lakshmanan413f8392023-09-28 22:46:37 +0200797 *default-constructor*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000798In case you define a class without a new() method, one will be automatically
799defined. This default constructor will have arguments for all the object
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700800variables, in the order they were specified. Thus if your class looks like: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000801
802 class AutoNew
Doug Kearns74da0ee2023-12-14 20:26:26 +0100803 var name: string
804 var age: number
805 var gender: Gender
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000806 endclass
807
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700808Then the default constructor will be: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000809
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000810 def new(this.name = v:none, this.age = v:none, this.gender = v:none)
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000811 enddef
812
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000813The "= v:none" default values make the arguments optional. Thus you can also
814call `new()` without any arguments. No assignment will happen and the default
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700815value for the object variables will be used. This is a more useful example,
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000816with default values: >
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000817
818 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100819 var lnum: number = 1
820 var col: number = 1
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000821 endclass
822
823If you want the constructor to have mandatory arguments, you need to write it
824yourself. For example, if for the AutoNew class above you insist on getting
825the name, you can define the constructor like this: >
826
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000827 def new(this.name, this.age = v:none, this.gender = v:none)
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000828 enddef
Yegappan Lakshmanan563e6442023-12-05 08:19:06 -0800829<
830When using the default new() method, if the order of the object variables in
831the class is changed later, then all the callers of the default new() method
Aliaksei Budaveib2149952024-01-07 17:52:10 +0300832need to change. To avoid this, the new() method can be explicitly defined
Yegappan Lakshmanan563e6442023-12-05 08:19:06 -0800833without any arguments.
834
835 *E1328*
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000836Note that you cannot use another default value than "v:none" here. If you
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700837want to initialize the object variables, do it where they are declared. This
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000838way you only need to look in one place for the default values.
Bram Moolenaar7db29e42022-12-11 15:53:04 +0000839
Ernie Rael03042a22023-11-11 08:53:32 +0100840All object variables will be used in the default constructor, including
841protected access ones.
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000842
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -0700843If the class extends another one, the object variables of that class will come
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +0000844first.
845
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000846
847Multiple constructors ~
errael92feeaf2023-12-27 10:07:09 -0800848 *multiple-constructors*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000849Normally a class has just one new() constructor. In case you find that the
850constructor is often called with the same arguments you may want to simplify
851your code by putting those arguments into a second constructor method. For
852example, if you tend to use the color black a lot: >
853
854 def new(this.garment, this.color, this.size)
855 enddef
856 ...
857 var pants = new(Garment.pants, Color.black, "XL")
858 var shirt = new(Garment.shirt, Color.black, "XL")
859 var shoes = new(Garment.shoes, Color.black, "45")
860
861Instead of repeating the color every time you can add a constructor that
862includes it: >
863
864 def newBlack(this.garment, this.size)
865 this.color = Color.black
866 enddef
867 ...
868 var pants = newBlack(Garment.pants, "XL")
869 var shirt = newBlack(Garment.shirt, "XL")
870 var shoes = newBlack(Garment.shoes, "9.5")
871
872Note that the method name must start with "new". If there is no method called
873"new()" then the default constructor is added, even though there are other
874constructor methods.
875
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +0100876Using variable type "any" for an Object~
877 *obj-var-type-any*
878You can use a variable declared with type "any" to hold an object. e.g.
879>
880 vim9script
881 class A
882 var n = 10
883 def Get(): number
884 return this.n
885 enddef
886 endclass
887
888 def Fn(o: any)
889 echo o.n
890 echo o.Get()
891 enddef
892
893 var a = A.new()
894 Fn(a)
895<
896In this example, Vim cannot determine the type of the parameter "o" for
897function Fn() at compile time. It can be either a |Dict| or an |Object|
898value. Therefore, at runtime, when the type is known, the object member
899variable and method are looked up. This process is not efficient, so it is
900recommended to use a more specific type whenever possible for better
901efficiency.
902
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +0100903Compiling methods in a Class ~
904 *class-compile*
905The |:defcompile| command can be used to compile all the class and object
906methods defined in a class: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000907
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +0100908 defcompile MyClass # Compile class "MyClass"
909 defcompile # Compile the classes in the current script
910<
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000911==============================================================================
912
Christian Brabandt6c1afa32024-01-01 20:50:51 +01009137. Type definition *typealias* *Vim9-type* *:type*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000914
Yegappan Lakshmanan2a71b542023-12-14 20:03:03 +0100915 *E1393* *E1395* *E1396* *E1397* *E1398*
916A type definition is giving a name to a type specification. This is also
917known as a "type alias". The type alias can be used wherever a built-in type
918can be used. Example: >
Yegappan Lakshmanan26e8f7b2023-10-06 10:24:10 -0700919
Yegappan Lakshmanan2a71b542023-12-14 20:03:03 +0100920 type ListOfStrings = list<string>
921 var s: ListOfStrings = ['a', 'b']
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000922
Yegappan Lakshmanan2a71b542023-12-14 20:03:03 +0100923 def ProcessStr(str: ListOfStrings): ListOfStrings
924 return str
925 enddef
926 echo ProcessStr(s)
927<
928 *E1394*
929A type alias name must start with an upper case character. Only existing
930types can be aliased.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000931
Yegappan Lakshmanan2a71b542023-12-14 20:03:03 +0100932 *E1399*
933A type alias can be created only at the script level and not inside a
934function. A type alias can be exported and used across scripts.
935
936 *E1400* *E1401* *E1402* *E1403* *E1407*
937A type alias cannot be used as an expression. A type alias cannot be used in
938the left-hand-side of an assignment.
939
940For a type alias name, the |typename()| function returns the type that is
941aliased: >
942
943 type ListOfStudents = list<dict<any>>
944 echo typename(ListOfStudents)
945 typealias<list<dict<any>>>
946<
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000947==============================================================================
948
Bram Moolenaarbe4e0162023-02-02 13:59:48 +00009498. Enum *Vim9-enum* *:enum* *:endenum*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000950
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +0100951 *enum* *E1418* *E1419* *E1420*
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000952An enum is a type that can have one of a list of values. Example: >
953
Doug Kearns49a35f62024-12-29 15:33:12 +0100954 enum Color
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +0100955 White,
956 Red,
957 Green, Blue, Black
Doug Kearns49a35f62024-12-29 15:33:12 +0100958 endenum
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +0100959<
960 *enumvalue* *E1422*
961The enum values are separated by commas. More than one enum value can be
962listed in a single line. The final enum value should not be followed by a
963comma.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000964
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +0100965An enum value is accessed using the enum name followed by the value name: >
Bram Moolenaarc1c365c2022-12-04 20:13:24 +0000966
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +0100967 var a: Color = Color.Blue
968<
969Enums are treated as classes, where each enum value is essentially an instance
970of that class. Unlike typical object instantiation with the |new()| method,
971enum instances cannot be created this way.
972
973An enum can only be defined in a |Vim9| script file. *E1414*
974An enum cannot be defined inside a function.
975
976 *E1415*
977An enum name must start with an uppercase letter. The name of an enum value
978in an enum can start with an upper or lowercase letter.
979
980 *E1416*
981An enum can implement an interface but cannot extend a class: >
982
983 enum MyEnum implements MyIntf
984 Value1,
985 Value2
986
987 def SomeMethod()
988 enddef
989 endenum
990<
991 *enum-constructor*
992The enum value objects in an enum are constructed like any other objects using
993the |new()| method. Arguments can be passed to the enum constructor by
994specifying them after the enum value name, just like calling a function. The
995default constructor doesn't have any arguments.
996
997 *E1417*
998An enum can contain class variables, class methods, object variables and
999object methods. The methods in an enum cannot be |:abstract| methods.
1000
1001The following example shows an enum with object variables and methods: >
1002
1003 vim9script
1004 enum Planet
1005 Earth(1, false),
1006 Jupiter(95, true),
1007 Saturn(146, true)
1008
1009 var moons: number
1010 var has_rings: bool
1011 def GetMoons(): number
1012 return this.moons
1013 enddef
1014 endenum
1015 echo Planet.Jupiter.GetMoons()
1016 echo Planet.Earth.has_rings
1017<
1018 *E1421* *E1423* *E1424* *E1425*
Aliaksei Budavei95740222024-04-04 23:05:33 +03001019Enums and their values are immutable. They cannot be utilized as numerical or
1020string types. Enum values can declare mutable instance variables.
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01001021
1022 *enum-name*
1023Each enum value object has a "name" instance variable which contains the name
1024of the enum value. This is a readonly variable.
1025
1026 *enum-ordinal* *E1426*
1027Each enum value has an associated ordinal number starting with 0. The ordinal
1028number of an enum value can be accessed using the "ordinal" instance variable.
1029This is a readonly variable. Note that if the ordering of the enum values in
1030an enum is changed, then their ordinal values will also change.
1031
1032 *enum-values*
1033All the values in an enum can be accessed using the "values" class variable
1034which is a List of the enum objects. This is a readonly variable.
1035
1036Example: >
1037 enum Planet
1038 Mercury,
1039 Venus,
1040 Earth
1041 endenum
1042
1043 echo Planet.Mercury
1044 echo Planet.Venus.name
1045 echo Planet.Venus.ordinal
1046 for p in Planet.values
1047 # ...
1048 endfor
1049<
1050An enum is a class with class variables for the enum value objects and object
1051variables for the enum value name and the enum value ordinal: >
1052
1053 enum Planet
1054 Mercury,
1055 Venus
1056 endenum
1057<
1058The above enum definition is equivalent to the following class definition: >
1059
1060 class Planet
1061 public static final Mercury: Planet = Planet.new('Mercury', 0)
1062 public static final Venus: Planet = Planet.new('Venus', 1)
1063
1064 public static const values: list<Planet> = [Planet.Mercury, Planet.Venus]
1065
1066 public const name: string
1067 public const ordinal: number
1068 endclass
1069<
Hirohito Higashi31b78cc2025-04-21 19:39:15 +02001070A enum can contain object variables and methods just like a regular class: >
Yegappan Lakshmanan4ec93fe2025-04-14 21:14:33 +02001071
1072 enum Color
1073 Cyan([0, 255, 255]),
1074 Magenta([255, 0, 255]),
1075 Gray([128, 128, 128])
1076
1077 var rgb_values: list<number>
1078
1079 def Get_RGB(): list<number>
1080 return this.rgb_values
1081 enddef
1082 endenum
1083 echo Color.Magenta.Get_RGB()
1084<
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001085==============================================================================
1086
10879. Rationale
1088
1089Most of the choices for |Vim9| classes come from popular and recently
1090developed languages, such as Java, TypeScript and Dart. The syntax has been
1091made to fit with the way Vim script works, such as using `endclass` instead of
1092using curly braces around the whole class.
1093
1094Some common constructs of object-oriented languages were chosen very long ago
1095when this kind of programming was still new, and later found to be
1096sub-optimal. By this time those constructs were widely used and changing them
1097was not an option. In Vim we do have the freedom to make different choices,
1098since classes are completely new. We can make the syntax simpler and more
1099consistent than what "old" languages use. Without diverting too much, it
1100should still mostly look like what you know from existing languages.
1101
1102Some recently developed languages add all kinds of fancy features that we
1103don't need for Vim. But some have nice ideas that we do want to use.
1104Thus we end up with a base of what is common in popular languages, dropping
1105what looks like a bad idea, and adding some nice features that are easy to
1106understand.
1107
1108The main rules we use to make decisions:
1109- Keep it simple.
1110- No surprises, mostly do what other languages are doing.
1111- Avoid mistakes from the past.
1112- Avoid the need for the script writer to consult the help to understand how
1113 things work, most things should be obvious.
1114- Keep it consistent.
1115- Aim at an average size plugin, not at a huge project.
1116
1117
1118Using new() for the constructor ~
1119
1120Many languages use the class name for the constructor method. A disadvantage
1121is that quite often this is a long name. And when changing the class name all
1122constructor methods need to be renamed. Not a big deal, but still a
1123disadvantage.
1124
1125Other languages, such as TypeScript, use a specific name, such as
1126"constructor()". That seems better. However, using "new" or "new()" to
1127create a new object has no obvious relation with "constructor()".
1128
1129For |Vim9| script using the same method name for all constructors seemed like
1130the right choice, and by calling it new() the relation between the caller and
1131the method being called is obvious.
1132
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001133No overloading of the constructor ~
1134
1135In Vim script, both legacy and |Vim9| script, there is no overloading of
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001136methods. That means it is not possible to use the same method name with
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001137different types of arguments. Therefore there also is only one new()
1138constructor.
1139
1140With |Vim9| script it would be possible to support overloading, since
1141arguments are typed. However, this gets complicated very quickly. Looking at
1142a new() call one has to inspect the types of the arguments to know which of
1143several new() methods is actually being called. And that can require
1144inspecting quite a bit of code. For example, if one of the arguments is the
1145return value of a method, you need to find that method to see what type it is
1146returning.
1147
1148Instead, every constructor has to have a different name, starting with "new".
1149That way multiple constructors with different arguments are possible, while it
1150is very easy to see which constructor is being used. And the type of
1151arguments can be properly checked.
1152
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001153No overloading of methods ~
1154
1155Same reasoning as for the constructor: It is often not obvious what type
1156arguments have, which would make it difficult to figure out what method is
1157actually being called. Better just give the methods a different name, then
1158type checking will make sure it works as you intended. This rules out
1159polymorphism, which we don't really need anyway.
1160
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001161Single inheritance and interfaces ~
1162
1163Some languages support multiple inheritance. Although that can be useful in
1164some cases, it makes the rules of how a class works quite complicated.
1165Instead, using interfaces to declare what is supported is much simpler. The
1166very popular Java language does it this way, and it should be good enough for
Bram Moolenaarbe4e0162023-02-02 13:59:48 +00001167Vim. The "keep it simple" rule applies here.
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001168
1169Explicitly declaring that a class supports an interface makes it easy to see
1170what a class is intended for. It also makes it possible to do proper type
1171checking. When an interface is changed any class that declares to implement
1172it will be checked if that change was also changed. The mechanism to assume a
1173class implements an interface just because the methods happen to match is
1174brittle and leads to obscure problems, let's not do that.
1175
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001176Using "this.variable" everywhere ~
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001177
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001178The object variables in various programming languages can often be accessed in
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001179different ways, depending on the location. Sometimes "this." has to be
1180prepended to avoid ambiguity. They are usually declared without "this.".
1181That is quite inconsistent and sometimes confusing.
1182
1183A very common issue is that in the constructor the arguments use the same name
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001184as the object variable. Then for these variables "this." needs to be prefixed
1185in the body, while for other variables this is not needed and often omitted.
1186This leads to a mix of variables with and without "this.", which is
1187inconsistent.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001188
Aliaksei Budaveib2149952024-01-07 17:52:10 +03001189For |Vim9| classes the "this." prefix is always used for declared methods and
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001190variables. Simple and consistent. When looking at the code inside a class
1191it's also directly clear which variable references are object variables and
1192which aren't.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001193
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001194Using class variables ~
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001195
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001196Using "static variable" to declare a class variable is very common, nothing
1197new here. In |Vim9| script these can be accessed directly by their name.
1198Very much like how a script-local variable can be used in a method. Since
1199object variables are always accessed with "this." prepended, it's also quickly
1200clear what kind of variable it is.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001201
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001202TypeScript prepends the class name before the class variable name, also inside
1203the class. This has two problems: The class name can be rather long, taking
1204up quite a bit of space, and when the class is renamed all these places need
1205to be changed too.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001206
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001207Declaring object and class variables ~
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001208
1209The main choice is whether to use "var" as with variable declarations.
1210TypeScript does not use it: >
1211 class Point {
1212 x: number;
1213 y = 0;
1214 }
1215
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001216Following that Vim object variables could be declared like this: >
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001217 class Point
1218 this.x: number
1219 this.y = 0
1220 endclass
1221
1222Some users pointed out that this looks more like an assignment than a
Aliaksei Budaveib2149952024-01-07 17:52:10 +03001223declaration. Adding "var" and omitting "this." changes that: >
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001224 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001225 var x: number
1226 var y = 0
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001227 endclass
1228
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001229We also need to be able to declare class variables using the "static" keyword.
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001230There we can also choose to leave out "var": >
1231 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001232 var x: number
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001233 static count = 0
1234 endclass
1235
1236Or do use it, before "static": >
1237 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001238 var x: number
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001239 var static count = 0
1240 endclass
1241
1242Or after "static": >
1243 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001244 var x: number
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +00001245 static var count = 0
1246 endclass
1247
1248This is more in line with "static def Func()".
1249
1250There is no clear preference whether to use "var" or not. The two main
1251reasons to leave it out are:
Doug Kearns74da0ee2023-12-14 20:26:26 +010012521. TypeScript and other popular languages do not use it.
Bram Moolenaar1b5f03e2023-01-09 20:12:45 +000012532. Less clutter.
1254
Doug Kearns74da0ee2023-12-14 20:26:26 +01001255However, it is more common for languages to reuse their general variable and
1256function declaration syntax for class/object variables and methods. Vim9 also
1257reuses the general function declaration syntax for methods. So, for the sake
1258of consistency, we require "var" in these declarations.
1259
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001260Using "ClassName.new()" to construct an object ~
1261
1262Many languages use the "new" operator to create an object, which is actually
1263kind of strange, since the constructor is defined as a method with arguments,
1264not a command. TypeScript also has the "new" keyword, but the method is
1265called "constructor()", it is hard to see the relation between the two.
1266
1267In |Vim9| script the constructor method is called new(), and it is invoked as
1268new(), simple and straightforward. Other languages use "new ClassName()",
1269while there is no ClassName() method, it's a method by another name in the
1270class called ClassName. Quite confusing.
1271
1272
Ernie Rael03042a22023-11-11 08:53:32 +01001273Vim9class access modes ~
1274 *vim9-access-modes*
1275The variable access modes, and their meaning, supported by Vim9class are
1276 |public-variable| read and write from anywhere
1277 |read-only-variable| read from anywhere, write from inside the
1278 class and sub-classes
1279 |protected-variable| read and write from inside the class and
1280 sub-classes
1281
1282The method access modes are similar, but without the read-only mode.
1283
1284
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001285Default read access to object variables ~
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001286
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001287Some users will remark that the access rules for object variables are
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001288asymmetric. Well, that is intentional. Changing a value is a very different
1289action than reading a value. The read operation has no side effects, it can
1290be done any number of times without affecting the object. Changing the value
1291can have many side effects, and even have a ripple effect, affecting other
1292objects.
1293
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001294When adding object variables one usually doesn't think much about this, just
1295get the type right. And normally the values are set in the new() method.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001296Therefore defaulting to read access only "just works" in most cases. And when
1297directly writing you get an error, which makes you wonder if you actually want
1298to allow that. This helps writing code with fewer mistakes.
1299
1300
Ernie Rael03042a22023-11-11 08:53:32 +01001301Making object variables protected with an underscore ~
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001302
Ernie Rael03042a22023-11-11 08:53:32 +01001303When an object variable is protected, it can only be read and changed inside
1304the class (and in sub-classes), then it cannot be used outside of the class.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001305Prepending an underscore is a simple way to make that visible. Various
1306programming languages have this as a recommendation.
1307
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001308In case you change your mind and want to make the object variable accessible
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001309outside of the class, you will have to remove the underscore everywhere.
1310Since the name only appears in the class (and sub-classes) they will be easy
1311to find and change.
1312
1313The other way around is much harder: you can easily prepend an underscore to
Ernie Rael03042a22023-11-11 08:53:32 +01001314the object variable inside the class to make it protected, but any usage
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001315elsewhere you will have to track down and change. You may have to make it a
1316"set" method call. This reflects the real world problem that taking away
1317access requires work to be done for all places where that access exists.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001318
Ernie Rael03042a22023-11-11 08:53:32 +01001319An alternative would have been using the "protected" keyword, just like
1320"public" changes the access in the other direction. Well, that's just to
1321reduce the number of keywords.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001322
Ernie Rael03042a22023-11-11 08:53:32 +01001323No private object variables ~
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001324
Yegappan Lakshmananc3b315f2023-09-24 14:36:17 -07001325Some languages provide several ways to control access to object variables.
1326The most known is "protected", and the meaning varies from language to
Ernie Rael03042a22023-11-11 08:53:32 +01001327language. Others are "shared", "private", "package" and even "friend".
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001328
1329These rules make life more difficult. That can be justified in projects where
1330many people work on the same, complex code where it is easy to make mistakes.
1331Especially when refactoring or other changes to the class model.
1332
1333The Vim scripts are expected to be used in a plugin, with just one person or a
1334small team working on it. Complex rules then only make it more complicated,
Bram Moolenaar71badf92023-04-22 22:40:14 +01001335the extra safety provided by the rules isn't really needed. Let's just keep
1336it simple and not specify access details.
Bram Moolenaarc1c365c2022-12-04 20:13:24 +00001337
1338
1339==============================================================================
1340
134110. To be done later
1342
1343Can a newSomething() constructor invoke another constructor? If yes, what are
1344the restrictions?
1345
1346Thoughts:
1347- Generics for a class: `class <Tkey, Tentry>`
1348- Generics for a function: `def <Tkey> GetLast(key: Tkey)`
1349- Mixins: not sure if that is useful, leave out for simplicity.
1350
1351Some things that look like good additions:
1352- For testing: Mock mechanism
1353
1354An important class to be provided is "Promise". Since Vim is single
1355threaded, connecting asynchronous operations is a natural way of allowing
1356plugins to do their work without blocking the user. It's a uniform way to
1357invoke callbacks and handle timeouts and errors.
1358
1359
1360 vim:tw=78:ts=8:noet:ft=help:norl: