static / non-static variables i methods

0

Jestem strasznym nowicjuszem, jeśli chodzi o Javę, stąd podejrzewam proste pytanie.

 package agents;
import javax.swing.*; // wczytanie biblioteki graficznej swing
import java.awt.*; // wczytanie biblioteki graficznej awt
import java.awt.event.*;
import jade.content.ContentManager;
import jade.content.lang.sl.SLCodec;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;

public class Kalkulator extends Agent {

    @Override
    protected void setup(){

        Okno okno=new Okno(); // tworzymy nowy obiekt typu Okno (dalej będziemy o nim mówić "okienko"), który zaraz stworzymy
        okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // zamknięcie okienka ma być jednoznaczne z zamknięciem programu
        okno.setVisible(true); // nasze okienko ma być widoczne

    }
    public DFAgentDescription[] findServices(String name) {
        DFAgentDescription [] result = null;
        DFAgentDescription dfad = new DFAgentDescription();
        ServiceDescription sd = new ServiceDescription();
        sd.setType(name);
        dfad.addServices(sd);
        try {
            result = DFService.search(this, dfad);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return result;
    }

}

class Okno extends JFrame // tworzymy nowy obiekt "Okno"
{
  public Okno() // "konstruktor" czyli główna funkcja danej klasy o takiej samej nazwie co klasa. Określa właściwości okienka
  {
    setTitle("Kalkulator"); // Nadajemy nazwę okienka (będzie się wyświetlać na niebieskim pasku programu)
    setSize(210,150); // Określamy wymiary okienka w pikselach (160 szerokości, 250 wysokości)

    MojPanel p=new MojPanel(); // Tworzymy nowy obiekt typu "MójPanel" (dalej nazywamy go "panel"), który zaraz stworzymy
    Container powzaw=getContentPane(); // tworzymy obiekt "powzaw" który stanowi powierzchnię okienka.
    powzaw.add(p); // do tej powierzchni dodajemy panel, który stworzyliśmy dwie linijki wyżej
  }
}

class MojPanel extends JPanel // tworzymy nowy obiekt MójPanel
{

  JTextField a;     // definiujemy zmienną "a" typu "pole tekstowe" dla pierwszej liczby
  JTextField b;     // definiujemy zmienną "b" typu "pole tekstowe" dla drugiej liczby
  JTextField wynik; // definiujemy zmienną "wynik" typu "pole tekstowe" dla wyniku

  // Zmienne te definiujemy bezpośrednio w klasie, żeby były dostępne dla wszystkich funkcji w tej klasie

  public MojPanel() // "konstruktor" czyli główna funkcja danej klasy o takiej samej nazwie co klasa. Tu tworzymy fizycznie nasz "panel"
  {
    setLayout(new FlowLayout(FlowLayout.LEFT)); // określamy układ elementów w panelu.
                                                // Tu: FlowLayout, czyli wszystkie elementy są wyrównane do lewej strony
                                                // każdy kolejny element będzie "doklejany" do poprzedniego z prawej strony

    ActionListener sl1=new Dodaj();       // Tworzymy "podsłuch" o nazwie "sl1" w postaci funkcji Dodaj()
    plus.addActionListener(sl1);          // i podpinamy go pod przycisk o nazwie "plus"

    }

