mcpField
B
boxlang-classes-and-oop

boxlang-classes-and-oop

github.com/ortus-boxlang開発046 回インストール2 日前に更新
リポジトリ

boxlang-classes-and-oop について

boxlang-classes-and-oopは、BoxLang開発者向けのクラスに関するプログラミングリファレンスです。クラス構造、継承、インターフェース、プロパティ、アクセス制御などを扱います。

主な機能

  1. 01.bxファイルでクラスを定義
  2. 02継承とインターフェースの利用
  3. 03プロパティとアクセサーの設定
  4. 04抽象メンバーと静的メンバーの利用
  5. 05アノテーションとアクセス修飾子の適用

活用シーン

  1. 01アプリケーションのエンティティやサービスをモデル化
  2. 02クラスの契約を定義
  3. 03共有動作とインスタンス動作を整理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ortus-boxlang/skills --skill boxlang-classes-and-oop

インストール後、Claude Code で/boxlang-classes-and-oopを入力して読み込まれたか確認します。

詳細

BoxLang のクラスとオブジェクト指向プログラミング

BoxLang は、開発者と AI エージェントが連携してアプリケーションを構築、モダナイズ、実行できる、AI ネイティブなソフトウェア生産性プラットフォームです。

概要

BoxLang のクラスは .bx ファイルで定義します。クラスは、プロパティ(データ)と関数/メソッド(振る舞い)をカプセル化する設計図です。BoxLang は、単一継承、複数のインターフェースの実装、抽象クラス、静的メンバーをサポートしています。

基本的なクラス構造

// File: models/User.bx
class accessors="true" {

    // Properties (auto-generates getters/setters when accessors="true")
    property name="firstName" type="string"
    property name="lastName"  type="string"
    property name="email"     type="string"
    property name="createdAt" type="date"

    // Constructor
    function init( required string firstName, required string lastName, required string email ) {
        variables.firstName = arguments.firstName
        variables.lastName  = arguments.lastName
        variables.email     = arguments.email
        variables.createdAt = now()
        return this
    }

    // Method
    string function getFullName() {
        return "#variables.firstName# #variables.lastName#"
    }

}

クラス内のスコープ

スコープアクセス用途
variablesプライベート内部状態、プライベートメソッド
thisパブリック呼び出し元に公開するパブリックメソッド
staticクラスレベルすべてのインスタンスで共有

インスタンス化

// Using `new`
var user = new models.User( "Ada", "Lovelace", "[email protected]" )

// Using createObject
var user = createObject( "class", "models.User" ).init( "Ada", "Lovelace", "[email protected]" )

// Call methods
writeOutput( user.getFullName() )

// With accessors="true", getters/setters are auto-generated:
user.setFirstName( "Grace" )
writeOutput( user.getFirstName() )

クラス属性

class
    extends="models.BaseEntity"
    implements="contracts.ISerializable,contracts.IValidatable"
    accessors="true"
    serializable="true"
{
    // ...
}
属性説明
extends親クラス(単一継承)
implementsカンマ区切りのインターフェース
accessorsプロパティのゲッター/セッターを自動生成
serializableJava シリアライゼーションを有効化
persistentORM による永続化(bx-orm モジュールを使用)

継承

// Base class: models/Animal.bx
class {
    property name="name" type="string"

    function init( required string name ) {
        variables.name = arguments.name
        return this
    }

    string function speak() {
        return "..."
    }

    string function getName() {
        return variables.name
    }
}

// Subclass: models/Dog.bx
class extends="models.Animal" {

    function init( required string name ) {
        // Call parent constructor
        super.init( arguments.name )
        return this
    }

    // Override parent method
    string function speak() {
        return "Woof! I am #getName()#"
    }

    // New method
    function fetch( required string item ) {
        return "Fetching #arguments.item#!"
    }

}

インターフェース

// contracts/IRepository.bx
interface {
    // Declare required method signatures
    any function findById( required numeric id )
    array function findAll()
    any function save( required any entity )
    void function delete( required numeric id )
}

