2010-04-22 13 views
16

Zuallererst lese ich Erickson nützliche Antwort auf "Why can’t I define a static method in a Java interface?". Bei dieser Frage geht es nicht um das "Warum", sondern um das "Wie dann?". Gibt es eine Möglichkeit, sicherzustellen, dass Klassen, die ein Interface implementieren, statische Methoden implementieren?


Edit: mein ursprüngliches Beispiel wurde schlecht gestellt, aber ich lasse es unten.

Während ich jetzt bin überzeugt, dass in den meisten Fällen, was ich will viel des Guten zu tun ist, gibt es ein Szenario, wo sie gebraucht werden:

Ich werde wieder das ParametricFunction Beispiel. Nehmen wir nun eine komplizierte Funktion, wie die Bessel functions, wo eine Nachschlagetabelle geeignet ist. Dies muss initialisiert werden, so dass die beiden Optionen die Parameter direkt an den Konstruktor übergeben oder init(double[] parameters) bereitstellen. Letzteres hat den Nachteil, dass getValue(double x) die Initialisierung jeden Anruf überprüfen muss (oder die ArrayIndexOutOfBoundsException muss als Initialisierung Prüfung berücksichtigt werden), so dass für zeitkritische Anwendungen, die ich den Konstruktor-Methode bevorzugen würde:

interface ParametricFunction { 
    public double getValue(double x); 
} 

class BesselFunction implements ParametricFunction { 
    public BesselFunction(double[] parameters) { ... } 
    public double getValue(double x) { ... } 
} 

Welche berührt ein weiteres Problem, die Unmöglichkeit von Konstruktoren in Schnittstellen. Was wäre da eine gute Lösung? Ich könnte natürlich den init(double[] parameters) Ansatz verwenden, aber ich erwähnte meinen Grund warum nicht.
(Edit: OK, hier eine abstrakte Klasse die Schnittstelle implementiert tun würde)

Nun lasst uns den ParametricFunction annehmen können nur bestimmte Parameter, beispielsweise positive ganze Zahlen. Wie überprüft man die Gültigkeit der Parameter, die an den Konstruktor übergeben werden? Eine IllegalArgument -Ausgabe zu werfen wäre eine Möglichkeit, aber eine scheint viel bequemer. Aber die Überprüfung der Parameter muss vor der Konstruktion erfolgen, also muss es eine statische Methode sein. Und hier würde ich wirklich gerne einen Weg finden, um sicherzustellen, dass jede Klasse, die die ParametricFunction Schnittstelle implementiert, diese statische Methode definiert.

Ich weiß, dass dieses Beispiel eher künstlich ist, und der Grund dafür, nicht einfach eine init Methode über die Schnittstelle zu verwenden, ist umstritten, ich würde immer noch gerne die Antwort wissen. Betrachten Sie es als akademische Frage, wenn Sie es nicht mögen.

(original Beispiel)

Also im Grunde möchte ich eine Schnittstelle sowohl übliche Verfahren und z.B. eine getSimilarObject Methode. Für (eine aus) Beispiel

public interface ParametricFunction { 
    /** @return f(x) using the parameters */ 
    static abstract public double getValue(double x, double[] parameters); 

    /** @return The function's name */ 
    static abstract public String getName(); 

    /** @return Whether the parameters are valid [added on edit] */ 
    static abstract public boolean checkParameters(double[] parameters); 
} 

und dann

public class Parabola implements ParametricFunction { 
    /** @return f(x) = parameters[0] * x² + parameters[1] * x + parameters[2] */ 
    static public double getValue(double x, double[] parameters) { 
    return (parameters[2] + x*(parameters[1] + x*parameters[0])); 
    } 
    static public String getName() { return "Parabola"; } 
    // edit: 
    static public boolean checkParameters(double[] parameters) { 
    return (parameters.length==3); 
    } 
} 

Da dies nicht im aktuellen Java-Standard erlaubt, was ist die nächste Sache, das?

