Posted to tcl by aspect at Thu Sep 11 00:20:32 GMT 2014view pretty

oo::class create AbstractMixin {
    superclass oo::class
    constructor {abstractmethods} {
        oo::define [self] constructor {args} [format {
            debug log {Constructing an abstract instance [self] that needs %1$s}
            next {*}$args
            set mymethods [info class methods [self] -all]
            foreach m %1$s {
                if {$m ni $mymethods} {
                    throw {CLASS ABSTRACTMETHOD} "abstract method $m not provided in [self]!"
                }
            }
        } [list $abstractmethods]]
    }
}

# AbstractBase is a klass which provides "abstractmethod"
klass create AbstractBase {
    variable abstractmethods
    constructor args {
        set abstractmethods {}
        next {*}$args
        oo::define [self] mixin [AbstractMixin new $abstractmethods]
    }
    method abstractmethod {name} {
        lappend abstractmethods $name
    }
}