Klasa tworzona o dynamicznie ładowany interfejs

Odpowiedz Nowy wątek
2007-10-30 11:55
cj_tomekk
0

Witam,
chcę zrobić dynamiczne ładowanie klas i ich interfejsu.
Wstępnie ładuję interfejs, następnie klasy. Dalej chce stworzyć klasę na podstawie tego intefejsu:

...
Class cls = cl.loadClass("Test1Class");
ZaladowanyInterfejs klasa = (ZaladowanyInterfejs) cls.newInstance();

Ale przecież dynamicznie ładuje interfejs (nie musze wiedzieć jak sie nazywa) więc jak moge dokonać to co robi powyższy zapis?

Pozostało 580 znaków

2007-10-30 12:05
pikseloza
0

niemozesz - w refleksjach dzialaja zwykle mechanizmy jak bys pisal zwyczajnie kod (poza dostepem do pol chronionych i prywatnych, mozna to ominac), no ale nigdy przenigdy nie mozesz instancjonowac interfejsu, wiec newInstance() zawsze zwroci bodajze InstantiationException.

Pozostało 580 znaków

2007-10-30 12:11
ten sam co u gory
0

ej sory nie zauwazylem ze ladujesz klase in instancjonujesz klase i tylko chcesz rzutowac na interfejs
to co napisalem powyzej to blad

ogolnie jesli interfejs ladujesz rowniez dynamicznie, to nie mozesz bezporeednio jego nazwy uzyc w kodzie, poniewaz zwyczajnie nie jest oan dostepna

mozesz zrobic cos takiego:
ZaladowanyInterfejs.cast(zaladowanaklasa.newInstance());
no ale to zwraca typ T, wiec musialbys na cos rzutowac, a znowu nie masz na co
ogolnie to musialbys znac albo ten intefejs, albo jego metody, i wykonywac je rozniez porpzez refleksje (typ Method itp)

Pozostało 580 znaków

2007-10-30 12:19
0

Trochę dziwne to jest, ale należy sobie przygotować takie coś jak fabryka obiektów. Będzie ona na podstawie zadanego interfejsu i klasy implementującej produkować obiekty.
Co zaś tyczy sie samego rzutowania:

Class zaladowanyInterface = Class.forName("moj.interf");
Class zaladowanaKlasa = Class.forName("moj.klas");
Object o = zaladowanyInterface.newInstance();
o = zaladowanyInterface.cast(o);

I oczywiście to nie zadziała ponieważ nie znasz nazwy interfejsu. Bez znajomości interfejsów nie można ich w praktyce używać. Można co prawda kombinować z refleksją, ale musisz wtedy w interfejsach używać jakiś zasad nazewnictwa metod i pól.

Zastanów się jeszcze czy rozwiązanie jest prawidłowe na poziomie pomysłu.

Pozostało 580 znaków

2007-10-30 12:56
cj_tomekk
0

We właściwym projekcie interfejs będzie znany. Jadnak chciałem zrobić takie api co pozwoli że no. umieszcze w jednym folderze interfejs, w innym klasy po interfejsie. Następnie ma nastąpić załadowanie wszystkiego do takiego stanu bym mógł korzystać z załadowanych klas za pomocą załadowanego interfejsu. Nie przeczę że sie da. :-) Ale takie rozwiązanie mnie interesuje

Pozostało 580 znaków

2007-10-30 13:09
0

to może java bean... ale tam tez trzeba znać interfejsy. Spróbuj zrobić tak:

  • wypisz wszystkie potrzebne interfejsy, nawet niech będą to zaślepki
  • stwórz je i skompiluj
  • do każdego napisz konfigurowalna za pomocą javabean fabryki.

Innej metody nie widzę. Generalnie interfejsy są do tego, żeby móc pisać soft bez potrzeby znajomości jak są zaimplementowane jego poszczególne części. Programowanie bez wiedzy jakie interfejsy należy wykorzystać jest skazane na zagładę.

Pozostało 580 znaków

2007-10-30 13:33
cj_tomekk
0

Zawsze lubiłem hardcore :-)

Pozostało 580 znaków

2007-11-01 01:22
0
cj_tomekk napisał(a)

We właściwym projekcie interfejs będzie znany. Jadnak chciałem zrobić takie api co pozwoli że no. umieszcze w jednym folderze interfejs, w innym klasy po interfejsie. Następnie ma nastąpić załadowanie wszystkiego do takiego stanu bym mógł korzystać z załadowanych klas za pomocą załadowanego interfejsu. Nie przeczę że sie da. :-) Ale takie rozwiązanie mnie interesuje

