Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

puts @var # (Переменная экземпляра класса.)

 end

end

def MyClass.classmeth2

 puts MyClass::SOME_CONST # (Константа класса.)

 # puts @@var # Ошибка: вне области видимости.

 puts @var # (Переменная экземпляра класса.)

end

myobj = MyClass.new

MyClass.classmeth1 # alpha, beta, gamma

MyClass.classmeth2 # alpha, gamma

myobj.mymethod # alpha, beta, delta

Следует еще сказать, что метод класса можно сделать закрытым, воспользовавшись методом

private_class_method
. Это аналог метода
private
на уровне экземпляра. См. также раздел 11.2.10.

11.1.5. Наследование суперклассу

Можно унаследовать класс, воспользовавшись символом

<
:

class Boojum < Snark

 # ...

end

Это объявление говорит, что класс

Boojum
является подклассом класса
Snark
или — что то же самое — класс
Snark
является суперклассом класса
Boojum
. Всем известно, что каждый буюм является снарком, но не каждый снарк — буюм.

Ясно, что цель наследования — расширить или специализировать функциональность. Мы хотим получить из общего нечто более специфическое.

Попутно отметим, что во многих языках, например в C++, допускается множественное наследование (МН). В Ruby, как и в Java, и в некоторых других языках, множественного наследования нет, но наличие классов-примесей компенсирует его отсутствие (см. раздел 11.1.12).

Рассмотрим несколько более реалистичный пример. У нас есть класс

Person
(человек), а мы хотим создать производный от него класс
Student
(студент).

Определим класс

Person
следующим образом:

class Person

 attr_accessor :name, :age, :sex

 def initialize(name, age, sex)

@name, @age, @sex = name, age, sex

 end

 # ...

end

А класс

Student
— так:

class Student < Person

 attr_accessor :idnum, :hours

 def initialize(name, age, sex, idnum, hours)

super(name, age, sex)

@idnum = idnum

@hours = hours

 end

 # ...

end

# Создать два объекта.

a = Person.new("Dave Bowman", 37, "m")

b = Student.new("Franklin Poole", 36, "m", "000-13-5031", 24)

Посмотрим внимательно, что здесь сделано. Что за

super
, вызываемый из метода
initialize
класса
Student
? Это просто вызов соответствующего метода родительского класса. А раз так, то ему передается три параметра (хотя наш собственный метод
initialize
принимает пять).

Не всегда необходимо использовать слово

super
подобным образом, но часто это удобно. В конце концов, атрибуты любого класса образуют надмножество множества атрибутов его родительского класса, так почему не воспользоваться для их инициализации конструктором родительского класса?

Если говорить об истинном смысле наследования, то оно, безусловно, описывает отношение «является». Студент является человеком, как и следовало ожидать. Сделаем еще три замечания:

• Каждый атрибут (и метод) родительского класса отражается в его потомках. Если в классе

Person
есть атрибут
height
, то класс
Student
унаследует его, а если родитель имеет метод
say_hello
, такой метод будет и у потомка.

• Потомок может иметь дополнительные атрибуты и методы, мы это только что видели. Поэтому создание подкласса часто еще называют расширением суперкласса.

• Потомок может переопределять любые атрибуты и методы своего родителя.

Последнее замечание подводит нас к вопросу о том, как разрешается вызов метода. Откуда я знаю, вызывается ли метод конкретного класса или его суперкласса?

Краткий ответ таков: не знаю и не интересуюсь. Если вызывается некий метод от имени объекта класса

Student
, то будет вызван метод, определенный в этом классе, если он существует. А если нет, вызывается метод суперкласса и так далее вверх по иерархии наследования. Мы говорим «и так далее», потому что у каждого класса (кроме
Object
) есть суперкласс.

А что если мы хотим вызвать метод суперкласса, но не из соответствующего метода подкласса? Можно сначала создать в подклассе синоним:

class Student # Повторное открытие класса.

 # Предполагается, что в классе Person есть метод say_hello...

 alias :say_hi :say_hello

 def say_hello

puts "Привет."

 end

 def formal_greeting

Поделиться:
Популярные книги

Лекарь Империи 7

Карелин Сергей Витальевич
7. Лекарь Империи
Фантастика:
городское фэнтези
аниме
боевая фантастика
попаданцы
5.00
рейтинг книги
Лекарь Империи 7

Глэрд VIII: Базис 2

Владимиров Денис
8. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Глэрд VIII: Базис 2

Наследие Маозари 5

Панежин Евгений
5. Наследие Маозари
Фантастика:
фэнтези
юмористическое фэнтези
5.00
рейтинг книги
Наследие Маозари 5

Звездная Кровь. Экзарх II

Рокотов Алексей
2. Экзарх
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Звездная Кровь. Экзарх II

Академия

Сай Ярослав
2. Медорфенов
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Академия

Я уже граф. Книга VII

Дрейк Сириус
7. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я уже граф. Книга VII

Барон отрицает правила

Ренгач Евгений
13. Закон сильного
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Барон отрицает правила

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Неудержимый. Книга XXX

Боярский Андрей
30. Неудержимый
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXX

Московское золото и нежная попа комсомолки. Часть Пятая

Хренов Алексей
5. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Московское золото и нежная попа комсомолки. Часть Пятая

Законы Рода. Том 11

Андрей Мельник
11. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 11

Зодчий. Книга II

Погуляй Юрий Александрович
2. Зодчий Империи
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Зодчий. Книга II

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Санек 3

Седой Василий
3. Санек
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Санек 3