2013-02-17 17 views
6

Czytałem dobrze uziemienia Rubyist i wspomina, jak klasa dziedziczy metody instancji swojej super klasy, aby obiekty klasy mogły wywoływać te metody instancji. Oto przykład:Zrozumienie dziedziczenia Ruby

class C 
    def run_instance_method 
    puts "This is an instance method." 
    end 
    def C.run_class_method 
    puts "This is a class method." 
    end 
end 

class D < C 
end 

Na podstawie tego co czytałem, to zawsze opisywano tej klasy D odziedziczy tylko metody instancja klasy C (w którym to przypadku, C :: run_class_method nie byłyby dziedziczone przez RE). Po uruchomieniu powyższy kod, zauważam jednak, że:

D.run_class_method # => "This is a class method." 

Oto moje przypuszczenie, dlaczego tak się dzieje i proszę dać mi znać, jeśli jest to właściwe zrozumienie. Jeśli istnieje instancja klasy D i spróbujesz uruchomić metodę d.run_instance_method, obiekt przeszuka swoją ścieżkę wyszukiwania metody i sprawdzi, czy ta metoda jest zdefiniowana w klasie singleton, w jej własnej klasie lub w jej nadklasach. Ponieważ metoda run_instance_method jest zdefiniowana w klasie C, nie wystąpią żadne problemy i zostanie wywołana metoda run_instance_method. Dla obiektu klasy D (który jest podklasą C i obiektu), jeśli wywołana zostanie metoda D.run_class_method, ponownie sprawdzi ona ścieżkę wyszukiwania metody dla obiektu klasy D. Ponownie, Ruby znajdzie go w klasie obiektu C.

Czy to rozumowanie jest dokładne?

Odpowiedz

5

Metody klas mogą być dziedziczone i zastępowane tak, jak mogą być stosowane metody instancji. Jeśli twoja klasa nadrzędna definiuje metodę klasy, podklasa dziedziczy tę metodę. Oznacza to, że jeśli twoja podklasa nie definiuje własnej metody klasy, to dziedziczy ona z jej nadklasy.

Jako zalecenie: podczas wywoływania metody klasy z jawnym odbiorcą powinieneś unikać polegania na dziedziczeniu. Zawsze wywołaj metodę klasy przez klasę, która ją definiuje. W przeciwnym razie bardzo trudno byłoby komuś, kto polega na kodzie, znaleźć klasę nadrzędną, która definiuje metodę klasy.

Odwołując się do pierwotnego założenia: wywołanie metody klasy z podklasy jest możliwe, ponieważ metody klas są metodami instancji standardu eigenclass.

class C 
    # instance methods goes here 
    class << self # open the eigenclass 
    # class methods go here as instance methods of the eigenclass 
    end 
end 

Ogólnie, to jaśniej określić metodami klasy jako poszczególnych metod pojedynczych bez wyraźnego otwarcia eigenclass.

Dla jasnego wyjaśnienia czytaj The Ruby Programming Language David Flanagan i Yukihiro Matsumoto

+0

dzięki za wyjaśnienie. Czy możesz mnie poprawić, jeśli nie mam racji z tym wyjaśnieniem: w zasadzie wszystkie metody klasowe znajdują się w ich eigenclass jako metody instancji. Jeśli klasa D dziedziczy z jej klasy superklasy C, to klasa D's eigenclass dziedziczy również dziedziczenie z klasy C klasy. Z tego powodu obiekt klasy D może wywołać metodę .run_class_method. Czy to jest dokładne? – wmock

+1

Dokładnie! Kiedy Ruby ocenia wyrażenie wywołania metody, najpierw musi ustalić, która metoda musi zostać wywołana. Jest to tak zwane "wyszukiwanie metod": najpierw wyszukaj definicję metody w klasie własnej, jeśli nie zostanie znaleziona żadna metoda, wyszukaj w klasie rodzic itd. Aż do katalogu głównego łańcucha. –

2

Niezbyt dokładnie. Jest tu ukryta inna koncepcja o nazwie metaclass lub eigenclass. Metoda klasy jest dziedziczona z eigenclass. Aby uzyskać więcej informacji na ten temat, patrz: Ruby Hacking Guide. (Po prostu wyszukaj "metody klasy" na stronie, jeśli nie chcesz ich wszystkich czytać.)