Genie中的类继承

时间:2016-09-04 02:37:50

标签: inheritance vala genie

试图理解Genie中的类继承,我创建了两个应该从Pet类继承属性的类(Kitten和Puppy)。目的是要求minou喵喵叫公爵,但是_name似乎超出了孩子们的范围。如何将此属性传递给子类?

以下是代码:

[indent=4]

// Experimenting with classes in Genie

class Pet

    _name:string

    construct ( name:string? )

        _name = name

class Kitten : Pet

    def meow()
        print self._name + " meowed!"

class Puppy : Pet

    def bark()
        print self._name + " barked!"

init
    var minou = new Kitten("Minou")
    var duke = new Puppy("Duke")

    minou.meow()
    duke.bark()

错误消息是:

Test78.gs:16.15-16.24: error: Access to private member `Pet._name' denied
        print self._name + " meowed!"

2 个答案:

答案 0 :(得分:2)

互联网上有很多关于继承的教程,它们经常使用动物或部分车辆创建复杂的层次结构。从概念上讲,这些继承层次结构是严格的,这就是为什么通常更好的方法是在构造函数中传递协作对象(支持组合而不是继承),并根据接口(多态)对协作者进行类型检查。这会创建解耦对象,并在程序中提供更大的灵活性,可维护性和可测试性。所以要学习继承,但也要从批判的角度来看。

Genie确实支持子类型和继承。你的程序遇到两个问题。第一个是范围,第二个是将参数传递给构造函数链。

首先是范围问题。 Genie中的下划线表示班级成员是私人的。它只能由该类的实例访问。要允许从子类型计算机语言访问它,请使用protected访问修饰符。目前,Genie解析器中尚未实现此功能。见Bug 690848 - Add support for "protected" class members 。所以我们必须公开name字段。这允许从子类型访问它,也可以从程序的任何部分访问Pet的实例。在Genie中,我们只需删除下划线即可公开。

一旦你使用了作用域,你就会收到一个错误“无法链接到需要参数的基础构造函数”。您需要为子类型添加构造函数,这些构造函数需要设置name字段。这可以直接完成,例如name = pet_name,或通过使用正确的参数调用超类型的构造函数,例如super( pet_name )。下面是一个显示两种方式的工作示例:

[indent=4]
init
    var minou = new Kitten( "Minou" )
    var duke = new Puppy( "Duke" )
    minou.meow()
    duke.bark()


class Pet
    name:string

    construct( pet_name:string = "Anonymous" )
        name = pet_name


class Kitten:Pet
    construct( pet_name:string = "Anonymous" )
        name = pet_name

    def meow()
        print name + " meowed!"


class Puppy:Pet
    construct( pet_name:string = "Anonymous" )
        super( pet_name )

    def bark()
        print name + " barked!"

答案 1 :(得分:1)

[indent=4]

class Pet

    prop  name:string

class Kitten : Pet

    def meow(name : string)
        print self.name + " meowed!"

class Puppy : Pet

    def bark(name : string)
        print self.name + " barked!"

init
    var minou = new Kitten()
    var duke = new Puppy()

    minou.meow(minou.name="Minou")
    duke.bark(duke.name="Duke")