如何在coffescript中继承带参数的类?

时间:2016-12-22 00:20:20

标签: class inheritance coffeescript

我有课程Human,我希望课程SocialBeing继承Human。但是在super(Human)方法中,Human类作为第一个位置参数传递给Human类实例,并且它的缺点和错误。从SocialBeing继承Human的正确方法是什么?

class Human  # As biological creature
    constructor: (@given_sex = null,
                  @age = null,  # Age of the person
                  @max_age = 85) ->  # Maximum allowed age of the person during person generation

        _alive = true

        alive: ->
            @_alive

        dead: ->
            not @alive()

        has_died: ->
            @_alive = false

        _available_sexes: {0: 'female', 1: 'male'}

        sex: ->
            _sex = @_available_sexes[@given_sex]

        @generate_human()

     generate_human: ->
            @_alive = true
            if @age is null
                @age = Math.floor(Math.random() * @max_age)
            if @given_sex is null
                @given_sex = Math.floor(Math.random() * 2)
            else if @given_sex not in [0,1]
                n = @given_sex
                err = 'Invalid sex value: ' + n
                console.log(err)
                throw new Error(err)


class SocialBeing extends Human  # Describes socialisation
    constructor: (@first_name = null,
                  @second_name = null,
                  @middle_name = null,
                  @other_name = null) ->
         super(Human)

         marital_status: null

h = new SocialBeing(first_name='Pal')  # In JavaScript thows an error

1 个答案:

答案 0 :(得分:0)

我认为你以错误的方式使用super。 我稍微简化了你的例子

class Human
     constructor: (@given_sex = null) ->  
          @generate_human()

     generate_human: ->
         if @given_sex is null
             @given_sex = Math.floor(Math.random() * 2)
         else if @given_sex not in [0,1]
             n = @given_sex
             err = 'Invalid sex value: ' + n
             console.log(err)
         else
              console.log("my sex is", @given_sex)

到目前为止,你的基类还行。现在,对于派生类,您可以在调用super

时显式设置参数
class SocialBeing extends Human
     constructor: (@first_name = null) ->
          super 1
          #or
          super null

但不知何故,这会破坏基类构造函数参数的用途。通常的方法是将基类构造函数参数添加到派生类构造函数参数

class SocialBeing extends Human
     constructor: (sex = null, @first_name = null) ->
          super sex

然后相应地设置你的派生类

h = new SocialBeing(sex = 1, first_name='Pal')

虽然在它的描述性常量也很好

male = 0
female = 1
h = new SocialBeing(male, 'Pal')

或者如果您觉得特别进步,可以添加FB的58种性别表达; - )

现在显然将所有这些ctor参数传递给super会变得有点麻烦。所以你能做的就是

class Human
      constructor: (@given_sex = null,
                    @age = null,  # Age of the person
                    @max_age = 85)

class SocialBeing extends Human
     constructor: (@first_name = null,
                   @second_name = null,
                   @middle_name = null,
                   @other_name = null) ->
          super arguments...

然而,有这么多论据特别是可选的,我认为这是一种设计气味。

我希望这会有所帮助