Класс наследования в 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")
Другие вопросы по тегам