Die Idee dahinter ist, mehrere ParametricFunction s in ein Paket zu setzen und Reflection zu verwenden, um alle aufzulisten, so dass der Benutzer z. welches zu plotten. Natürlich könnte man eine Loader-Klasse bereitstellen, die ein Array der verfügbaren ParametricFunctions enthält, aber jedes Mal, wenn ein neues implementiert wird, muss man sich auch daran erinnern, es dort hinzuzufügen.

edit: Ein Beispiel zu nennen ist

public double evaluate(String fnName, double x, double parameters) throws (a lot) { 
    Class<ParametricFunction> c = (Class<ParametricFunction>) ClassLoader.getSystemClassLoader().loadClass(fnName); 
    Method m = c.getMethod("getValue", x, parameters); 
    return ((double) m.invoke(null)); 
} 

und ruft evaluate("Parabola", 1, new double[]{1,2,0});.

+1

Warum muss getValue statisch sein? Sie könnten genau das tun, was Sie wollen, wenn getValue nicht statisch ist. – nos

+0

Dann müsste ich eine Instanz der Klasse erstellen. Korrigiere mich, wenn ich falsch liege, aber in Bezug auf seinen Zweck scheint das hier nicht nützlich zu sein. –

+2

Was ist falsch ist dein Design. Es ist nicht OO. parameter [] sollte ein Instanzfeld der Parabola-Klasse sein, im Konstruktor gesetzt und überprüft und in der Klasse getValue() verwendet werden. –

Antwort

14

Sie nicht Klassen erfordern eine bestimmte statische Methoden über eine Schnittstelle zu implementieren. In Java macht das keinen Sinn. Schnittstellen erzwingen das Vorhandensein bestimmter nicht-statischer Methoden in den Klassen, die die Schnittstelle implementieren. das machen sie.

Der einfachste Weg ist definitiv, eine Art von Fabrikklasse zu haben, die Instanzen der anderen erzeugt. Ja, das bedeutet, dass Sie daran denken müssen, diese Fabrik auf dem neuesten Stand zu halten, wenn Sie neue Instanzen hinzufügen, aber seit dem, was Sie als Erstes tun, testen Sie es (Sie testen es, ja?) Ich werde dieses Problem sehr schnell aufgreifen!

+5

Warum macht es keinen Sinn? Kann eine Schnittstelle nicht verlangen, dass Klassen eine 'statische öffentliche Zeichenkette getDescription()' bereitstellen? Ich verwechsle das nicht mit Javadoc, was ich meine ist z. eine GUI, in der der Benutzer die 'ParametricFunction' auswählt, um Daten anzupassen und zu wissen, was jede Funktion macht, wenn der Name alleine nicht so intuitiv ist. Und dann betrachten Sie die 'ParametricFunction' als etwas komplizierter, so dass die Instanziierung wirklich viel Zeit in Anspruch nehmen würde, besonders wenn Sie eine Liste mit den Beschreibungen von zum Beispiel 100' ParameterFunktionen' anbieten, von denen letztendlich nur eine ausgewählt würde . –

+1

Es macht keinen Sinn, weil Sie statische Methoden für Klassen und nicht für Instanzen aufrufen. Es gibt keine Interesse für beide Klassen, den gleichen Namen der statischen Methode zu teilen, da Sie diese Methode nicht über die Schnittstelle aufrufen ... Was würden Sie erwarten, dass die getDescription() zurückkehrt? Die Beschreibung der Klasse? Oder die Beschreibung der aktuellen Instanzklasse? –

+0

Einige Objektsysteme lösen dies, indem sie die statischen Methoden zu Methoden für das Klassenobjekt machen. Java hat dies nicht getan und sich entschieden, in diesem Bereich näher an C++ zu sein. –

3

Die Idee dahinter in einer Reflexion Paket und Verwendung mehr ParametricFunction den setzt sie alle aufzuzählen, so dass der Benutzer zum Beispiel wählen welches zu plotten.

, die für einen grundlegenden Grund zum Scheitern verurteilt geht: Reflexion bietet keine Möglichkeit, alle Klassen in einem Paket zur Liste (weil „alle Klassen in einem Paket“ nicht eine gut definierte Menge ist, aufgrund der Flexibilität der Klassenlademechanismus).

