Lisp 什么';CLOS中的构造函数的等价物是什么?

Lisp 什么';CLOS中的构造函数的等价物是什么?,lisp,common-lisp,clos,Lisp,Common Lisp,Clos,如何用Lisp表达以下Java代码 class Foo { private String s; public Foo(String s) { this.s = s; } } class Bar extends Foo { public Bar(int i) { super(Integer.toString(i)); } } 在Lisp中,make instance或initialize instance是否等同于构造函

如何用Lisp表达以下Java代码

class Foo {
    private String s;

    public Foo(String s) {
        this.s = s;
    }
}

class Bar extends Foo {
    public Bar(int i) {
        super(Integer.toString(i));
    }
}

在Lisp中,
make instance
initialize instance
是否等同于构造函数?如果是,如何调用超类构造函数?

使用
call-NEXT-METHOD
从方法中调用下一个方法

通常只需使用标准方法组合工具,为
初始化实例
编写
:BEFORE
:AFTER
:AROUND
方法

单向:

(defclass foo ()
  ((s :type string :initarg :s)))

(defclass bar (foo) ())

(defmethod initialize-instance :around ((b bar) &key i)
  (call-next-method b :s (princ-to-string i)))
例如:

CL-USER 17 > (make-instance 'bar :i 10)
#<BAR 402000B95B>

CL-USER 18 > (describe *)

#<BAR 4130439703> is a BAR
S      "10"
CL-USER 17>(制作实例栏:i10)
#
CL-USER 18>(描述*)
#这是一家酒吧
S“10”

注意,我调用了
CALL-NEXT-METHOD
,但没有更改它分派的参数。我刚刚更改了
&key
initarg参数。

这里是对Rainier示例的一个放大,增加了一个小转折: 通过约束插槽值进行专门化(子类化),至少 施工时间。考虑一个类,M盒,用于二维矩形:

(defclass m-box ()
  ((left   :accessor m-box-left   :initform 0 :type integer :initarg :left  )
   (top    :accessor m-box-top    :initform 0 :type integer :initarg :top   )
   (width  :accessor m-box-width  :initform 0 :type integer :initarg :width )
   (height :accessor m-box-height :initform 0 :type integer :initarg :height)))
我们可以这样尝试:

(describe (make-instance 'm-box :left 42 :top -39 :width 5 :height  11))

: #<M-BOX {10047A8F83}>
:   [standard-object]
: 
: Slots with :INSTANCE allocation:
:   LEFT    = 42
:   TOP     = -39
:   WIDTH   = 5
:   HEIGHT  = 11
我们可以制作m-block的一个实例,如下所示:

(describe (make-instance 'm-block :left 17 :top -34 :width 5 :height  11))

: #<M-BLOCK {10049C0CC3}>
:   [standard-object]
: 
: Slots with :INSTANCE allocation:
:   LEFT    = 17
:   TOP     = -34
:   WIDTH   = 1
:   HEIGHT  = 1
用户的以下尝试被拒绝:

(describe (make-instance 'm-block :left 17 :top -34 :width 5 :height  11))

an m-block must have unit width and height
   [Condition of type SIMPLE-ERROR]
但这一点也证明了高度的默认值,它经历了:

(describe (make-instance 'm-block :left 17 :top -34 :width 1))

: #<M-BLOCK {1005377983}>
:   [standard-object]
: 
: Slots with :INSTANCE allocation:
:   LEFT    = 17
:   TOP     = -34
:   WIDTH   = 1
:   HEIGHT  = 1
(描述(使实例'm-block:左17:顶部-34:宽度1))
: #
:[标准对象]
: 
:插槽:实例分配:
:左=17
:TOP=-34
:宽度=1
:高度=1
此示例允许用户设置宽度或高度。我不知道 知道如何在子类实例中使宽度和高度为只读
而不是在超类的实例中。

不调用NEXT-METHOD,只调用具有相同参数的NEXT方法。我将如何实现我的示例,即将整型参数转换为字符串并将其传递给超类方法?@Tobias Brandt:参见我的示例
(defclass m-block (m-box) ())
(defmethod initialize-instance
  :around
  ((mb m-block)
   &key (left 0) (top 0) (width 1) (height 1))
  (when (or (/= 1 width) (/= 1 height))
    (error "an m-block must have unit width and height"))
  (call-next-method mb :left left :top top :width 1 :height 1))
(describe (make-instance 'm-block :left 17 :top -34 :width 5 :height  11))

an m-block must have unit width and height
   [Condition of type SIMPLE-ERROR]
(describe (make-instance 'm-block :left 17 :top -34 :width 1))

: #<M-BLOCK {1005377983}>
:   [standard-object]
: 
: Slots with :INSTANCE allocation:
:   LEFT    = 17
:   TOP     = -34
:   WIDTH   = 1
:   HEIGHT  = 1