Definicja metody w innej metodzie?

0

Witam
Natrafiłem na taki fragment kodu:

import java.awt.EventQueue;
 
 public class Test {
 	public static void main(String[] args) {
 		EventQueue.invokeLater(new Runnable() {
 			@Override
 			public void run() {
 				new MyFrame();
 			}
 		});
 	}
 }

Jak widać (o ile dobrze widzę) w metodzie main jest definiowana metoda run(). Dlaczego to ma prawo działać? Wydawało mi się, że nie można definiować metod w innych metodach, czemu ten kod nie jest poza mainem?

1

Źle widzisz. Masz tam new Runnable() czyli tworzenie nowego obiektu klasy Runnable. Ale Runnable to interfejs, więc efektywnie tworzysz obiekt anonimowej klasy implementującej ten interfejs i definiujesz wymagane metody.
Przy okazji mamy już od dawna lambdy, wiec ten kod można by zapisać analogicznie jako EventQueue.invokeLater(()->new MyFrame()); bo Runnable ma tylko jedną metodę.

0

To jest klasa anonimowa, od java 8 mozesz to napisać nawet tak

EventQueue.invokeLater(() -> new MyFrame());
0
Shalom napisał(a):

Źle widzisz. Masz tam new Runnable() czyli tworzenie nowego obiektu klasy Runnable. Ale Runnable to interfejs, więc efektywnie tworzysz obiekt anonimowej klasy implementującej ten interfejs i definiujesz wymagane metody.
Przy okazji mamy już od dawna lambdy, wiec ten kod można by zapisać analogicznie jako EventQueue.invokeLater(()->new MyFrame()); bo Runnable ma tylko jedną metodę.

Czyli generalnie w metodach można definiować inne metody przy tworzeniu obiektów klas, które nie posiadają jeszcze definicji jakiejś metody? Dobrze rozumiem? Do tej pory wydawało mi sie, że nie można tego robić, że tak powiem, dynamicznie, tylko trzeba gdzieś w osobnym pliku zdefiniować daną metodę.

1

Jeśli chcesz stworzyć obiekt z interfejsu(interfejs nie ma uzupełnionej implementacji), to możesz go zawsze zaimplementować w miejscu, w którym robisz new Interface(). Wtedy nazywa się to klasą anonimową(dynamicznie ją implementujesz). Dopóki interfejs ma jedną metodę, dopóty możesz użyć do tego lambd. W Twoim przypadku to nie jest metoda w metodzie, tylko obiekt klasy anonimowej w metodzie.

0
IHaveHandedInMyResignation napisał(a):

Jeśli chcesz stworzyć obiekt z interfejsu(interfejs nie ma uzupełnionej implementacji), to możesz go zawsze zaimplementować w miejscu, w którym robisz new Interface(). Wtedy nazywa się to klasą anonimową(dynamicznie ją implementujesz). Dopóki interfejs ma jedną metodę, dopóty możesz użyć do tego lambd. W Twoim przypadku to nie jest metoda w metodzie, tylko obiekt klasy anonimowej w metodzie.

Dziwne. Dzięki wszystkim za odpowiedzi.

0

Czyli generalnie w metodach można definiować inne metody przy tworzeniu obiektów klas, które nie posiadają jeszcze definicji jakiejś metody? Dobrze rozumiem?

Nie. W metodzie możesz zrobić sobie klasę (anonimową lub nie), a w tej klasie możesz zrobić to co w każdej innej klasie oraz dodatkowo domknąć się na stanie z otaczających metod. Przykład z klasami nieanonimowymi https://www.ideone.com/xXr3ml :

/* package whatever; // don't place package name! */
 
import java.util.*;
import java.lang.*;
import java.io.*;
 
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		class Greeter {
			void greet() {
				System.out.println(Arrays.toString(args));
			}
		}
		new Greeter().greet();
		new Ideone().foo("me, of course");
	}
 
	void foo(String who) {
		class Bar {
			void baz() {
				class Abc {
					void xyz() {
						System.out.println("foo(" + who + ").Bar.baz().Abc.xyz()");
					}
				}
				new Abc().xyz();
			}
		}
		new Bar().baz();
	}
}

Wynik:

[]
foo(me, of course).Bar.baz().Abc.xyz()
1
PanRafal napisał(a):

Dziwne. Dzięki wszystkim za odpowiedzi.

Dlaczego dziwne? Po prostu nie występuje w kursach dla początkujących.
A tak à propos, jeśli to projekt Swingowy, bo tak pachnie fragment, to tą technikę się masowo używa choć dla Listenerów, tylko wzrokowo się wtapia

Przychodzi w pewnym momencie pora na tzw "drugą" książkę do Javy. Nie starszą niż Java 8.
Thinking in Java Bruce Eckel
Joshua Bloch
Zaawansowane książki Horstman

0
AnyKtokolwiek napisał(a):
PanRafal napisał(a):

Dziwne. Dzięki wszystkim za odpowiedzi.

Dlaczego dziwne? Po prostu nie występuje w kursach dla początkujących.
A tak à propos, jeśli to projekt Swingowy, bo tak pachnie fragment, to tą technikę się masowo używa choć dla Listenerów, tylko wzrokowo się wtapia

Przychodzi w pewnym momencie pora na tzw "drugą" książkę do Javy. Nie starszą niż Java 8.
Thinking in Java Bruce Eckel
Joshua Bloch
Zaawansowane książki Horstman

Jeszcze nie nadszedł ten moment. Kursy javy po prostu są skonstruowane tak, że co jakiś czas natrafiasz na coś co nie było nigdzie wcześniej omówione i musisz wchodzić na fora, albo szukać tego w innych kursach. Póki co chcę przerobić wszystko co jest w tym kursie, z którego teraz korzystam, a potem pomyślę co dalej, zorientuję się czy w innych kursach są jakieś informacje, z którymi się nie zapoznałem.

0

new Greeter().greet();

Czy dobrze rozumiem, że w tej linijce tworzysz obiekt klasy Greeter i jednocześnie wywołujesz jej metodę greet()? Myślałem, że wszystko musi być osobno :|

0

Dobrze rozumiesz. Jak widać nie musi

0

Ok, to temat wyczerpany, dzięki.

0

Można też zrobić tak:

String s = new Object() {
    private String m1() {
        return "hello " + m2();
    }

    private String m2() {
        return "world";
    }
}.m1();
System.out.println(s);

1 użytkowników online, w tym zalogowanych: 0, gości: 1