Die moderne Lösung für diese Art von Sache ist es, sie über ein Dependency-Injection-Framework in die Anwendungskonfiguration zu integrieren.

Offensichtlich könnte man einen Lader Klasse bieten eine Reihe der verfügbar ParametricFunction ist enthalten, aber jedes Mal ein neues Geschäft implementiert man es daran zu erinnern, hat es das Hinzufügen, zu .

Nun, mit Ihrem Konzept, jedes Mal, wenn ein neues implementiert wird, ist man gezwungen, es in dasselbe Paket zu legen. Indem Sie es in eine Konfigurationsdatei oder eine Loader-Klasse (genau das gleiche) einfügen, entfernen Sie diese Einschränkung.

+0

Nun, ich könnte die böse Sache tun und das Dateisystem verwenden, um das Verzeichnis des Pakets aufzulisten ... Für mich macht es Sinn, alle 'ParametricFunction's in ein Paket wie' my.math.function.parametric' zu schreiben. Aber eine Konfigurationsdatei würde auch den Klassenlader erfordern und eine erweiterte Sache wie (Ich werde die Frage sofort bearbeiten) 'static boolean checkParameters (...)' würde immer noch den Mechanismus, nach dem ich gefragt, nein? –

+0

@Tobias: Die Konfigurationsdatei hätte einen spezifischen Namen und listet die spezifischen Namen der zu ladenden Klassen auf - kein Problem. Was das checkParameter() angeht - das ist einfach falsch. Sie missbrauchen grundsätzlich OO-Konzepte. Klassen sollen mehrere Instanzen mit unterschiedlichem Status haben, nicht als eine Sammlung von statischen Methoden. –

+0

Wenn nicht Klassen, was kann ich als eine Sammlung von statischen Methoden verwenden? Macht meine eigene Antwort die Dinge zumindest ein bisschen besser? –

0

Eine Lösung - ist alle Methoden nicht statisch mit der Anforderung, dass die Klasse Standardkonstruktor haben muss. Dann können Sie es einfach instanziieren und Methoden aufrufen, die Sie benötigen.

+1

@Ha: Du meinst wie in der Antwort, die ich selbst gepostet habe? Ich habe es überdacht, aber für mich erscheint es unnötig, eine Klasse zu instanziieren, für die die Möglichkeit mehrerer Instanzen nichts Nützliches bietet. –

+1

Ja, Sie verlieren 16 Byte, um die Instanz zu speichern, erhalten aber eine Menge Geschwindigkeit, da nur Konstruktor über Reflektion aufgerufen wird. –

+0

Ich habe dieses Muster in Eclipse verwendet. Mylyn Connectors Plugins bieten eine Klasse, die eine abstrakte Klasse erweitert, und nur eine einzelne Instanz der Klasse des Connectors wird irgendwo innerhalb des Mylyn durch Reflektion erzeugt. So ist dein Fall - nur eine reflexionsbewusste Singlton-Klasse erstellt alle notwendigen Instanzen und legt sie in die Karte. –

0

Was wollen Sie tun, um nicht in Ordnung ...

Sie wollen in einer Schnittstelle I statische Methoden zu definieren und einige Implementierungen A und B dieser Schnittstelle haben, mit ihren eigenen Umsetzung dieser statischen Methoden erklärt in die Schnittstelle I.

Stellen Sie sich vor, wie der Computer wissen würde, was zu tun ist, wenn Sie I.staticMethod() aufrufen ??? Wird es die Implementierung von A oder B benutzen? !!

Das Interesse, eine Methode in der Schnittstelle zu deklarieren, besteht darin, Polymorphie zu verwenden und diese Methode für verschiedene Objektimplementierungen aufzurufen ... Aber für statische Methoden, da Sie die Methode nicht von einer Instanz (eigentlich von Ihnen) aufrufen kann aber nicht wirklich gebraucht werden ...) aber mit ClassName.xxxMethod hat es absolut kein Interesse ...

