ฉันจะรับชื่อคลาสของผู้ปกครองใน 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 เสมอ บางทีบางอย่างอาจให้เบาะแสเกี่ยวกับชื่อวิธีการที่คุณมองหา
Ivaylo Strandjev

@IvayloStrandjev นั่นจะไม่ช่วย มีวิธีการมากเกินไปที่จะมองผ่าน มันเสียเวลา
sawa

1
@sawa ไม่จริง. เอาฉันไป 30 วิ เพียงพอสำหรับผู้ใช้รายอื่นที่เร็วกว่าฉัน แต่ค่อนข้างเร็ว
Ivaylo Strandjev

9
@checkit: ง่ายกว่ามาก! 8.methods.grep(/class/)คุณไม่จำเป็นต้องเรียงลำดับด้วยการกรองแบบนี้ :)
Sergio Tulentsev

@SergioTulentsev ดีมาก !! มันจะเป็นประโยชน์จริงๆ :)
Rahul Tapali

คำตอบ:



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

เมื่อได้รับวัตถุ (Instantiated Class) คุณสามารถได้รับคลาสแม่

>> 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 เอาชนะการสืบทอดคลาสเดี่ยวได้ในคราวเดียวโดยใช้ mixin

ฉันจะพยายามอธิบายด้วยตัวอย่าง

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 เป็น super class o ทุกคลาส ลองดูสมมติว่าเราต้องการดูแผนผังลำดับชั้นคลาส C

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

คุณสามารถดูลำดับชั้นทั้งหมดของคลาส C ชี้ไปที่หมายเหตุโดยใช้วิธีนี้คุณจะไม่พบโมดูลที่รวมหรือนำหน้าในคลาสพาเรนต์

มีอีกวิธีหนึ่งในการค้นหาลำดับชั้นที่สมบูรณ์รวมถึงโมดูล อ้างอิงจาก Ruby docบรรพบุรุษของ . ส่งคืนรายการโมดูลที่รวม / นำหน้าใน mod (รวมถึงตัว mod เอง)

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-oriented_programming)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.