Класс наследования в Genie
Пытаясь понять наследование классов в 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!"
2 ответа
В Интернете существует множество учебных пособий, касающихся наследования, и они часто создают сложные иерархии с использованием животных или частей транспортных средств. Концептуально эти иерархии наследования являются жесткими, и именно поэтому часто лучше передавать взаимодействующие объекты в конструкторе (предпочтение композиции по наследованию) и проверять тип соавторов по интерфейсу (полиморфизм). Это создает разъединенные объекты и обеспечивает большую гибкость, удобство сопровождения и тестируемость в вашей программе. Так что узнайте о наследовании, но и сделайте это с критической точки зрения.
Джинн поддерживает подтип и наследование. Ваша программа сталкивается с двумя проблемами. Первый - это область действия, а второй - передача параметров по цепочке конструкторов.
Сначала проблема объема. Подчеркивание в Genie означает, что ученик является личным. Доступ к нему может получить только экземпляр этого класса. Чтобы разрешить доступ к нему с подтипов компьютерных языков, используйте protected
модификатор доступа. В настоящее время это не реализовано в парсере Genie. См. Ошибка 690848 - Добавлена поддержка "защищенных" членов класса. Таким образом, мы должны сделать 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!"
[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")