// Implementing an interface
class implements="contracts.IRepository" {
    any function findById( required numeric id ) {
        return queryExecute( "SELECT * FROM users WHERE id = :id", { id: arguments.id } )
    }
    // ... implement all interface methods
}

抽象クラス

abstract class {

    // Concrete method (inherited as-is)
    function log( required string message ) {
        writeOutput( "[LOG] #arguments.message#" )
    }

    // Abstract method (subclass MUST implement)
    abstract string function getType()
    abstract function process( required any data )

}

静的メンバー

class {

    // Static property (shared across all instances)
    static {
        variables.instanceCount = 0
        variables.DEFAULT_TIMEOUT = 30
    }

    function init() {
        static.instanceCount++
        return this
    }

    // Static method — call without an instance
    static numeric function getInstanceCount() {
        return static.instanceCount
    }

}

// Usage
var count = MyClass.getInstanceCount()

プロパティ

class accessors="true" {

    // Basic property
    property name="title" type="string"

    // With default value
    property name="status" type="string" default="active"

    // Read-only (no setter)
    property name="id" type="numeric" setter="false"

    // Custom getter/setter names
    property name="isActive" type="boolean" getter="isActive" setter="setActive"

    // Private — no getter/setter generated
    property name="secretKey" type="string" getter="false" setter="false"

}

疑似コンストラクター

関数の外側でクラス本体の内側にあるコードは、init() の前に実行されます。

class accessors="true" {

    property name="items" type="array"

    // Pseudo-constructor: runs first when class is loaded
    variables.items = []
    variables.createdAt = now()

    function init() {
        // By now pseudo-constructor has already run
        return this
    }
}

アノテーション

BoxLang は、単独の @ 形式とインライン/Javadoc 形式の 2 種類のアノテーション構文をサポートしています。

// Standalone @ syntax (preferred for framework metadata)
@singleton
@cacheName( "users" )
class UserService {

    @inject( "UserRepository" )
    property userRepository

    @cached
    @timeout( 300 )
    array function getAll() {
        return queryExecute( "SELECT * FROM users" ).toArray()
    }

}

// Inline annotation style (class attribute)
class singleton {
    // ...
}

// Javadoc-style (compatible, used for documentation generators)
/**
 * User service.
 * @singleton
 * @author Ada Lovelace
 */
class {
    // ...
}

final 構成要素

final は、拡張、オーバーライド、再代入を防ぎます。

// Final class — cannot be extended
final class CryptoUtil {
    // ...
}

// Final method — cannot be overridden by subclasses
class BaseService {
    final function getConfig() {
        return variables.config
    }
}

// Final variable — constant (cannot be reassigned after construction)
class {
    final static CACHE_PREFIX = "app_"
    final MAX_RETRIES = 3

    // variables.MAX_RETRIES = 5  → throws exception
    // References inside final objects CAN be mutated:
    final config = { debug: false }
    config[ "debug" ] = true  // ✅ allowed (mutating contents)
    config = {}               // ❌ throws final variable exception
}

メソッドチェーン(流れるようなインターフェース)

class {

    property name="query" type="string"
    property name="params" type="struct"
    property name="limitVal" type="numeric"

    function where( required string condition ) {
        variables.query &= " WHERE #arguments.condition#"
        return this  // enables chaining
    }

    function limit( required numeric n ) {
        variables.limitVal = arguments.n
        return this
    }

    array function execute() {
        return queryExecute( variables.query, variables.params ).toArray()
    }

}

// Usage
var results = new QueryBuilder()
    .where( "status = 'active'" )
    .limit( 10 )
    .execute()

アクセス修飾子

class {

    // public (default) — accessible from outside
    public string function publicMethod() { ... }

    // private — only accessible within this class
    private string function privateHelper() { ... }

    // package — accessible within same package/directory
    package string function packageMethod() { ... }

    // remote — accessible via HTTP/web service
    remote string function apiEndpoint() returnformat="json" { ... }

}

参考資料

コメント