2013-03-27 12 views
7

Ich bin neu in Scala und habe gehört, dass alles ein Objekt in Scala ist. Was ich nicht verstehe, ist der Vorteil von "Alles ist ein Objekt"? Was kann ich nicht tun, wenn alles kein Objekt ist? Beispiele sind willkommen. DankeAlles ist ein Objekt in Scala

+1

Ruby ist in diesem Aspekt Scala sehr gemein http://stackoverflow.com/questions/10158791/java-and-ruby-everything-is-an-object-in-oo –

+2

Jemand, der Scala kennt sollte schreibe auch eine Antwort über die Nützlichkeit von Funktionsobjekten – Thomas

Antwort

4

Der Vorteil, wenn "alles" ein Objekt ist, besteht darin, dass Sie viel weniger Fälle haben, in denen Abstraktion bricht.

Zum Beispiel sind Methoden keine Objekte in Java. Also, wenn ich zwei Saiten haben, kann ich

String s1 = "one"; 
String s2 = "two"; 
static String caps(String s) { return s.toUpperCase(); } 
caps(s1); // Works 
caps(s2); // Also works 

So haben wir String Identität in unserem Betrieb machen etwas Großbuchstaben abstrahiert. Aber was, wenn wir die Identität der Operation abstrahieren wollen - das heißt, wir tun etwas zu einem String, der einen anderen String zurückgibt, aber wir wollen abstrahieren, was die Details sind? Jetzt stecken wir fest, weil Methoden keine Objekte in Java sind. In Scala können Methoden in Funktionen konvertiert werden, die Objekte sind. Zum Beispiel:

def stringop(s: String, f: String => String) = if (s.length > 0) f(s) else s 
stringop(s1, _.toUpperCase) 
stringop(s2, _.toLowerCase) 

Jetzt haben wir die Idee der Durchführung einer String-Transformation auf nichtleere Strings abstrahiert.

Und wir können Listen der Operationen und so machen und sie weitergeben, wenn das ist, was wir tun müssen.

Es gibt andere weniger wesentliche Fälle (Objekt vs. Klasse, primitiv vs. nicht, Wertklassen usw.), aber der große trennt die Unterscheidung zwischen Methode und Objekt, so dass das Umgehen und Abstrahieren über die Funktionalität einfach ist so einfach wie herumzugehen und über Daten zu abstrahieren.

3

Der Vorteil ist, dass Sie nicht verschiedene Operatoren haben, die unterschiedliche Regeln in Ihrer Sprache befolgen. In Java zum Beispiel zum Ausführen von Operationen mit Objekten verwenden Sie die Methode dot name zum Aufrufen des Codes (statische Objekte verwenden weiterhin die Technik dot name, aber manchmal wird this object oder static object abgeleitet), während integrierte Objekte (keine Objekte) a verwenden andere Methode, die der eingebauten Operatormanipulation.

Number one = Integer.valueOf(1); 
Number two = Integer.valueOf(2); 
Number three = one.plus(two); // if only such methods existed. 

int one = 1; 
int two = 2; 
int three = one + two; 

die wichtigsten Unterschiede ist, dass die dot name Technik polymorphisim unterliegt, Überladen von Operatoren, Methode versteckt, und all die guten Sachen, die Sie mit Java-Objekten zu tun. Die + Technik ist vordefiniert und vollständig nicht flexibel.

Scala umgeht die Inflexibilität der + Methode grundsätzlich es als dot name Operator Handhabung ist und eine starke Eins-zu-Eins-Zuordnung solcher Betreiber Objektmethoden. Daher wird in Scala alles ein Objekt bedeutet, dass alles ein Objekt ist, so dass der Betrieb

5 + 7 

Ergebnisse in zwei Objekten erstellt werden (a 5-Objekt und ein 7-Objekt) die Plus-Methode der 5 Objekt wird mit dem Parameter 7 aufgerufen (wenn mein Scala-Speicher mir richtig dient) und ein "12" -Objekt wird als Wert der Operation zurückgegeben.

Das alles ist ein Objekt hat viele Vorteile in einer funktionalen Programmierumgebung, zum Beispiel, Blöcke von Code sind jetzt auch Objekt, wodurch es möglich ist, Blöcke von Code (ohne Namen) als Parameter noch hin und her zu übergeben immer noch an eine strenge Typprüfung gebunden sein (der Codeblock liefert nur 10 oder eine Unterklasse von String oder was auch immer).

Wenn es darauf hinausläuft, macht es einige Arten von Lösungen sehr einfach zu implementieren, und oft werden die Ineffizienzen durch die fehlende Notwendigkeit, "marshalling code" in "primitive bewegen, manipulieren, aus primitiven verschieben" behandelt.

+0

Dies hat viel mehr damit zu tun, beliebige symbolische Zeichen als Methodennamen zuzulassen, die es mit allem-ist-ein-Objekt macht.Tatsächlich sind Primitive _nicht_ präzise Objekte aus Performance-Gründen , obwohl Scala einen sehr, sehr guten Job macht, um das Boxen zu verdecken, das es tut (und nur boxt, wenn notwendig). –

+0

Ho Wenn es gemacht wird, ist eine Technik, die Sichtweise ist, dass was von dem "alles ist ein Objekt" gefördert wird. Genauso wie kompiliertes Java keine Assemblerbefehle ist, selbst wenn die Implementierungstechnik sie in kompilierte Assemblyanweisungen (JIT) umwandelt. –

+0

