Jak zaimplementować klasę abstrakcyjną w języku Ruby?
Wiem, że w rubinie nie ma koncepcji klasy abstrakcyjnej. Ale jeśli w ogóle trzeba to wdrożyć, to jak to zrobić? Próbowałem czegoś takiego ...
class A
def self.new
raise 'Doh! You are trying to write Java in Ruby!'
end
endclass B < A
...
...
end
Ale kiedy próbuję utworzyć wystąpienie B, wywołuje wewnętrznie
A.new, co zgłasza wyjątek.
Ponadto nie można tworzyć instancji modułów, ale także nie można ich dziedziczyć. uczynienie nowej metody prywatną również jest niemożliwe. Jakieś wskazówki?
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
17 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Zwłaszcza, ponieważ mogą dodać do niej metody w locie
http://asqyzeron.wordpress.com ... time/
.
Języki kaczy, takie jak Ruby, używają obecności/nieobecności lub zachowania metod w czasie wykonywania, aby określić, czy należy je wywołać, czy nie. Więc twoje pytanie odnosi się do abstrakcji
metoda
ma znaczenie
i na tym historia powinna się zakończyć. Jedynym powodem używania klas abstrakcyjnych w Javie jest naleganie, aby niektóre metody zostały wypełnione, podczas gdy inne mają własne zachowanie w klasie abstrakcyjnej. W języku pisania kaczych nacisk kładziony jest na metody, a nie klasy/typy, więc powinieneś przenieść swoje zmartwienia na ten poziom.
W swoim pytaniu zasadniczo próbujesz odtworzyć słowo kluczowe z języka Java, które jest zapachem kodu do wykonywania języka Java w języku Ruby.
Anonimowy użytkownik
Potwierdzenie od:
Po prostu wywołujesz z listą metod abstrakcyjnych, a gdy są one wywoływane przez instancję klasy abstrakcyjnej, generowany jest wyjątek .
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
potrzebne
Klasa abstrakcyjna.
Jeśli myślisz, że potrzebujesz klasy abstrakcyjnej, myślisz za dużo w języku, który ich dostarcza/wymaga, a nie w języku Ruby jako takim.
Jak sugerowali inni, mixin jest bardziej odpowiedni dla rzeczy, które muszą być interfejsami (tak jak definiuje je Java), a przemyślenie projektu jest bardziej odpowiednie dla rzeczy, które „potrzebują” abstrakcyjnych klas z innych języków, takich jak C ++.
Aktualizacja 2019: Nie potrzebowałem klas abstrakcyjnych w Rubim przez 16 i pół roku użytkowania. Wszystko, co mówią wszystkie osoby komentujące moją odpowiedź, rozwiązuje się, ucząc się języka Ruby i używając odpowiednich narzędzi, takich jak moduły (które dają nawet ogólne implementacje). W poleceniach, którymi zarządzałem, są ludzie, którzy utworzyli klasy z podstawową implementacją, która kończy się niepowodzeniem (na przykład klasa abstrakcyjna), ale jest to głównie marnowanie kodu, ponieważ da dokładnie to samo wynik taki sam jak w produkcji.
Anonimowy użytkownik
Potwierdzenie od:
I oczywiście dodanie jeszcze jednego błędu w celu zainicjowania klasy bazowej byłoby w tym przypadku trywialne.
Anonimowy użytkownik
Potwierdzenie od:
interface
http://rubygems.org/gems/interface abstract
http://rubygems.org/gems/abstract simple abstract
https://rubygems.org/gems/simple_abstract
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Ale w rzeczywistości moduł jest bardziej podobny do tego, czego tu potrzebujesz - na przykład, niezliczone jest klasę abstrakcyjną w innych językach. Technicznie nie można ich podłączyć, ale obejmuje SOMEMODULE Call osiągnie o tym samym celu. Czy jest jakiś powód, dla którego nie działa dla ciebie?
Anonimowy użytkownik
Potwierdzenie od:
Mój wskaźnik jest taki: użyj
mixin
http://www.rubycentral.com/pic ... .html
zamiast dziedziczenia.
Anonimowy użytkownik
Potwierdzenie od:
Nadal nie widzę żadnych praktycznych korzyści ze stosowania klas abstrakcyjnych w języku ruby.
Anonimowy użytkownik
Potwierdzenie od:
Zależy to od zwykłego #method_missing zgłaszania niezaimplementowanych metod,
ale nie pozwala na implementację klas abstrakcyjnych (nawet jeśli mają metodę inicjalizacji)
Jak sugerowały inne plakaty, prawdopodobnie powinieneś użyć mieszanki, a nie klasy abstrakcyjnej.
Anonimowy użytkownik
Potwierdzenie od:
Przykład (z pliku README.md):
Anonimowy użytkownik
Potwierdzenie od:
https://rubygems.org/gems/abstract
https://rubygems.org/gems/abstract
Anonimowy użytkownik
Potwierdzenie od:
Innym podejściem byłoby umieszczenie całej tej funkcjonalności w module, którego, jak wspomniałeś, nigdy nie można uruchomić. Następnie włącz moduł do swoich klas, zamiast dziedziczyć po innej klasie. Jednak to by zepsuło rzeczy takie jak super.
Więc wszystko zależy od tego, jak chcesz to zorganizować. Chociaż moduły wydają się być czystszym rozwiązaniem problemu „jak napisać pewne rzeczy, których raczą używać inne klasy”
Anonimowy użytkownik
Potwierdzenie od:
<pre class="lang-rb prettyprint-override">
Wyniki: