Làm cách nào để lấy tên lớp của cha mẹ trong Ruby


85

Giả sử tôi có một lớp ABnơi Bkế thừa A. Làm cách nào để in tên lớp cha trongB

class A
end

class B < A
end

Một số điều tôi đã thử

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

Cảm ơn :)


4
khi bị kẹt như thế này luôn thử B.methods.sorttrong irb. Có thể điều gì đó sẽ cung cấp cho bạn manh mối về tên phương thức mà bạn tìm kiếm.
Ivaylo Strandjev

@IvayloStrandjev Điều đó sẽ không giúp được gì. Có quá nhiều phương pháp để xem qua. Thật lãng phí thời gian.
sawa

@sawa không đúng. Mất tôi 30 giây. Đủ để những người dùng khác nhanh hơn tôi, nhưng khá nhanh.
Ivaylo Strandjev

8
@checkit: đơn giản hơn nhiều! 8.methods.grep(/class/)Bạn thậm chí không cần phải loại với loại lọc :)
Sergio Tulentsev

@SergioTishedsev hay quá !! nó sẽ thực sự hữu ích :)
Rahul Tapali

Câu trả lời:



62

Nếu bạn muốn toàn bộ ngăn xếp tổ tiên, hãy thử:

object.class.ancestors

Ví dụ:

> a = Array.new
=> []
> a.class.ancestors
=> [Array, Enumerable, Object, Kernel, BasicObject]

1
Hãy nhớ rằng cũng bao gồm các mô-đun được bao gồm trong một lớp. Bạn có thể thấy Arraytheo sau Enumerable, không phải là cha, mà là một mô-đun có trong Array . Nếu bạn muốn chỉ các lớp học, bạn có thể làm điều gì đó giống như Array.ancestors.select { |ancestor| ancestor.is_a? Class } #=> [Array, Object, BasicObject].
3limin4t0r

18

Cho một đối tượng (Lớp khởi tạo), bạn có thể lấy được Lớp cha

>> x = B.new
>> x.class.superclass.name
=>"A"

16

Trong trường hợp google đưa bất kỳ ai đang làm việc trong Rails đến đây, thay vào đó, điều bạn có thể muốn là base_class, cũng như superclasssẽ duyệt qua cấu trúc kế thừa 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

Hơn nữa...

class C < B
end

> C.base_class
=> A

Nói cách khác, base_classcung cấp cho bạn phần trên cùng của cây kế thừa nhưng giới hạn trong ngữ cảnh của ứng dụng của bạn. Mặc dù vậy, cảnh báo công bằng, theo như Rails có liên quan "ứng dụng của bạn" bao gồm bất kỳ viên ngọc nào bạn đang sử dụng, vì vậy nếu bạn có một mô hình phân lớp thứ gì đó được xác định trong một viên đá quý, base_classsẽ trả về lớp của viên ngọc đó, không phải của bạn.


8

Thuật ngữ bạn đang tìm kiếm là superclass. Và thực sự bạn có thể làm B.superclassđể có được A. (Bạn cũng có thể làm B.ancestorsđể lấy danh sách tất cả các lớp và mô-đun mà nó kế thừa - đại loại như vậy [B, A, Object, Kernel, BasicObject].)


2

Kế thừa là một quan hệ giữa hai lớp. Kế thừa tạo ra một mối quan hệ cha mẹ giữa các lớp. Nó là một cơ chế để sử dụng lại mã và cho phép các phần mở rộng độc lập của phần mềm gốc thông qua các lớp và giao diện công khai. .

Trong Ruby, một lớp chỉ có thể kế thừa từ một lớp khác. (nghĩa là một lớp có thể kế thừa từ một lớp kế thừa từ một lớp khác kế thừa từ một lớp khác, nhưng một lớp không thể kế thừa từ nhiều lớp cùng một lúc). Lớp BasicObject là lớp cha của tất cả các lớp trong Ruby. Do đó, các phương thức của nó có sẵn cho tất cả các đối tượng trừ khi bị ghi đè rõ ràng.

Ruby vượt qua sự kế thừa một lớp cùng một lúc bằng cách sử dụng mixin.

Tôi sẽ cố gắng giải thích bằng một ví dụ.

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

Bạn có thể theo dõi bằng cách sử dụng class_name.superclass.name và thực hiện quá trình này trừ khi bạn tìm thấy BasicOject trong hệ thống phân cấp này. BasicObject là siêu lớp o mọi lớp. hãy xem giả sử chúng ta muốn xem cây phân cấp lớp C.

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

Bạn có thể thấy toàn bộ hệ thống phân cấp của lớp C. Điểm cần lưu ý khi sử dụng cách tiếp cận này, bạn sẽ không tìm thấy các mô-đun được bao gồm hoặc thêm vào trước trong các lớp cha.

Có một cách tiếp cận khác để tìm hệ thống phân cấp hoàn chỉnh bao gồm các mô-đun. Theo tổ tiên của Ruby doc . Trả về danh sách các mô-đun được bao gồm / thêm vào trước trong bản mod (bao gồm cả bản thân mod).

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

Ở đây, Mux và Kernel là Mô-đun.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.