4 Stimmen

Kompilieren einer Java-Klasse gegen eine Schnittstelle, auch wenn keine angegeben wurde

Ich unterrichte einen Einführungskurs in die Programmierung und wir verwenden Java. Ich möchte den Studenten helfen zu lernen, wie man eine schriftliche Klassenspezifikation in ein funktionierendes Programm umsetzt. Ich werde die schriftliche Spezifikation zur Verfügung stellen. Sie gibt den Namen der Klasse und das Verhalten in Form von Methodensignaturen an. Ich möchte, dass die Schüler diese in eine funktionierende Java-Klasse übersetzen.

Ich könnte ihnen eine Schnittstelle zur Verfügung stellen und sie die Schnittstelle implementieren lassen, aber das verfehlt einen Teil des Zwecks: das Lesen und Interpretieren eines schriftlichen Pflichtenhefts. Ich möchte, dass sie die Klasse von Grund auf neu schreiben. Dann möchte ich ihre Arbeit benoten.

Meine Idee zur Überprüfung ihrer Arbeit ist folgende: Kompilieren Sie ihre Java-Klassendatei gegen meine eigene Schnittstelle. Wenn sie kompiliert, weiß ich zumindest, dass sie alle Methodenverträge befolgt haben, und ich kann mit dem Testen der Funktionalität beginnen. Lässt sie sich nicht kompilieren, erhalte ich eine Fehlermeldung, die mir mitteilt, welche Methoden nicht korrekt implementiert wurden.

Wie kann ich erzwingen, dass eine Java-Klassendatei gegen eine Schnittstelle kompiliert wird, auch wenn im Quellcode ursprünglich keine angegeben war?

Mit anderen Worten: Ich habe die folgenden zwei Dateien:

FooInterface.java

public interface FooInterface
{
    ...
}

Foo.java

public class Foo
{
    ...
}

Ich möchte Foo so kompilieren, als ob es FooInterface explizit implementiert. Aber ich möchte nicht einen Haufen von Quellcode-Dateien manuell bearbeiten müssen, um dies zu tun. Wie kann ich das machen?

Editar

Um die Frage nach dem Wert einer schriftlichen Spezifikation im Vergleich zur Bereitstellung der Schnittstelle zu beantworten, soll hier ein hypothetisches Spezifikationsdokument dargestellt werden:

Schreiben Sie eine Klasse namens Foo mit den folgenden Methoden:

älteste : ages (int[]) -> int
Gibt in einem Array von Altersangaben die höchste zurück.

anyAdults : ages (int[]) -> boolean
Gibt ein Array von Altersangaben zurück, ob einer von ihnen 18 oder älter ist.

IMO hat dies einen großen pädagogischen Nutzen. Die Schüler müssen kritisch beurteilen, ob ihr Programm die Spezifikationen einhält. Wenn ich die Schnittstellendatei zur Verfügung stellen würde, könnten sie ihr Gehirn ausschalten und sich einfach vom Compiler sagen lassen, ob sie die Spezifikation befolgt haben oder nicht. Die Verwendung des Compilers als kognitive Krücke ist die gleiche Technik, die die schlechteren Schüler derzeit (erfolglos) anwenden, um ihre Klammern auszugleichen.

3 Stimmen

+1 Guter Kurs. Sie sind ein guter Lehrer.

3 Stimmen

Wenn Sie Ihren Schülern genau Methodensignaturen als Teil der Spezifikation zu verwenden, wie unterscheidet sich das davon, ihnen eine echte Schnittstelle zu geben? Und wenn Sie nur die Klasse beschreiben, wird Ihr Ansatz wahrscheinlich in vielen Fällen scheitern, weil die tatsächlichen Signaturen, die Sie und Ihre Schüler entwickeln, sich geringfügig unterscheiden können.

0 Stimmen

