Implementierung von Interfaces -> Problem mit main

freakdran

Mitglied
Hallo,

ich bin gerade mit Kommilitonen am diskutieren wie genau eine unserer Aufgaben gelöst werden soll.

Wir haben ein Interface bekommen
Java:
public interface StringToolkit {
	
	/**
	 * Diese Funktion akzeptiert einen String original als Parameter und liefert 
	 * einen neuen String als Ergebnis, in dem alle Buchstaben des ursprünglichen 
	 * Strings in Großbuchstaben umgewandelt enthalten sind. 
	 * Gewandelt werden die Buchstaben a bis z und die Umlaute ä, ö und ü. 
	 * Beispiel: "Viel Erfolg bei der Aufgabe!" wird umgewandelt in 
	 * "VIEL ERFOLG BEI DER AUFGABE!".
	 */
	String toUpper(String original);
}
und sollen eben das Beschriebene als Methode (ohne Schleifen, nur Rekursion) schreiben und dazu wie eigentlich immer eine main-Funktion.
Jetzt haben wir das Problem, dass wir nicht wissen ob wir das Interface direkt beim erstellen der Klasse implementieren sollen was zu
Java:
public class StringToolkitImpl implements StringToolkit {

	@Override
	public String toUpper(String original) {
		
		return null;
	}
}
führt oder es selbst schreiben sollen, was zum zum gleichen Ergebnis führt, bis auf Zeile 4, in der wir bisher immer ein "public static ..." benutzt haben.

Wenn wir die erste Variante benutzen zeigt es uns mit
Java:
public static void main(String[] args) {
...

println(toUpper(original));
}
den Fehler "Cannot make a static reference to the non-static method toUpper(String) from the type StringToolkitImpl" mit quick fix "change toUpper to static". Wenn wir das machen zeigt und toUpper() den Fehler "This static method cannot hide the instance method from StringToolkit" an und falls wir nur "public void main(...)" schreiben funktioniert alles Fehlerfrei.

Wenn wir alles selbst schreiben funktioniert auch alles ohne Probleme, deshalb fragen wir uns, warum der Fehler bei toUpper() kommt wenn wir static dazuschreiben und warum es funktioniert wenn wir nur das static aus der main löschen.

Ich hoffe ich hab mich verständlich ausgedrückt und bedanke mich schonmal
 
Aus einem statischen Kontext kann NIE auf einen nicht statischen Kontext zugegriffen werden.
Ein Interface wird immer von einem nicht statischen Kontext implementiert -> daher kannst du die Methode "toUpper" nicht statisch machen.
Wenn du wiederrum das "static" von der main Methode entfernst ist diese Methode Teil des nicht statischen Kontext und der Aufruf macht keine Probleme.
Leider muss jedes Java Programm ein statische main Methode haben um ausgeführt zu werden.

Die 1.Variante passt schon mit der Klasse "StringToolkitImpl". In der main Methode müsst ihr dann ein Objekt dieser Klasse erzeugen 😉
 
Eine Analogie hier:

MultiplicationUtil Interface
Java:
interface MultiplicationUtil {
  int multiply(int a, int b);
}

SimpleMultiplication
Java:
class SimpleMultiplication implements MultiplicationUtil {
  
  @Override
  public int multiply(int a, int b) {
    return a * b;
  }
}

AnotherSimpleMultiplication
Java:
class AnotherSimpleMultiplication implements MultiplicationUtil {
  
  @Override
  public int multiply(int a, int b) {
    int result = 0;
    for (int i = 0; i < b; i++) {
      result += a;
    }
    return result;
  }
}

InterfaceTest
Java:
public class InterfaceTest {
  public static void main(String... args) {
    MultiplicationUtil mult = new SimpleMultiplication();
    int a = 4;
    int b = 5;
    System.out.println(mult.multiply(a, b));
    mult = new AnotherSimpleMultiplication();
    System.out.println(mult.multiply(a, b));
  }
}
 
Zuletzt bearbeitet:
Hieße das, dass es bei Flown die letzten 3 in 3 verschiedene Klassen müssen?



Ist das Thema der Vorlesung am Freitag gewesen, bzw der Anfang davon und morgen würde der Rest kommen, nur muss die Aufgabe bis Vorlesungsbeginn fertig sein.
 
Joose hat recht. Jede Klasse oder Interface sollte in einer eigenen Datei definiert sein!
Man könnte alle in eine Datei schreiben, aber dann müsst man die Klassen/Interfaces static deklarieren, damit man von außen auch auf sie zugreifen kann. Sonst würde man eine Instanz aus der beinhaltenden Klasse benötigen. Aber das ist äußerst selten und sollte nicht verwendet werden.
 
Ok, danke, das macht das zumindest etwas verständlicher, da ich das bisher nicht wusste.
Ich habs grade mal handschriftlich als Pseudocode geschrieben und ich glaube ich habs verstanden und die Lösung (bin mir aber nicht ganz sicher ob das so funktioniert :bahnhof:

Edit: @Flown: Ja, hatten wir bisher so noch nicht besprochen deshalb war mir das unklar

Edit2: Ok hab jetzt erst mal noch getestet, ich kann auch alles in eine Datei schreiben (was mich zumindest im Moment weniger verwirren wird) und deshalb versuch ichs jetzt einfach alles erst mal in eine Datei zu packen. Wir müssen ja nur in dieser einen Datei arbeiten und nicht von außen auf etwas zugreifen.
 
Zuletzt bearbeitet:
Es scheint zu funktionieren, also großes Danke an Flown und Joose.

Ich würde den Code gerne posten, ist aber meiner Meinung nach etwas lang und unübersichtlich wenn man nicht gerade weis was genau gemacht wird, selbst ich muss teilweise grade suchen. 😀
 
Poste ihn einfach, damit andere mit einem ähnlichen Problem eine Lösung haben 🙂
Ob es dann die optimalste ist oder nicht sei mal dahin gestellt. Aber wird sich sicher auch jemand finden der euch dann eine vereinfachte Version zeigt 😉
 
Ich schreib mein kleineres Problem einfach noch hier dazu, dass ich nicht noch ein Thema erstellen muss, dafür erscheint mir das Problem zu banal.

Ich hab mehrere Methoden, die ein Zeichen eines Hauptstrings mit dem ersten Zeichen eines anderen (Sucher-)Strings vergleicht, falls die Zeichen gleich sind ruft sie eine weitere Methode auf, die die Zeichen des Hauptstrings von der Stelle des gefundenen Zeichens ab in einen neuen String packen mit der maximalen Länge des Sucherstrings. Dann wird der neue String zurückgegeben und mit dem Sucherstring verglichen.
Jetzt kommt das Problem:
Java:
if(pruefstring == search)
			return zaehler;
Ich hab es mit Breakpoints Zeile für Zeile durchlaufen lassen und habe gemerkt dass er zwar z.B.
Java:
if("2" == "2")
überprüft, aber dann einfach das return ignoriert und den zaehler weiterzählen lässt.
 

Zurück
Oben