Class
Class
Function
class is used to encapsulate a set of fields and methods into the same object structure. Fields save instance status, methods describe instance behavior, and this is used internally to access the current instance.
BT's class syntax follows a JavaScript-like style, but constructs instances with ClassName::constructor(...). The most common constructor name is new, so this is usually written as User::new(...).
Syntax
Define class
class ClassName { field_name: initial_value field_name pub public_field: initial_value method_name(parameter1, parameter2) { method_body } pub public_method(parameter) { method_body } new(parameter) { initialization_logic this } }
Create instance
object = ClassName::new(parameter) object = ClassName::other_public_constructor(parameter)
Class::new() is the current instantiation writing method of BT, not new Class().
Members
class members are divided into fields and methods. The
Fields use name: expression declarations:
class User { name: 'Unnamed' age: 0 }
Naked field The
field can also only write the name without writing : and initial value. This writing method is called a naked field. The naked field will occupy a member name in the instance in advance, and the default value is empty.
class User { name new(name) { this.name = name this } pub get_name() { this.name } } user = User::new('Tom') println user.get_name()
The naked fields name and name: '' are different: the default value of name is empty, and the default value of name: '' is the empty string. this.name = name is usually used in the constructor to override the default value. The
Methods do not use fn; write method_name(parameters) { ... } directly:
class User { name: 'BT' pub get_name() { this.name } }
method has the same return value as an ordinary function. When there is no explicit return, the value of the last statement in the method body is the return value.
this
this represents the currently operating instance and is only used in class methods and constructors.
class Counter { value: 0 pub inc() { this.value++ this } pub get() { this.value } } counter = Counter::new() counter.inc().inc() println counter.get()
this.value is used to read the current instance fields, this.value = 1 is used to write the current instance fields, and this.method() is used to call other methods of the current instance.
Access to private members must be done directly through this.xxx. Do not assign this to other variables before accessing private members, because permission judgment only regards access directly from this as class internal access.
class User { password: '' new(password) { this.password = password this } check(password) { this.password == password } pub login(password) { this.check(password) } }
new
new is the most common constructor name. Write ClassName::new(...) when creating an instance.
class User { name: '' age: 0 new(name, age) { this.name = name this.age = age this } pub info() { this.name + ':' + this.age } } user = User::new('Tom', 18) println user.info()
If new is not defined in the class, Class::new() will still create an instance and use the default value in the class field:
class Config { pub host: '127.0.0.1' pub port: 8080 } config = Config::new() println config.host println config.port
The constructor return rule requires special attention: the BT method returns the value of the last statement by default. After the constructor is executed, if empty or null is returned, Class::new() will return a new instance; if another value is returned, that value will be returned.
Therefore, it is recommended to write this in the last line of the constructor to clearly return the current instance:
class User { name: '' new(name) { this.name = name this } }
Don't just put the assignment statement in the last line of the constructor:
class User { name: '' new(name) { this.name = name } } user = User::new('Tom')
The last statement of new above is an assignment expression, and the assignment expression returns 'Tom' on the right, so User::new('Tom') returns a string, not an instance.
Multiple structure entries
BT constructors are not limited to new. Any public method can be used as a construction entry through ClassName::method_name(...): the runtime first creates an instance, then binds this to it while executing that method.
class User { name: '' role: 'user' new(name) { this.name = name this } pub admin(name) { this.name = name this.role = 'admin' this } pub label() { this.name + ':' + this.role } } tom = User::new('Tom') root = User::admin('Root') println tom.label() println root.label()
Except for new, the method used as the entrance to the construction needs to be pub, otherwise it cannot be accessed outside the class.
Public and private
class members are private by default. Only fields or methods added with pub can be accessed through instances outside the class.
class Account { balance: 0 new(balance) { this.balance = balance this } pub deposit(amount) { this.balance += amount this } pub get_balance() { this.balance } can_withdraw(amount) { this.balance >= amount } pub withdraw(amount) { if this.can_withdraw(amount) { this.balance -= amount true } else { false } } } account = Account::new(100) account.deposit(50) println account.get_balance() println account.withdraw(80) println account.get_balance()
Externally accessible:
account.deposit(50) account.get_balance()
Externally not accessible:
account.balance account.can_withdraw(10)
Private members are still accessible inside the class via this:
this.balance this.can_withdraw(10)
BT currently does not have the private keyword. The default is private, write pub only when it needs to be made public.
Field writing
Public fields can be read and written outside the class:
class User { pub name: '' } user = User::new() user.name = 'Tom' println user.name
Private fields can only be written inside the class through this:
class User { name: '' pub set_name(name) { this.name = name this } pub get_name() { this.name } }
If a field that has not been declared in the class definition is added to this, this field will be saved as a private field; if a field is added on an external instance, this field will be saved as a public field.
class User { pub set_token(token) { this.token = token this } } user = User::new() user.set_token('abc') user.nickname = 'Tom'
The above token is a private field added through this inside the class, and nickname is a public field added externally.
Chain call
BT supports chain call. If the class method wants to continue the chain call, just return this.
class Query { table: '' where_sql: '' limit_size: 0 new(table) { this.table = table this } pub where(sql) { this.where_sql = sql this } pub limit(size) { this.limit_size = size this } pub sql() { 'select * from ' + this.table + ' where ' + this.where_sql + ' limit ' + this.limit_size } } sql = Query::new('users') .where('age >= 18') .limit(10) .sql() println sql
Parameters
class itself has no calling parameters. Parameters are written on the constructor or ordinary method.
class Page { page: 1 size: 20 new(page = 1, size = 20) { this.page = page this.size = size this } } p1 = Page::new() p2 = Page::new(2, 50)
Return Value
-
class Name { ... }will create a class value and save it to the class name variable. -
Name::new(...)returns a class instance by default. -
Name::method(...)will first create a class instance, and then execute the specified method as the construction entry. - The instance method returns the value of the last statement in the method body, or you can use
returnto force the return.
empty or null; it returns that value when another value is returned.
Code Examples
Complete encapsulation example
class User { name: '' password: '' pub role: 'user' new(name, password) { this.name = name this.password = password this } pub admin(name, password) { this.name = name this.password = password this.role = 'admin' this } pub get_name() { this.name } pub rename(name) { this.name = name this } check_password(password) { this.password == password } pub login(password) { this.check_password(password) } pub label() { this.name + '[' + this.role + ']' } } user = User::new('Tom', '123456') admin = User::admin('Root', 'root_pwd') println user.rename('Tommy').label() println user.login('123456') println admin.label()
Private member protection status
class Counter { value: 0 new(start = 0) { this.value = start this } pub inc() { this.value++ this } pub dec() { this.value-- this } pub get() { this.value } } counter = Counter::new(10) counter.inc().inc().dec() println counter.get()
Notes
-
Class::new()is instantiation syntax; do not writenew Class().
new is the recommended constructor name; if new is not defined, Class::new() will also return an instance with default fields.
- It is recommended to write
thisin the last line of the construction method to prevent the last assignment statement from returning ordinary values such as strings and numbers as the construction result. - Members are private by default; public fields or methods must be written as
pub.
this.xxx.
- There is currently no
private,extends,super,staticsyntax; do not use it according to the JS class inheritance writing method. - Field initial values are suitable for scalar default values; variable values such as arrays and objects are recommended to be initialized with
this.xxx = []orthis.xxx = {}innewto avoid multiple instances sharing the same default reference.