Also muss man diese statischen Methoden nicht in die Schnittstelle einfügen ... einfach in beide hineinlegen Implementierungen und rufen Sie sie mit A.staticMethod() und B.staticMethod() (und sie müssen nicht einmal den gleichen Methodennamen teilen!)

Ich frage mich, wie Sie Ihre statische Methode aufrufen möchten, probieren Sie Code zu zeigen?

+0

Ich würde niemals I.staticMethod() nennen wollen, deshalb habe ich es auch als abstrakt bezeichnet. Ein Beispiel ist in der nun bearbeiteten Frage. –

+0

Also würden Sie A.staticMethod oder B.staticMethod ... nennen So wissen Sie zur Kompilierzeit, auf welcher Klasse Sie die Methode aufrufen, also warum brauchen Sie eine gemeinsame Schnittstelle mit der statischen Methode? Wenn Sie die statische Methode für eine Objektinstanz aufrufen würden (i.staticMethod (sowieso nicht möglich), a.staticMethod oder b.staticMethod), sollten Sie besser nicht statische Methoden verwenden ... –

+3

Weil ich A und B, um das staticMethod * sicher zu implementieren * und sicherzustellen, dass jemand anderes, der das Interface für eine neue Klasse verwendet, dies auch tut. –

2

Ihre Antwort auf Ihre eigene Frage kann weiter vereinfacht werden. Halten Sie die ParametricFunction Schnittstelle, wie sie ist, und ändern Parabola in ein Singleton, die ParametricFunction implementiert:

public class Parabola implements ParametricFunction { 
    private static Parabola instance = new Parabola(); 

    private Parabola() {} 

    static public ParametricFunction getInstance() { 
    return instance; 
    } 

    public double getValue(double x, double[] parameters) { 
    return (parameters[2] + x*(parameters[1] + x*parameters[0])); 
    } 
    public String getName() { return "Parabola"; } 
    public boolean checkParameters(double[] parameters) { 
    return (parameters.length==3); 
    } 
} 

der Tat, wenn es keinen besonderen Grund, warum braucht Parabola eine Singleton-Klasse sein, könnten Sie loswerden der statischen Methode erhalten und attribiere und mache den Konstruktor öffentlich.

Der Zweck von einer Instanz von Parabola schaffen, ist zu Ihre Anwendung vereinfachen.

EDIT als Antwort auf Ihre Frage unter:

Sie nicht Standard verwenden können Java-Konstrukte eine Klasse zu zwingen, eine statische Methode mit einer bestimmten Signatur zu implementieren. Es gibt keine solche Sache als eine abstrakte statische Methode in Java.

Sie können überprüfen, ob eine statische Methode implementiert ist, indem Sie ein separates Tool schreiben, das als Teil Ihres Builds ausgeführt wird und entweder den Quellcode oder den kompilierten Code überprüft. Aber IMO, es ist die Mühe nicht wert. Alle fehlenden getInstance() werden angezeigt, wenn Sie Code kompilieren, der sie aufruft, oder zur Laufzeit, wenn Sie versuchen, sie reflektiv zu verwenden. Das sollte meiner Meinung nach gut genug sein.

Außerdem kann ich nicht einen überzeugenden Grund, warum Sie benötigen die Klasse, um ein Singleton zu sein; d.h. warum die getInstance Methode notwendig ist.

+0

+1 Definitiv weniger kompliziert als mein Weg, danke. Aber es gibt immer noch keine Möglichkeit sicherzustellen, dass eine neue Klasse, sagen wir 'Gaussian', auch die' getInstance() 'Methode implementiert. –

+0

warum nur eine Instanz erstellen, tatsächlich könnte es viele Parabeln in seiner Anwendung geben ... Singleton sollte für Toolbox, Dienste usw. verwendet werden, aber keine Modellobjekte. Ich glaube wirklich, Sie haben nur OOP Grundlagen! –

+2

@Sebastien Lorber - sprichst du mit mir? Hast du meine ganze Antwort gelesen? –

1