@ChssPly76 - Da bin ich anderer Meinung. Wenn der Auftraggeber sorgfältig vorgeht, kann die Signatur der Methode genau beschrieben werden, und die Schüler sollten in der Lage sein, sie leicht auszuführen, vorausgesetzt, sie sind sorgfältig. Es gibt noch einen weiteren Aspekt: Ein Teil des Lernens beinhaltet das Lesen und Interpretieren der Dokumentation, selbst angesichts einer unvollständigen Spezifikation oder eines Fehlers des Lehrers. Etwas selbst angesichts solcher Herausforderungen zu bauen, sollte imho gefördert werden.

2voto

Sie können nicht tun, was Sie tun wollen, wenn Sie nicht ihre Quelle verarbeiten.

Wenn Sie das wirklich wollen, können Sie ein Programm schreiben, das die Klasse lädt und mit Hilfe von Reflection die Methoden überprüft, um zu sehen, ob ihre Signaturen den gewünschten Werten entsprechen. Dafür ist eine Menge Ellenbogenschmalz nötig.

Ich persönlich würde vorschlagen, dass sie die Schnittstelle im Unterricht gemeinsam festlegen, bevor das Projekt zugewiesen wird, und dann sagen, dass DIESE Schnittstelle verwendet werden muss.

2voto

finnw Punkte 46519

Wenn die Spezifikation Folgendes enthält genau Methodensignaturen, können Sie auch die Schnittstelle bereitstellen, da die Schüler die Schnittstelle nicht wirklich schreiben, sondern aus der Spezifikation kopieren werden.

Wenn die Spezifikation nicht genau ist (nur die Parameter jeder Methode beschreibt), sollten Sie wahrscheinlich keine Schnittstelle verwenden, weil es viele gültige Interpretationen derselben Methode oder Parameterbeschreibung geben kann ( protected vs. public , unterschiedliche Reihenfolge der Argumente, List vs. Array vs. Iterable , BitSet vs. Set<Integer> usw.) Sie sollten Ihre Schülerinnen und Schüler nicht dafür bestrafen, dass sie eine Lösung gefunden haben, die nicht genau der Ihren entspricht.

1voto

Aditya Mukherji Punkte 8875

Die Idee von @weiji mit der Reflexion klingt wirklich gut, auch wenn sie die Dinge für Sie sehr kompliziert machen könnte
Vielleicht könnten Sie eine weitere Klasse schreiben, die von ihrer Klasse erbt, aber zusätzlich die angegebene Schnittstelle implementiert und mit Dummy-Methoden gefüllt ist, die einfach die entsprechenden Funktionen in der Elternklasse aufrufen

1voto

Tom Duckering Punkte 2689

Es ist zwar hakelig, aber können Sie nicht einfach ein Tool wie sed verwenden, um "implementiert YourInterface" einzufügen, wenn es angebracht ist?

Ich weiß, dass dies schwierig wäre, wenn es viele Klassen mit unterschiedlichen Namen gäbe, aber es scheint nur eine Klasse zu geben, die sie einreichen können, also wäre es in Ordnung.

Wenn dieser Ansatz wirklich abwegig ist, können Sie ihn gerne in den Kommentaren kritisieren, um der Nachwelt zu dienen.

1voto

broschb Punkte 4968

Eine andere Möglichkeit ist, die Schüler erst die Schnittstelle und dann die Klasse schreiben zu lassen. Man könnte ihnen also die Anforderungen vorgeben und sie eine Klasse mit Methoden schreiben lassen, die diese Anforderungen erfüllen, und sie eine Schnittstelle schreiben lassen, die diese Klasse implementiert. Sie hätten also Folgendes:

InterfaceFoo{
 ....
 }
Foo implements InterfaceFoo{
 ....
 }

Dann könnten Sie einfach eine Klasse mit den definierten Methoden haben und InterfaceFoo implementieren. Wenn es kompiliert, dann wissen Sie, dass die Schüler die korrekten Methoden und Signaturen erstellt haben, wenn nicht, dann wird der Compiler Sie wissen lassen, was sie übersehen haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X