Nichtsdestoweniger kann Java keine '+' Methode _on anything_ definieren, während es eine 'plus' Methode für Objekte definieren kann. Es sind die erlaubten Bezeichner in einem Symbol, nicht das Alles-ist-ein-Objekt, das Scala hier unterscheidet. –

3

Ein bestimmter Vorteil, der mir in den Sinn kommt (da Sie nach Beispielen gefragt haben), ist in Java primitive Typen (int, boolean ...), in Scala sind Objekte, denen Sie Funktionalität mit impliziten Konvertierungen hinzufügen können. Zum Beispiel, wenn Sie eine toRoman Methode Ints hinzufügen möchten, können Sie eine implizite Klasse wie schreiben:

implicit class RomanInt(i:Int){ 
    def toRoman = //some algorithm to convert i to a Roman representation 
} 

Dann könnten Sie diese Methode von jedem Int wörtlichen nennen wie:

val romanFive = 5.toRoman // V 

Diese So können Sie Grundtypen "pimpern", um sie an Ihre Bedürfnisse anzupassen.

+0

Dies ist genauso wahr, ob Int-Objekte Objekte sind oder ob Sie implizite Konvertierungen von Primitiven in Klassen erstellen können. –

2

Zusätzlich zu den von anderen gemachten Aussagen, betone ich immer, dass die einheitliche Behandlung aller Werte in Scala zum Teil eine Illusion ist. Zum größten Teil ist es eine sehr willkommene Illusion. Und Scala ist sehr schlau, so oft wie möglich echte JVM-Primitive zu verwenden und automatische Transformationen (normalerweise als Boxen und Unboxing bezeichnet) nur so oft wie nötig durchzuführen.

Wenn jedoch das dynamische Muster der Anwendung von automatischen Boxen und Unboxing sehr hoch ist, kann es unerwünschte Kosten (sowohl Speicher als auch CPU) damit verbunden sein. Dies kann teilweise mit der Verwendung von Spezialisierung, die spezielle Versionen von generischen Klassen erstellt, wenn bestimmte Typ Parameter von (Programmierer angegebenen) primitiven Typen sind abgeschwächt werden. Dies vermeidet das Boxen und Unboxing, kostet aber mehr .class Dateien in Ihrer laufenden Anwendung.

0

Nicht alles ist ein Objekt in Scala, obwohl mehr Objekte in Scala Objekte sind als ihre Analoga in Java.

Der Vorteil von Objekten ist, dass sie Taschen des Zustands sind, die auch ein gewisses Verhalten mit sich bringen. Mit der Hinzufügung von Polymorphismus geben Objekte Möglichkeiten, das implizite Verhalten und den Zustand zu ändern. Genug mit der Poesie, lassen Sie uns in einige Beispiele gehen. Die if Anweisung ist kein Objekt, weder in Scala noch in Java. Wenn dies der Fall wäre, könnten Sie in der Lage sein, eine Unterklasse zu erstellen, eine andere Abhängigkeit an ihrer Stelle einzufügen und sie für die Protokollierung einer Datei zu verwenden, wenn Ihr Code die if-Anweisung verwendet. Wäre das nicht magisch? Es würde in einigen Fällen helfen, Fehler zu debuggen, und in anderen Fällen würde es Ihre Haare weiß werden lassen, bevor Sie einen Fehler gefunden haben, der von jemandem verursacht wurde, der das Verhalten von if überschreibt.

Besuchen Sie eine objektlose, aussagekräftige Welt: Imaging Ihre Lieblings-OOP-Programmiersprache. Denken Sie an die Standardbibliothek, die es zur Verfügung stellt. Es gibt viele Klassen dort, richtig? Sie bieten Möglichkeiten für die Anpassung, oder? Sie nehmen Parameter, die andere Objekte sind, sie erstellen andere Objekte. Sie können alle diese anpassen. Sie haben Polymorphismus. Stellen Sie sich nun vor, dass die Standardbibliothek nur aus Stichwörtern besteht. Sie könnten fast nicht so viel anpassen, da Sie keine Keywords überschreiben können. Sie würden in den Fällen stecken bleiben, in die sich die Sprachdesigner entschloss zu implementieren, und Sie wären hilflos, irgendetwas dort anzupassen. Solche Sprachen existieren, du kennst sie gut, sie sind die Fortsetzung-ähnlichen Sprachen.Sie können dort kaum Funktionen erstellen, aber um das Verhalten der SELECT Anweisung anzupassen, mussten neue Versionen der Sprache erscheinen, die die am meisten gewünschten Funktionen enthielten. Dies wäre eine extreme Welt, in der Sie nur in der Lage wären zu programmieren, indem Sie die Sprachdesigner nach neuen Funktionen fragen (die Sie möglicherweise nicht erhalten, weil jemand anderes wichtigeres eine Funktion benötigt, die inkompatibel ist mit dem, was Sie wollen)

Zusammenfassend ist NICHT alles ein Objekt in scala: Klassen, Ausdrücke, Schlüsselwörter und Pakete sind es sicherlich nicht. Mehr Dinge sind jedoch, wie Funktionen. Was ist IMHO eine schöne Faustregel ist, dass mehr Objekte mehr Flexibilität

P.S. In Python zum Beispiel, noch mehr Dinge sind Objekte (wie die Klassen selbst, das analoge Konzept für packages (das heißt Python-Module und Pakete). Sie würden sehen, wie dort, schwarze Magie ist einfacher zu tun, und das bringt sowohl gute und schlechte Folgen