  class Dodaj implements ActionListener
  {
    public void actionPerformed(ActionEvent zdarzenie) // wykryj zdarzenie - kliknięcie
    {
                    DFAgentDescription[] dfad = Kalkulator.findServices("Add");
                    ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
                    msg.addReceiver(dfad[0].getName());
                    send(msg);
    }
  }
}

Generalnie problem jest na końcu.
non-static method findServices(java.lang.String) cannot be referenced from a static context DFAgentDescription[] dfad = Kalkulator.findServices("Add");
non-static method send(jade.lang.acl.ACLMessage) cannot be referenced from a static context Kalkulator.send(msg);
Jak zmienie findservices na static, to otrzymuję:
non-static variable this cannot be referenced from a static context result = DFService.search(this, dfad);
non-static method send(jade.lang.acl.ACLMessage) cannot be referenced from a static context Kalkulator.send(msg);
I tu już się moja wiedza kończy.

Generalnie chcę stworzyć agenta, który pokaże menu Kalkulatora i będzie po kliknięciu działania szukał usługi zarejestrowanej przez inne agenty (dodawanie/odejmowanie/etc) i wysyłał w wiadomości argumenty, a po zwrocie wyniku wyrzucał go do okienka.

0

findServices nie jest statyczne, chodziło ci chyba o samo DFAgentDescription[] dfad = findServices("Add"); (Dodaj jest niestatyczną klasą Kalkulator)

0
iooi napisał(a)

findServices nie jest statyczne, chodziło ci chyba o samo DFAgentDescription[] dfad = findServices("Add"); (Dodaj jest niestatyczną klasą Kalkulator)

Masz rację, ale ja nie rozumiem dlaczego jest jak jest.
non-static method findServices(java.lang.String) cannot be referenced from a static context DFAgentDescription[] dfad = Kalkulator.findServices("Add");

Dlaczego DFAgentDescription[] dfad jest statyczne?

Do mnie trzeba jak do konia, bo w Javie (i w ogóle obiektowo) nic nie pisałem, a od razu muszę wystrugać coś na agentach. Generalnie kody potrafię zrozumieć, ale z palca bym hello world nie napisał.

0

Nie. "Kalkulator" to jest statyczny kontekst. Aby wywołać niestatyczną metodę musisz mieć obiekt na którym ją wywołujesz, tzn niestatyczne metody mają implicite podany argument "this" (jest to ukryte przed programistą, bo nie ma sensu tak pisać). Na jakim obiekcie działasz pisząc "Kompilator.findServices"? Podpowiedź: żadnym, a więc to jest błąd.

Jeśli wywołujesz metodę bez kontekstu w metodzie niestatycznej to domyślnym kontekstem jest "this", czyli np pisząc "wait()" w rzeczywistości wykonujesz "this.wait()".

Sprawę trochę komplikują rzeczy typu "import static blbalblab", bo wyciągają statyczne metody do domyślnego kontekstu.

Używając jakiegoś w miarę dobrego IDE, możesz łatwo odróżnić metody statyczne od niestatycznych, np NetBeans używa pochylonego tekstu do wyświetlania wywołań statycznych metod.

Jeśli nie potrafisz nic napisać w Javie to idź tutaj: http://download.oracle.com/javase/tutorial/

0

Nie dość, że czytać ze zrozumieniem nie potrafię, to się okazało, że po prostu czytać też nie bardzo.

Generalnie to wersja "DFAgentDescription[] dfad = findServices("Add");" była moim wyjściowym pomysłem, ale wtedy się okazywało
cannot find symbol
symbol : method findServices(java.lang.String)
location: class agents.MojPanel.Dodaj
DFAgentDescription[] dfad = findServices("Add");
Więc na czuja dodałem to "Kalkulator." (próbując trików z C++). I wtedy były problemy ze statycznością.
Generalnie rozumiem problem, po Twoim wyjaśnieniu Wibowit. Przynajmniej tak mi się wydaje. Tyle, że nie wiem jak go rozwiązać.
Także jak ktoś poinstruowałby mnie w jaki sposób i czy w ogóle da się wywołać tą metodę, to byłbym wdzięczny.

0

Musisz jakoś poprzekazywać te referencje do obiektów pomiędzy obiektami. W konstruktorze, przez settery, a najlepiej przez wstrzykiwanie zależności :P Ale wstrzykiwanie zależności to już trudniejsza trochę sprawa. Staraj się nie używać statycznych metod i pól, praktycznie uniemożliwia to poprawne testowanie jednostkowe kodu.

0

Dzięki za wędkę :)

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