【问题标题】:Class inheritance in GenieGenie 中的类继承
【发布时间】:2016-09-04 02:37:49
【问题描述】:

为了理解 Genie 中的类继承,我创建了两个类(Kitten 和 Puppy),它们应该从 Pet 类继承属性。目的是让 minou 喵喵叫,让 duke 吠叫,但是 _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!"

【问题讨论】:

  • 你有一个简单的错字,我修正了,我添加了我现在收到的错误消息。解决方案是使 _name 受保护而不是私有。
  • 但是我不知道 Genie 类中受保护/公共成员的语法,也许这是一个限制,应该报告给 bugzilla.gnome.org

标签: inheritance vala genie


【解决方案1】:

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

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!"

【讨论】:

    【解决方案2】:
    [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")
    

    【讨论】:

      猜你喜欢
      • 2010-11-08
      • 1970-01-01
      • 2020-04-18
      • 2023-03-27
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2013-05-26
      • 1970-01-01
      相关资源
      最近更新 更多