Der Grund dafür ist die Lesbarkeit: fit ("Parabola", XValues, fValues) vs. fit (Parabola.getInstance(), XValues, fValues) vs. fit (neu Parabola(), XValues, fValues). Warum sollte ich eine Instanz der Funktion vollständig durch seine Argumente ohne interne Daten haben wollen?

Eigentlich etwas über Sie Grundlagen orientierte Objektprogrammierung fehlen ...

Wenn Sie ein Objekt Parabola definieren, sollte dieses Objekt eine Parabel dar, und nicht eine Toolbox überprüfen Parameter ok etc sind ...

Ihre Parabola Artikel sollten die Parameter (x, y ...) enthalten und man konnte sie mit Konstruktor übergeben ...

double x; 
double [] parameters; 
public Parabola(double x, double[] parameters) { 
    this.x = x; 
    this.parameters = parameters; 
} 

So sollten Sie nicht auf Ihre func verwenden Parameter tion, da die Parameter deklariert werden nun als Klassenmitglied Attribute ...

public double getValue() { 
    return (this.parameters[2] + x*(this.parameters[1] + x*this.parameters[0])); 
} 

Dann rufen Sie einfach

parabolaInstance.getValue(); 
+0

Ich weiß, aber das würde eine Fit-Funktion erfordern, 'setParameters (Parameter)' und 'getValue (x)' jedes Mal anstelle von einfach 'getValue (x, Parameter)' aufzurufen. Auf der anderen Seite würde setParameters nur für eine neue Anpassung aufgerufen werden und das Übergeben der Parameter für jede Auswertung ist eine Verschwendung ... ich verstehe. +1 –

+1

