Pozvati private metodu

Odavno znam da je u nekim OO jezicima moguće pozvati privatnu metodu (ili pristupiti privatnom atributu, sasvim je svejedno), ali nikad nisam naleteo na tu vrstu problema, pa se nisam preterano ni udubljivao. Međutim malopre sam naleteo na diskusiju na ESu gde je postavljano pitanje na koje bi odgovor mogao da bude baš ovo.

Princip koji se koristi da bi se ovo postiglo je refleksija. Wikipedia za refleksiju kaže da je to proces u kome program prati i menja svoju strukturu i ponašanje. Deo sa menjanjem ponašanja je upravo ono što nama treba.

Ukoliko sami pišete ceo projekat bez korišćenja bilo kakvog frameworka verovatno Vam ovako nešto nikad neće ni trebati, ali mala je šansa da ćete uvek svaki projekat raditi od nule. Jednostavno previše vremena oduzima, a ne treba izmišljati toplu vodu i raditi nešto što je neko već uradio. A kad već koristite tuđe delove koda može se desiti da bi Vam baš zgodno bilo da možete da  pozovete neku metodu ili da koristite neko polje za koje je autor smatrao da Vam nikad neće trebati. Te metode nisu privatne bez razloga, tako da se trudite da izbegnete da radite ovo (zvučim kao oni sa TV-a : “Ovo su radili uvežbani profesionalci i ne pokušavajte ovo kod kuće” :) ).

U svakom slučaju, potražio sam kako da uradim ovo u dva jezika koja trenutno naviše koristim. U pitanju su Python i Java.

U Python-u je metoda privatna ukoliko joj ime počinje sa dve podcrte, a ne završava sa dve podcrte. Pošto je u Pythonu sve objekat (i moduli, i klase, i metode…) sve se može uraditi u jednoj liniji (u ovom kodu poslednja linija):

#!/usr/bin/env python
class T:
    def __test(self):
        print "Privatna metoda __test iz klase T"
    def test(self):
        print "Javna metoda test iz klase T"
        self.__test()
 
if __name__ == "__main__":
    t = T()
    t.test()
    try:
        t.__test()
    except AttributeError:
        print "\t***Pokusaj pozivanja privatne metode klase T***"
    t.__class__._T__test(t)

Kao što ste mogli očekivati, izlaz je:

Javna metoda test iz klase T
Privatna metoda __test iz klase T
        ***Pokusaj pozivanja privatne metode klase T***
Privatna metoda __test iz klase T

Što se tiče Jave, stvari su malo komplikovanije (zar može jednostavnije od Python-a ;) ):

public class A {
    private void echo() {
        System.out.println("Iz klase A");
    }
}
import java.lang.reflect.Method;
 
public class B {
    public static void main(String args[])  {
        try {
            A a = new A();
            Class c = a.getClass();
            Method m = c.getDeclaredMethod("echo", new Class[0]);
            m.setAccessible(true);
            m.invoke(a);
        }
        catch (Exception e) { e.printStackTrace(); }
    }
}

Ovde izlaz izgleda ovako:

Iz klase A

Pokušao sam da nađem kod i za C++, međutim kad nakon par minuta googlanja nisam pronašao odustao sam (ipak je pola 7 ujutru :) ), ali zbog same strukture jezika pretpostavljam da ovako nešto nije moguće uraditi u par linija koda. Sam C++ ne podržava refleksiju, ali koliko znam postoje neki mehanizmi, kao na primer korišćenje podataka za debug-ovanje koje kompajler ugrađuje u izvršne fajlove, korišćenjem dynamic_cast operatora ili čak menjanje samog kompajlera, međutim ni jedno rešenje mi ne deluje kao nešto što mi je potrebno u ovom trenutku… Sledeći put…

Facebook comments:

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

 

Switch to our mobile site