Interfejs z implementacją funkcji?

0

Witam

Mamy kilka klas dziedziczących np. po JPanel, JDialog.
Wszystkie te klasy wykorzystują te same funkcję (na przykład do dodawania przycisków na panelu).
Czy mogę stworzyć jakiś interfejs w którym będzie deklaracja i implementacja funkcji?
Czy jedynie można to zrobić na zwykłej klasie, zawrzeć w niej te metody i dziedziczyć z niej?

Pozrawiam

0

Nie możesz. Jednak można to rozwiązać przez kompozycję i delegację:

interface I{
  public void i();
}
class IImpl implements I{
  public void i(){
     System.out.println("i");
  }
}

class MyJPanel extends JPanel implements I{
  private I i = new IImpl();

  public void i(){
     i.i();
  }
}
0

Dzięki. Jest to bardziej wydajniejsze niż dziedziczenie??

Pozdrawiam

0

Ze względu na sposób w jaki w javie jest realizowane dziedziczenie tzn. dziedziczymy tylko z jednej klasy każde rozwiązanie jest lepsze i wydajniejsze :)

0

Albo przez metodę statyczną. Rozwiązanie z delegacją ma tę wadę, że delegowana metoda nie ma dostępu do obiektu delegującego.

interface I{
}


class IImpl {
  public static void i(I obiekt){
     System.out.println(obiekt);
  }
}

class MyJPanel extends JPanel implements I{

  public void i(){
     IImpl.i(this);
  }
}
0

Możesz jak najbardziej zrobić też po zwykłej klasie lub po klasie implementującej jakiś wspólny interfejs. Jednak ponieważ obiekty dziedziczące po klasach Swinga już mają swojego przodka, to musisz skorzystać z klas wewnętrznych, które będą dziedziczyć po tej klasie ze wspólnym kodem. Na przykład coś w tym stylu:

abstract class WspólnyKod
{
	private Component c;
	public WspólnyKod(Component c) { this.c = c; }
	protected Component get() { return c; }

	protected void metoda1()
	{
		System.out.println("Komponent graficzny:" + c.getName());
	}
	protected Window metoda2(Window w)
	{
		System.out.println("Okno top-level: " + w.getName());
		System.out.println("Inny obiekt: " + metoda3());
		return w;
	}
	abstract protected JComponent metoda3();
}

class InnyWspólnyKod
{
	//...
}

interface WspólnyInterfejs
{
	//...
	class KomplikacjaDoKwadratu
	{
		//...
	}
}

class MyJPanel extends JPanel
{
	private class Impl extends WspólnyKod
	{
		protected class Impl2level
			extends InnyWspólnyKod
			implements WspólnyInterfejs
		{
			public Impl2level() {}
			//...
		}
		private Impl2level y = new Impl2level();
		private Impl(JComponent c) { super(c); }

		@Override protected JComponent metoda3()
		{
			//...
			System.out.println("Adres klasy podwójnie wewnętrznej: "  + y);
			return (JComponent)get();
		}
	}
	private Impl x = new Impl(this);
	private JFrame f;

	public MyJPanel(JFrame f) { this.f = f; }
	//...
	public void i()
	{
		System.out.println("Realne dziedziczenie po 2 klasach");
		x.metoda1();
		System.out.println("Obiekt okna top-level: "
			+ x.metoda2(f).getName());
		System.out.println("Jakieś okno: " + x.metoda3());
	}

Trochę wydaje się to skomplikowane, ale sprowadza się do tego, że jak nie możesz dziedziczyć po jakiejś klasie bo dziedziczysz już po innej, to niech dziedziczy Twoja klasa wewnętrzna, z którą możesz zrobić wszystko. Klasa wewnętrzna (tu prywatna) ma dostęp zarówno do kodu po którym dziedziczy jak i do kodu klasy ją obejmującej dzięki niejawnie używanemu polu MyJPanel.this, którym poprzedzone są wszelkie dostępy do pól i metod tej klasy.
Realizacja klas wewnętrznych jest na poziomie generowanego kodu bardzo podobna do dziedziczenia wielobazowego w C++. Dziedziczenie z użyciem klas wewnętrznych ma tak naprawdę jeszcze większe możliwości niż każda postać dziedziczenia wielobazowego z C++. A to dlatego, że nie tylko mamy nad tymi klasami jawną i całkowita kontrolę oraz dlatego, że klasy wewnętrzne mogą dziedziczyć po klasach, które mają niby wielobazowe dziedziczenie - ale mogą mieć również cały garnitur swoich klas wewnętrznych połączonych na najróżniejsze sposoby. Ba, nawet klasy abstrakcyjne i interfejsy mogą mieć swoje klasy wewnętrzne, a więc interfejs, który nie może mieć własnego kodu może realnie dziedziczyć wielobazowo po realnym kodzie. A właściwie nie tyle interfejs ile klasa, która go zaimplementuje.

0

[browar] Hehe, dużo programuje juz w Javie, ale zawsze się czegos można nauczyć nowego. Faktycznie, nigdy nie myślałem o klasach wewnętrznych jako sposób na wielodziedziczenie. Może dlatego, że wielodziedziczenie jakoś nigdy mi nie było potrzebne. Szczerze, to może z jeden raz użyłem w C++, ale to było tak daaaawnoooo...

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