kolego jak juz ktoś powyżej napisał Fabryka obiektów to jest dokładnie to o co ci chodzi .....Factory Object
ponizej jest przykładowa klasa. Cmd to jest interfejs który implemetuja wszystkie klasy poniezej. w metodzie cmd(name) przrekazujesz jakis string po którym ma rozpozawac klasy nie wiem czy to nazwa czy cokolwiek. Metoda ta jak zauwazysz zwraca interfejs Cmd czyli moze to byc którakolwiek klasa implemetująca go bo on pozwoli ci wywołac na sobei metody tylko te które sam zawiera.

public class CmdFactory {

public Cmd cmd(String param) {

    if (param.equals("view")) {

        return new ViewCmdImpl();

    } else if (param.equals("list")) {

        return new ListCmdImpl();

    } else if (param.equals("delete")) {

        return new DeleteCmdImpl();

    } else if (param.equals("addform")) {

        return new AddFormCmdImpl();

    } else if (param.equals("add")) {

        return new AddCmdImpl();

    } else if (param.equals("updateform")){

        return new UpdateFormCmdImpl();

    } else if (param.equals("update")) {

        return new UpdateCmdImpl();

    } else {

        return new ErrorCmdImpl();
    }

}

}

no i gdzies tam tworzysz dalej
tworzysz

CmdFactory factory=new CmdFactory();
Cmd InstanceClassImpl=factory.cmd("update");

i teraz
InstanceClassImpl bedzie obiektem typu UpdateCmdImpl

no i posługujesz sie teraz tylko interfejsem nikt na zewnatrz nie bedzie musiał wiediec jaka jest implemetcja klasy i która została wybrany tylko fabryka o tym wie

Pozostało 580 znaków

2007-11-01 10:44
0

uuuuuu, ale brzydki kod..
a nie lepiej tak:

private static final string VIEW="view";
private static final string LIST="list";
private static final string DELETE="delete";
private static final string ADD="add";
private static final Map<String,Class<? extends Cmd>> map=new TreeMap<String,Class<? extends Cmd>>();
static{
map.put(VIEW,ViewCmdImpl.class);
map.put(LIST,ListCmdImpl.class);
map.put(DELETE,DeleteCmdImpl.class);
map.put(ADD,AddCmd
}
public void myMethod(Stringparam){
   map.get(param).instance();
}

pozdrawiam

Pozostało 580 znaków

2007-11-01 11:51
0

jeśli chodzi o wygląd to nie przecze ze moj jest brzydki ale łatwiejszy do zrozumienia i co ważniejsze mniej pamięciożerny. ładnie nie zawsze jest super , twój kod jest trudny do zrozumienia a juz napewno dla początkującego. wogóle to robisz tak ze przy tworzeniu obiektu fabryki najpierw tworzysz z góry pola stringowe ...bedzie ich 500 to zrobisz 500 stringów a potem jesczze od razu musisz zbudowac mape czyli kolejna pamiec. jak juz cos to lepiej chyba tak by było bez przepisywania stringów

private static final Map<String,Class<? extends Cmd>> map=new HashMap<String,Class<? extends Cmd>>();
static{
map.put("view",ViewCmdImpl.class);
map.put("list",ListCmdImpl.class);
map.put("del",DeleteCmdImpl.class);
map.put("add",AddCmdImpl.class);
}

jesczze nie widziałem takiej implemetacji fabryki obiektów ale pewnie zadziała chociaz czy napewno ten kod

public void myMethod(Stringparam){
map.get(param).instance();
}

zwróci instancje obiektu ?? jak juz cos to tak

public Cmd myMethod(String param) throws Exception{
   return map.get(param).newInstance();
}

no dziwne rozwiązanie no ale pewnie zadziała. no moze byc.. ale sie rowinąłem.

pozdrawiam :)

Pozostało 580 znaków

2007-11-01 13:59
ktos inny
0

to tak na marginesie, ale ty tez tworzysz tyle samo stringow w pamieci ile eximus, przeciez java jak widzi literal typu "jakis napis" sama alokuje dla niego poamiec we wspolnym poolu stringow

poza tym kod eximusa jest bardzo czytelny i logiczny, moze nie dla poczatkujacego ale jednak mi sie wydaje ze jest on mimo wszystko potezniejszy, a jakby wypelniac mape z pliku konfig jakiegos (przy duzym projekcie) to wcale nie trzeba zmieniac kodu zrodlowego aby dodawac nowe implementacje interfejsu Cmd czy jaki tam jest

to tyle, ale mozna sie nie zgadzac ze mna, specem nie jestem :-)

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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