Diskuze: používání "this" jako argument
Zobrazeno 4 zpráv z 4.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
Parametr this odkazuje na instanci dané třídy ve které se nachází, neboli parametr this ti umožnuje přistupovat k tomu samému objektu(instanci) v třídě, která danou instanci vyjadřuje(popisuje). Příklad, který jsi použil není zcela vhodný k pochopení jak this funguje.
v tvé případě
..
helloButton.addActionListener(this);
goodbyeButton.addActionListener(this);
...
je to samé jako
..
helloButton.addActionListener(new Toolbar());
goodbyeButton.addActionListener(new Toolbar());
...
proto taky metoda actionPerformed se nachází v class Toolbar . Nicméně new Toolbar() vytvoří novou instanci(tvz. zavolá konstruktor), což je zbytečné tak se tam radši hodí this, kdy tam tvz. pošleš instanci sebe sama, a nevytváří další dva objekty v haldě.( je to paměťově optimálnější řešení). Což ovšem neznamená, že v někdy nemusí nastat situace kdy příkaz this bude nevhodný a bude vhodnější vytvořit nové jednorázové instance new Toolbar().
pro bližší pochopení this se tvůj kód dá napsat taky takto. Je to naprosto identický zápis a je to správnější zápis, akorát se to tak nepíše. Nicméně když nějakou *.class dekompiluješ tak tam ty this parametry objevíš.
public Toolbar() {
this.helloButton = new JButton("Hello");
this.goodbyeButton = new JButton("Goodbye");
this.helloButton.addActionListener(this);
this.goodbyeButton.addActionListener(this);
this.setLayout(new FlowLayout(FlowLayout.LEFT));
this.add(helloButton);
this.add(goodbyeButton);
}
ve tvé fázi učení ti to bude dělat ještě problémy ale až to použiješ tak 500x tak to budeš dokonale zvládat. Stejně jako příkaz super. Tyto věci se hlavně používají pokud v kódu kombinuješ statiku, instance a OOP.
Na tomto příkladu se to bude vysvětlovat trošku obtížněji, pokud jsi
začátečník.
Nejprve věz, že pokud implementuješ nějaké rozhraní (v tomto případě
ActionListener), tak se instance tvé třídy mohou vydávat za datový typ
tohoto rozhraní.
Teď vysvětlení předchozí věty:)
Doufám, že tušíš, co je to datový typ.
Každý objekt v Javě MUSÍ být nějakého datového typu.
Například:
private int promenna; (objekt promenna je datového typu int)
private Smoula tatka = new Smoula(); (tatka je datového typu Smoula)
private String text = "nějaký text"; (text je datového typu String)
atd.
Protože z rozhraní nejde vytvořit objekt, tak se mohou za toto rozhraní
vydávat objekty, které toto rozhraní implementují.
Příklad:
víš, že třída A implementuje rozhraní B. Takže když vytvoříš nový
objekt
private A objekt = new A(); (tak tento objekt je datového typu
A, ale současně můžeš napsat i toto)
private B objekt = new A(); (a tím bude tento objekt datového
typu B, což je rozhraní)
Takže třeba v praxi:
Víš, že ArrayList implementuje List. Takže můžeš napsat buď:
private ArrayList kolekce = new ArrayList();
nebo
private List kolekce = new ArrayList();
No a teď se dostávám k tomuhle příkladu...
Ty tady z nepochopitelných důvodů implementuješ ActionListener. Tím
říkáš mimo jiné, že třída Toolbar je datového typu Toolbar a může
být datového typu ActionListener. (a ano, i JPanel, protože z něj dědíš,
ale to není teď součástí odpovědi).
Takže pro tebe to znamená, že Toolbar je jakoby ActionListener.
No a klíčové slovo "this" znamená v Javě odkaz na vlastní instanci ve třídě. V podstatě si můžeš přeložit slovo this, jako kdybys volal konkrétní instanci Toolbaru.
Takže Java to pochopí tak, že ty při volání kódu helloButton.addActionListener(this); voláš v podstatě helloButton.addActionListener(actionPerforrmed(ActionEvent e)), která je implementovaná v této třídě. (proto jsi ji musel implementovat, když jsi určil, že budeš implementovat rozhraní ActionListener).
Kdybys to this chtěl vypustit, tak bys to mohl napsat i takhle:
helloButton.addActionListener(event -> {
JButton clicked = (JButton)e.getSource();
});
//nebo při nejhorším takhle
helloButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton)e.getSource();
}
});
Zobrazeno 4 zpráv z 4.