2009-07-07 7 views
6

수퍼 클래스와 Base::Number, Base::Color과 같은 파생 클래스가 있습니다. Number의 경우 Fixnum에서 상속받은 것처럼 그 자식 클래스를 사용할 수 있기를 바랍니다.루비의 다중 상속 유형 클래스 상속

is_a? Base에 적절하게 응답하면서이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

그래서, 내가 혼합 된 수있는 기본 생각하고

Number.new(5) + Number.new(6) # => 11 
Number.new.is_a? Base   # => true 

를 수행하고의 is_a? kind_of을 덮어 쓸 수 있어야한다? instance_of? 방법,하지만 잘하면 거기에 깨끗한 방법.

답변

13

이 루비를 사용하여 실제로 매우 간단합니다 :

module Slugish 
    attr_accessor :slug 
    def loud_slug 
    "#{slug}!" 
    end 
end 

class Stringy < String 
    include Slugish 
end 

class Hashy < Hash 
    include Slugish 
end 

hello = Stringy.new("Hello") 
world = Stringy.new("World") 

hello.slug = "So slow" 
world.slug = "Worldly" 

hello.loud_slug  #=> "So slow!" 
world.loud_slug  #=> "Worldly!" 

hello.is_a?(Slugish) #=> true 
world.is_a?(Slugish) #=> true 

"#{hello} #{world}" #=> "Hello World" 

stuff = Hashy.new 
stuff[:hello] = :world 
stuff.slug = "My stuff" 
stuff.loud_stug  #=> "My stuff!" 
stuff.is_a?(Slugish) #=> true 
+1

와우, 나는 몰랐습니다. mixin에 대해 'true'라고 대답했고, 포함 된 모듈에 다른 모듈이 포함 된 경우에도 작동합니다. 아마도 이것을 대신 포워딩 할 수있을 것이다. 감사! – cloudhead

+1

오타가 있어야합니다 :'world = Stringy.new ("World")' – rampion

1

동일한 기본 클래스에서 파생 된 "번호"와 "색상"과 같이 완전히 관련이없는 클래스가있는 경우 상속을 잘못 사용한다고 생각합니다. 같은 루틴에 대한 액세스가 필요한 경우 컴포지션을 대신 사용합니다 (왜 그런지는 알 수 없습니다).

+0

점은 그들은이 기능을 공유하고 난 그들 모두가 다른 루비 데이터 유형 대, 자료로 인식 될 필요가 무관하지 않은 것입니다. – cloudhead

+1

숫자와 색상은 실제로 관련이 없습니다. 상속은 "is-a"관계가 아니라 "has-a"관계입니다. 작곡을 사용하십시오. –

+0

상속은 다양한 도우미 기능을 묶는 것이 아닙니다. –

3

왜 is_a를 사용하겠습니까?/kind_of? respond_to 때? 물건을 확인하는 훨씬 깨끗한 방법입니까? 객체가 임의로 선택된 수퍼 클래스의 하위 클래스가 아닌 인터페이스/계약을 구현하도록합니다. 하지만 어쩌면 여기서 어떤 종류의 요구 사항을 놓치고있을 수도 있습니다.

편집 : 귀하의 추론을 이해하지만 가끔 OO/동적 설계가 불량합니다. 이 같은

if a.is_a?(something) 
    #do something 
elif a.is_a?(something_else) 
    #do something else 
... 

또는 뭔가 :

if !a.is_a?(something) 
    #raise condition/return null/etc. 
endif 
...

나는 생각 중 하나는 잎 클래스에서 허용 생각이 될 수도 있지만 프레임 워크에서 상속으로 해결해야 이런 일을하고있는 코드가 실패하면 메시지 전달 기반 언어에서의 예외가 완벽한 디자인 결정이라는 것을은 알지 못합니다.

추가 된 문제로 is_a? 대신 응답?은 유닛 테스트 중에 모형 객체를 사용할 수있는 능력을 제한합니다. 어느 정도 복잡한 코드라도 꽤 큰 문제가 될 수 있습니다.

+2

respond_to? 항상 깨끗한 것은 아니지만 이후에 다른 모든 통화에 응답하는 한 가지 방법에 응답하기 때문에가 아닙니다. 따라서 유형이 올바른지 한 번 확인하는 것이이 경우에 더 좋습니다. – cloudhead

1

다중 상속에 해당하는 루비는 mixins입니다. 나에게 당신이 원하는 것은 Base가 여러 클래스에 섞여있는 모듈이라는 것입니다.

+0

예, 포함 된 모듈이 is_a와 관련하여 수퍼 클래스처럼 작동하는 것을 알지 못했습니까? - 그게 꽤 문제가되지 않습니다. – cloudhead