Как мне получить имя родительского класса в Ruby

86

Предположим, у меня есть классы Aи Bгде Bнаследуется A. Как напечатать имя родительского класса вB

class A
end

class B < A
end

Кое-что я пробовал

>> B.new.class #=> B   #which is correct
>> B.new.parent  #=> Undefined method `parent`
>> B.parent   #=> Object
>> B.parent.class #=> Class

Благодаря :)

Рахул Тапали
источник
5
когда застряли вот так, всегда пытайтесь использовать B.methods.sortirb. Может быть, что-то подскажет, какое имя метода вы ищете.
Ивайло Странджев
@IvayloStrandjev Это не поможет. Слишком много способов просмотреть. Это пустая трата времени.
sawa
1
@sawa неправда. Заняло у меня 30 секунд. Достаточно, чтобы другие пользователи были быстрее меня, но довольно быстро.
Ивайло Странджев
9
@checkit: намного проще! 8.methods.grep(/class/)Вам даже не нужно сортировать с такой фильтрацией :)
Серджио Туленцев
@SergioTulentsev милый !! это будет действительно полезно :)
Рахул Тапали

Ответы:

136
class A
end

class B < A
end

B.superclass # => A
B.superclass.name # => "A"
Серджио Тюленцев
источник
62

Если вам нужен полный стек предков, попробуйте:

object.class.ancestors

Например:

> a = Array.new
=> []
> a.class.ancestors
=> [Array, Enumerable, Object, Kernel, BasicObject]
Джеймс С.
источник
1
Имейте в виду, что это также включает модули, включенные в класс. Вы можете увидеть, что Arrayза ним следует Enumerable, что это не родительский элемент, а модуль, включенный в массив . Если вам нужны только классы, вы можете сделать что-то вроде Array.ancestors.select { |ancestor| ancestor.is_a? Class } #=> [Array, Object, BasicObject].
3limin4t0r
18

Учитывая объект (экземпляр класса), вы можете получить родительский класс

>> x = B.new
>> x.class.superclass.name
=>"A"
Райт
источник
16

В случае , если Google приносит кто - нибудь здесь , кто работает в Rails, что вы можете вместо этого base_class, так как superclassпересечет структуру наследования ActiveRecord , а также.

class A < ActiveRecord::Base
end

class B < A
end

> A.superclass
=> ActiveRecord::Base
> B.superclass
=> A

> A.base_class
=> A
> B.base_class
=> A

Еще больше...

class C < B
end

> C.base_class
=> A

Другими словами, base_classдает вам верхнюю часть дерева наследования, но ограничивается контекстом вашего приложения. Однако справедливое предупреждение, что касается Rails, «ваше приложение» включает в себя любые используемые вами драгоценные камни, поэтому, если у вас есть модель, которая подклассифицирует что-то определенное в геме, base_classвернет класс драгоценного камня, а не ваш.

Джоэл Фауз
источник
8

Термин, который вы ищете superclass. И действительно можно вообще B.superclassполучить A. (Вы также B.ancestorsможете получить список всех классов и модулей, от которых он наследуется - что-то вроде [B, A, Object, Kernel, BasicObject].)

Чак
источник
2

Наследование - это отношение между двумя классами. Наследование создает отношения родитель-потомок между классами. Это механизм для повторного использования кода и позволяющий независимые расширения исходного программного обеспечения через общедоступные классы и интерфейсы. Преимущество наследования состоит в том, что классы, расположенные ниже по иерархии, получают функции тех, которые находятся выше, но также могут добавлять определенные собственные функции. .

В Ruby класс может наследовать только от одного другого класса. (т.е. класс может наследовать от класса, который наследуется от другого класса, который наследуется от другого класса, но один класс не может наследовать сразу от многих классов). Класс BasicObject является родительским классом для всех классов в Ruby. Следовательно, его методы доступны для всех объектов, если они явно не переопределены.

Ruby сразу преодолевает наследование одного класса, используя миксин.

Попробую пояснить на примере.

module Mux
 def sam
  p "I am an module"
 end
end
class A
  include Mux
end
class B < A
end
class C < B
end
class D < A
end

Вы можете выполнить трассировку с помощью class_name.superclass.name и выполнить этот процесс, если вы не нашли BasicOject в этой иерархии. BasicObject - это суперкласс для всех классов. Давайте посмотрим, что предположим, что мы хотим увидеть дерево иерархии класса C.

 C.superclass
   => B
 B.superclass
  => A
 A.superclass
  => Object
 Object.superclass
  => BasicObject

Вы можете увидеть всю иерархию класса C. Обратите внимание, что при таком подходе вы не найдете модулей, которые включены или добавлены в родительские классы.

Есть еще один подход к поиску полной иерархии, включая модули. По словам предков Ruby doc . Возвращает список модулей, включенных / добавленных в мод (включая сам мод).

C.ancestors
 => [C, B, A, Mux, Object, Kernel, BasicObject]

Здесь Mux и Kernel - это модули.

http://rubylearning.com/satishtalim/ruby_inheritance.html https://en.wikipedia.org/wiki/Inheritance_(object-oriated_programming)

Мукеш Кумар Гупта
источник