Eigentlich warum tun so etwas wie dies nicht: Parabola Parabel = new Parabola (x; y; z) fit (Parabola) mit public void (oder was Sie wollen) fit (ParametricFunction pamFunc) { // yourimpl } –

+0

+1 wahr in der Tat. Aber was ist mit dem Problem, das ich als Antwort auf Donal Fellows Antwort formuliere? http://stackoverflow.com/questions/2689312/is-there-a-way-to-make-sure-classes-implementing-an-interface-implement-static-me/2689947#2689947 –

4

Warum Java 5 Enum nicht versuchen? dh:

public enum ParametricFunctions implements ParametricFunction { 
    Parabola() { 
     /** @return f(x) = parameters[0] * x² + parameters[1] * x + parameters[2] */ 
     public double getValue(double x, double[] parameters) { 
      return (parameters[2] + x*(parameters[1] + x*parameters[0])); 
     } 

     public String getName() { return "Parabola"; } 

     public boolean checkParameters(double[] parameters) { 
      return (parameters.length==3); 
     } 
    }, 

    // other functions as enum members 
} 

Mit diesem können Sie die statischen Funktionstypen leicht und mit Kompilierung-Sicherheit sehen, aber immer noch erlauben, die Art der Schnittstelle verwiesen anderswo werden. Sie können auch eine Methode für den Aufzählungstyp platzieren, um das Nachschlagen der Funktion nach Namen zu ermöglichen.


EDIT für Bedenken bezüglich der Dateigröße mit dem Enum Weg.

In diesem Fall können Sie jede Funktion definieren könnte, da sie eine eigene Klasse ist, das heißt:

public class Parabola implements ParametricFunction { 

    /** @return f(x) = parameters[0] * x² + parameters[1] * x + parameters[2] */ 
    public double getValue(double x, double[] parameters) { 
     return (parameters[2] + x*(parameters[1] + x*parameters[0])); 
    } 

    public String getName() { return "Parabola"; } 

    public boolean checkParameters(double[] parameters) { 
     return (parameters.length==3); 
    } 

}

Dann können Sie viele separate, Implementierungsdateien haben, und komponieren sie in eine kleinere, Enum ähnliche Klasse, über die statisch auf die Funktionen zugegriffen werden kann. Ie:

public class ParametricFunctions { 
    public static final ParametricFunction parabola = new Parabola(), 
              bessel = new BesselFunction(), 
              // etc 
} 

Dies ermöglicht einen einzigen Ort, um die Funktionen nachzuschlagen, mit der Implementierung getrennt gehalten. Sie können sie auch einer statischen Auflistung für die Namenssuche hinzufügen. Sie könnten dann die Lesbarkeit in Ihre Funktionen aufrechtzuerhalten, wie in einem anderen Kommentar erwähnt:

import static ...ParametricFunctions.parabola; 
// etc 

public void someMethodCallingFit() { 
    fit(parabola, xValues, yValues); 
} 
+0

+1 für diese Idee. Aber leider ergibt sich daraus eine riesige Datei, wenn ich angefangen habe, BesselFunctions usw. einzubinden, die in einer separaten Klasse wirklich besser sein könnten ... –

+0

@Tobias: bitte nachsehen, ob meine Edit-Adressen das betreffen. – Grundlefleck

+0

Sie können mehrere Enums erstellen. Sie werden nur verwendet, um sicherzustellen, dass es sich bei Implementierungen um Singletons handelt. Eine natürliche Entwicklung dieses Ansatzes ist das Gruppieren von Funktionen in der gleichen Enumeration in der Benutzeroberfläche. –

0

@Sebastien: Warum gibt es kein Interesse für beiden Klassen der genauen gleichen statische Methode Namen zu teilen? Mit Reflexion könnte dies die einzige Möglichkeit sein sicherzustellen, dass die Methode existiert. I möchte getDescription() die Beschreibung der Klasse zurückgeben. Warum sollte sich auf verschiedenen Instanzen ändern? Deshalb möchte ich diese Methode statisch sein und dennoch in eine Interface-ähnliche Art erzwingen, dass es implementiert ist. - Tobias Kienzler 3

Wie ich bereits gesagt, die Methode statisch deklarieren bedeutet, dass Sie es direkt aus der Klasse aufrufen können und keine Instanz der Klasse benötigen. Da es keinen Sinn hat, I.staticMethod() (wie bereits erklärt) aufzurufen, können Sie einfach nur A.staticMethod1() und B.staticMethod2() aufrufen, ihr Name spielt keine Rolle, da Sie sie von A oder A aufrufen B-Klasse, zur Kompilierzeit bekannt!

Wenn Sie möchten, dass eine getDescription die gleiche Beschreibung unabhängig von der betreffenden ParametricFunction zurückgibt, machen Sie die ParametricFunction einfach zu einer abstrakten Klasse und implementieren Sie die statischen Methoden direkt in dieser Klasse. Dann können Sie A, I oder B.getDescription() aufrufen; (sogar a, ich oder b ...). Aber es bleibt dasselbe als es in A und B zu implementieren und es zu rufen, warf A oder B ...

Das Aufrufen einer statischen Methode aus einer Instanz ist keine gute Übung und hat kein Interesse, also sollten Sie A.meth anrufen() oder b.meth() und nicht a.meth() oder b.meth()

Weil ich A und B wollte implementieren, die Static sicher und sicher, dass jemand anderes das Interface machen für eine neue Klasse wird es auch tun.- Tobias Kienzler Vor 5 Stunden

Eigentlich „jemand anderes“ wird normalerweise nicht nennen a.meth() oder b.meth() also, wenn er eine Klasse C und wollen macht die C.meth() aufrufen Er wird das niemals tun können, weil C.meth() nicht implementiert ist oder nicht statisch ist ... also wird er es tun, oder das C.meth() würde nie aufgerufen werden und dann ist es auch nicht sinnvoll zu erzwingen developpers statische Funktionen zu implementieren, die nie verwendet werden würde ...

ich weiß nicht, was ich hinzufügen ...

+0

Ich habe die Frage aktualisiert, ich hoffe, es verdeutlicht meine Absichten. –

0

Constructor in-Schnittstelle? äh? Möchten Sie Interface i = neue Schnittstelle (double [] Parameter) aufrufen können? Und der Computer würde ein anderes Mal selbst die Implementierung wählen? Dies ist so seltsam wie statisch in der Schnittstelle: D

Wie Sie gesagt haben, sollte die Überprüfung der Parameter vor dem Bau erfolgen ... Aber das bedeutet nicht, Sie können keine Ausnahme auf Konstruktion auslösen, wenn die Parameter nicht in Ordnung sind. Es ist nur eine Sicherheit, die Sie hinzufügen können, die sicherstellen wird, dass das konstruierte Objekt kohärent sein wird. Aber mit einem solchen Code können Sie eine vorherige Validierung nicht umgehen: Wenn Sie beim Erstellen einer Ausnahme eine Ausnahme auslösen, wird Ihnen angezeigt, "Hey, Sie haben einen Fehler!" während nicht validieren die params wird nur sagen, "ho jemand mit GUI versucht, einen schlechten Wert zu setzen, senden wir ihm eine Fehlermeldung ..."

Eigentlich, da Sie die Werte validieren müssen, und das Objekt ist nicht einmal konstruiert, warum wollen Sie diese Validierung unbedingt auf das Modellobjekt anwenden? Form/Gui/was auch immer Validierung könnte überall durchgeführt werden, in einer Validierung Java-Klasse ... Setzen Sie einfach eine statische (oder nicht) -Methode in einer anderen Klasse namens ParametricFunctionValidationHelper, wo Sie Ihre Methode und die Validierung implementieren.

public static boolean validateParametricFunction(String functionType, double[] parameters) { 
    if (functionType.equals("bessel")) return validateBessel(parameters); 
    if (functionType.equals("parabola")) return validateParabola(parameters); 
} 

Es spielt keine Rolle, wie Sie Ihre Function dargestellt wird (i String wählen, weil ich Sie es aus Benutzeroberfläche erhalten annehmen, Web oder gui ... es Enum gewesen ...

Sie haben könnten kann auch das Objekt validieren, nachdem sie konstruiert haben:

public static boolean validateParametricFunction(ParametricFunction pamFunc) { 
    if (pamFunc instanceOf BesselFunction) return validateBessel(pamFunc.getParameters); 
    ...... 
} 

Sie können sogar setzen statische Validierungsmethoden in Funktionsklassen und dann werden Sie haben: public static boolean validateParametricFunction (ParametricFunction pamFunc) { if (pamFunc instanceOf BesselFunction) gibt BesselFunction.validateBessel zurück (pamFunc.getParameters); if (pamFunc instanceOf ParaboloFunction) gibt ParabolaFunction.validateParabola zurück (pamFunc.getParameters); }

Ja, Sie können die statische Methode in der Schnittstelle nicht einstellen, aber wie würden Sie eine solche Methode nennen?

Mit Code wie

public static boolean validateParametricFunction(ParametricFunction pamFunc) { 
    return ParametricFunction.validate(pamFunc); 
} 

??? Dies ist sinnlos, da die JVM überhaupt nicht wissen kann, welche Implementierung der statischen Methode verwendet werden soll, da Sie die statische Methode nicht von einer Instanz, sondern von einer Klasse aufrufen! Es ist nur sinnvoll, wenn Sie die validate-Methode direkt in der ParametricFunction-Klasse implementieren, aber wenn Sie so etwas tun, müssen Sie genau das tun, was ich Ihnen zuvor mit instanceOf gezeigt habe, weil die Instanz von pamFunc ist das einzige Element, das Sie auswählen müssen, welche Art von Validierung Sie verwenden müssen ...

Deshalb sollten Sie besser eine nicht statische Methode und es in der Schnittstelle wie setzen verwenden würde:

public static boolean validateParametricFunction(ParametricFunction pamFunc) { 
    return pamFunc.validate(); 
} 

Eigentlich, was Sie tun sollten, ist: - Retrieve Parameter (String?) Von GUI/Web-Schnittstelle/alles - Parse String-Parameter in einem guten Format (String ... int) - diese Parameter mit einer Prüfklasse validieren (statische Methode oder nicht) - Wenn keine Validierung -> Druck Nachricht an Benutzern - konstruiert Else Objekt - Verwenden Sie das Objekt

Ich sehe nirgends eine Notwendigkeit der statischen Methode in der Schnittstelle ...

Verwandte Themen