Class精灵中的继承
Class inheritance in Genie
为了理解 Genie 中的 class 继承,我创建了两个 classes(小猫和小狗),它们应该从宠物 class 继承属性。目的是让 minou 喵喵叫,让 duke 吠叫,但是 _name 似乎超出了 child classes 的范围。如何将此 属性 传递给 child classes?
代码如下:
[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!"
网上有很多关于继承的教程,他们经常使用动物或车辆部件创建复杂的层次结构。从概念上讲,这些继承层次结构是严格的,这就是为什么在构造函数中传递协作对象(有利于组合而不是继承)并针对接口(多态性)对协作者进行类型检查通常更好。这会创建解耦对象,并允许您的程序具有更大的灵活性、可维护性和可测试性。所以学习继承,也要从批判的角度去做。
Genie 支持子类型化和继承。您的程序遇到两个问题。第一个是作用域,第二个是在构造函数链中向上传递参数。
首先是范围问题。 Genie 中的下划线表示 class 成员是私有的。它只能由 class 的一个实例访问。要允许从子类型计算机语言访问它,请使用 protected
访问修饰符。这目前在 Genie 解析器中没有实现。参见 Bug 690848 - Add support for "protected" class members 。所以我们必须使 name
字段 public。这允许从子类型访问它,也可以从范围内 Pet
实例的程序的任何部分访问它。在 Genie 中,我们只需删除下划线使其成为 public.
一旦您的示波器开始工作,您将收到一个错误 "unable to chain up to base constructor requiring arguments"。您需要为子类型添加构造函数,这些构造函数需要设置 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!"
[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")
为了理解 Genie 中的 class 继承,我创建了两个 classes(小猫和小狗),它们应该从宠物 class 继承属性。目的是让 minou 喵喵叫,让 duke 吠叫,但是 _name 似乎超出了 child classes 的范围。如何将此 属性 传递给 child classes?
代码如下:
[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!"
网上有很多关于继承的教程,他们经常使用动物或车辆部件创建复杂的层次结构。从概念上讲,这些继承层次结构是严格的,这就是为什么在构造函数中传递协作对象(有利于组合而不是继承)并针对接口(多态性)对协作者进行类型检查通常更好。这会创建解耦对象,并允许您的程序具有更大的灵活性、可维护性和可测试性。所以学习继承,也要从批判的角度去做。
Genie 支持子类型化和继承。您的程序遇到两个问题。第一个是作用域,第二个是在构造函数链中向上传递参数。
首先是范围问题。 Genie 中的下划线表示 class 成员是私有的。它只能由 class 的一个实例访问。要允许从子类型计算机语言访问它,请使用 protected
访问修饰符。这目前在 Genie 解析器中没有实现。参见 Bug 690848 - Add support for "protected" class members 。所以我们必须使 name
字段 public。这允许从子类型访问它,也可以从范围内 Pet
实例的程序的任何部分访问它。在 Genie 中,我们只需删除下划线使其成为 public.
一旦您的示波器开始工作,您将收到一个错误 "unable to chain up to base constructor requiring arguments"。您需要为子类型添加构造函数,这些构造函数需要设置 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!"
[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")