Hi,
;D tja immer noch nicht der feierlich angekündigte code, sondern ein weiterer theoretischer side-Thread.
Liegt aber u.a. auch daran, dass tragischerweise mein Arbeitsjahr noch nicht abgeschlossen ist.
Zumindest habe ich mir jetzt die OO Fähigkeiten von LS näher zu Gemüte geführt. Schliesslich muss ich den HF DP code portieren.
Sieht so aus, dass ich für die Ausgabe Notes-Logging (LS-NotesLog-Klasse, nicht log.nsf) verwende. Der HF DP code ist reiner Konsolen code und print statements sind keine Freude.
Hier der Vergleich zu Java (bzw. was LS-OO fehlt oder was es da mehr gibt). Wie gesagt gehe ich dann in den Beispielen später darauf ein, was die einzelnen Fremdwörter wie Polimorphismus, Abstrakte Klassen und ähnliches bedeuten.
Es ist nur jetzt eben frisch in der Erinnerung.
Für vorhandenes Notes-Talente, die jetzt ein bischen mit Java daddeln mag das auch sonstwie interessant sein.
Für mich in der Reihenfolge der Bedeutung in Vergleich zu Java. Wird möglicherweise fortgeführt:
I. Was fehlt LotusScript:
- Keine Abstrakten Klassen oder Interfaces.
Beide dienen in Java zur Unterstützung von Polymorphismus. Beide können nicht instantiiert werden.
In LotusScript kann jede Klasse instantiiert werden. Das ist nicht gut. Interfaces und Abstrakte Klassen dienen als eine Art "polimorphe Klammer" (Begriff ist von mir), was ziemlich gut ist (wird noch zu sehen sein).
- Keine Interfaces
In Java gibt es zwar keine Mehrfachvererbung. Zumindest oder völlig ausreichenderweise kann man aber durch Java-Interfaces ein Objekt in mehrerere, mehrere, mehrere sagen wir Vererbungsstränge sagen wir polymorphistisch einbinden.
- fehlender IDE support
<updated date="30.12.04">
- kein Methoden - overloading (s. u.) >:(
- kein Variablen-shadowing (wird noch erklärt)
- kein Äquivalent zu final (CONST ist verboten!)
</updated>
- Keine Packages
In Java können Klassen in sogenannte Packages geordnet werden. Dies hilft der Übersichtlichkeit, wenn man viele Klassen hat und man hat auch zusätzliche access modifier
- Keine Reflection Möglichkeiten (Javabuch3 Kap. 43)
Man kann so Klassen in den code einbinden, die zur Laufzeit bekannt sind und zur Kompilierzeit nocht nicht bekannt sind.
Viele Java-Frameworks wie Spring, Hibernate, Struts, etc. benutzen die Reflection API stark. Der Wald und Wiesen Programmierer auch manchmal und es gibt zu diesem Thema nun sogar ein eigenes Buch bei Manning. Sun hat viel Mühe darin gesteckt, die Performance Kosten von Reflectioning (?) zu verringern.
- keine static Methoden oder Variablen
static Member (Überbegriff für Methoden und Variablen) gehören nicht zum Objekt sondern zur Klasse. Machen manchmal Sinn. Z.B. beim Singleton Pattern.
- Nur 1 Konstruktor pro Klasse möglich (kein Konstruktor overloading)
In Java kann es mehrere geben. Es wird immer der "passende" aufgerufen. Passend hängt von den dem new übergebenen Parametern ab:
Person person = new Person("Meier", 18);
// ruft auf:
Person(String name, int age) {
// stuff
}
Person person = new Person("Meier");
// ruft auf:
Person (String name) {
// stuff
}
In LotusScript ist zwar die Übergabe von Parametern möglich. Es kann aber nur einen Konstruktor pro Klasse geben.
- 2 statt 4 access modifier
In Java gibt es neben public und private noch <leer>(=package-visibility) und protected. Hilft bei der Kappselung in Anwendung mit vielen Klassen.
- Keine Serialisierung
In Java können Objekte in einen Stream umgewandelt werden, der dann in einem File zwischengelagert wird oder übers Netzwerk geschickt werden kann. Sinnvoll für Anwendungen mit verteilten Objekten.
- Keine gemeinsame Parent-Klasse.
In Java erbt jede Klasse von java.lang.Object. Das unterstützt Polymorphismus. Man kann das natürlich selbst programmieren.
- Syntax für Aufruf des Parent Constructors in LS sehr merkwürdig
In Vererbungshierarchien wird der Constructor der Klasse von der geerbt wurde mitaufgerufen. Falls die Signatur des Constructors in Lotus Script Parameter erfordert, ist die Syntax echt gewöhnungsbedürftig. Später mehr.
- keine inneren Klassen
Kann in manchen Fällen relativ praktisch zu sein.
II. Was hat LotusScript zusätzlich:
- Explizites Löschen von Objekten
Offenbar gibt es einen Garbage Collector und zusätzlich kann man die Objekte explizit aus dem Speicher entfernen (destroy Methode). In Java ist man auf Gedeih und Verderb vom Garbage Collector angewiesen. Offenbar wird das aber in Java 1.5 ein bischen oder viel besser (weiss nicht).
- Neben Variablen und Methoden gibt es noch sogenannte Properties
Wie getter und setter in Java. In Java gibt es dafür Namenskonventionen (setXxx, getXyyy). Eigentlich ausreichend. Schlecht finde ich das mit den Properties aber nicht.
Bei der Portierung des HF DP gof codes wird dann zu sehen sein, inwieweit sich die Nachteile (und Vorteile) von LS gegenüber Java bemerkbar machen.
Danke für die Informationen !
Nur aus Interesse (leider hänge ich in Java noch ganz am Anfang):
- Nur 1 Konstruktor pro Klasse möglich (kein Konstruktor overloading)
In Java kann es mehrere geben. Es wird immer der "passende" aufgerufen. Passend hängt von den dem new übergebenen Parametern ab:
Person person = new Person("Meier", 18);
// ruft auf:
Person(String name, int age) {
// stuff
}
Person person = new Person("Meier");
// ruft auf:
Person (String name) {
// stuff
}
In LotusScript ist zwar die Übergabe von Parametern möglich. Es kann aber nur einen Konstruktor pro Klasse geben.
In LotusScript übersetzt heißt das für mich, ich kann in Java z.B. so ein neues Objekt erstellen:
Dim guy as New Person("Hans")
oder
Dim guy as New Person("Hans", 300)
1:1 zusammengezählt heißt dies für mich, man kann in Java Parameter weglassen. In LotusScript: no way.
Ich habe die Problematik oft in LS, wenn ich globale Functions erstelle.
Ich will da manche Dinge offen halten. z.B.
Function DoSomeStuff(strBlaBla as Strung, boolean1 as Boolean, int2 as Integer)
Wenn ich nun diese Function aufrufe, muss ich immer alle 3 Parameter angeben, auch wenn z.B. int2 nur interessiert, wenn boolean1 = True ist.
Wenn dies in Java möglich ist, wäre es ein weiterer Punkt für Deine Liste "Was fehlt in LotusScript".
Dann wäre aber interessant, wie dies in Java gehändelt wird. Ein Select Case auf "wurde der 2. Parameter übergeben oder weggelassen" ?
Mehrere Konstruktoren pro Klasse in LS: müsste man wohl über Parameter händeln und entsprechend aufzweigen (Select Case / If-Else etc.).
Axel: ein Seitenhieb sei erlaubt: die Java-Implementation ist ... sorry ... hinverbrannt, das macht das ganze Gemüse total unübersichtlich. Statt einem Overload des Constructors New wäre es viel schlauer gewesen, eine Implementation à la Delphi zu wählen, wo mehrere Konstruktoren mit unterschiedlichem Namen definiert werden können und beim Instantiieren eines Objektes (Create) muss der zu verwendende Konstruktor namentlich aufgeführt werden. Das erhöht ganz gewaltig die Lesbarkeit des Sourcecodes. Da kann Java leider die unglückliche Elternschaft nicht verbergen.
Das ist richtig. Man kann aber mit statischen Factory-Methoden arbeiten.
Es gibt Diskussionen im Internet der Art "new considered evil".
Ein noch blöderer Aspekt dieses Konstruktor_heisst_wie_klasse_Phänomen ist ... aber das führt jetzt zuweit.
Etwas, dass btw. auch so ähnlich in EJB2.0 geändert wurde. Egal.
So geht das mit static Factory-Methode:
class Person {
// wg. private kann Objekt nur über Factory Methode erzeugt werden
private Person (String name, int age) {
this.name = name;
this.age = age;
}
public static Person createPersonWithoutParameters() {
return new Person("No_Name", -1);
}
public static Person createPersonWithName(String name) {
return new Person(name, -1);
}
public static Person createPersonWithNameAndAge(String name, int age) {
return new Person (name, age);
}
}
Boar. Methoden-Overloading geht ja auch nicht.
@Mathias und @all: Das könnte auch für Scriptlibraries gelten. Aber anstatt mit if-thens, select-cases herumzugurken, ist es möglicherweise besser die Methoden/Funktionen einfach durchzunummerieren:
Agent
// Options
Option Public
Option Declare
// Declarations:
Public Class Person
Private DEFAULT_NAME As String
Private DEFAULT_AGE As Integer
Private name As String
Private age As Integer
' UNTERSCHIED zu Java: Nur 1 Constructor erlaubt
Public Sub New ()
Print "Constructor aufgerufen"
DEFAULT_NAME = "No Name"
DEFAULT_AGE = -1
End Sub
' Method-overloading funktioniert auch nicht :-(
Public Function setData () As String
Print "Methode setData() aufgerufen"
Me.name = DEFAULT_NAME
Me.age = DEFAULT_AGE
'setData = "setData verändert Properties dieses Objekts. name=" & Me.name & " age=" & Me.age
setData = "setData hat delegiert:" & setData1(DEFAULT_NAME, DEFAULT_AGE)
End Function
'Method overloading funktioniert nicht :-(. setData(sName As STring, sAge as Integer) ist verboten. Deshalb setData1
Public Function setData1(sName As String, sAge As Integer) As String
Print "Methode setData1(sName As String, sAge As Integer) aufgerufen"
Me.name = sName
Me.age = sAge
setData1 = "setData1 verändert Properties dieses Objekts. name=" & Me.name & " age=" & Me.age
End Function
End Class
// Initialize
Sub Initialize
Dim aPerson As Person
Set aPerson = New Person()
Print aPerson.setData()
Print aPerson.setData1("Meier", 17)
End Sub