2016-09-04 6 views
1

Попытка понять наследование классов в Genie, я создал два класса (Kitten and Puppy), которые должны наследовать свойства из класса Pet. Цель состоит в том, чтобы попросить миноу, чтобы мяуканье и герцог лаять, однако, похоже, что имя не выходит за рамки классов ребенка. Как передать это свойство дочерним классам?Наследование класса в Genie

Вот код:

[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!" 
+0

Вы имели просто опечатка, который я установил, я добавил сообщение об ошибке я получаю в настоящее время. Решением было бы сделать '_name' защищенным, а не частным. –

+0

Однако я не знаю синтаксиса для защищенных/открытых членов в классах Genie, возможно, это ограничение и должно быть сообщено bugzilla.gnome.org –

ответ

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
[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")