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

  # Поприветствовать так, как принято в суперклассе.

  say_hi

 end

end

У наследования есть разные тонкости, которых мы здесь касаться не будем. Общий принцип мы изложили, но не пропустите следующий раздел.

11.1.6. Опрос класса объекта

Часто возникает вопрос: «Что это за объект? Как он соотносится с данным классом?» Есть много способов получить тот или иной ответ.

Во-первых, метод экземпляра class всегда возвращает класс объекта. Применявшийся ранее синоним type объявлен устаревшим.

s = 'Hello'

n = 237

sc = s.class # String

nc = n.class # Fixnum

He думайте, будто методы class или type возвращают строку, представляющую имя класса. На самом деле возвращается экземпляр класса Class! При желании мы могли бы вызвать метод класса, определенный в этом типе, как если бы это был метод экземпляра класса Class (каковым он в действительности и является).

s2 = 'some string'

var = s2.class            # String

my_str = var.new('Hi...') # Новая строка.

Можно сравнить такую переменную с константным именем класса и выяснить, равны ли они; можно даже использовать переменную в роли суперкласса и определить на ее основе подкласс! Запутались? Просто помните, что в Ruby Class — это объект, a Object — это класс.

Иногда нужно сравнить объект с классом, чтобы понять, принадлежит ли данный объект указанному классу. Для этого служит метод instance_of?, например:

puts (5.instance_of? Fixnum)       # true

puts ('XYZZY'.instance_of? Fixnum) # false

puts ('PLUGH'.instance_of? String) # true

А если нужно принять во внимание еще и отношение наследования? К вашим услугам метод kind_of? (похожий на instance_of?). У него есть синоним is_a? , что вполне естественно, ибо мы описываем классическое отношение «является».

n = 9876543210

flag1 = n.instance_of? Bignum # true

flag2 = n.kind_of? Bignum     # true

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату