Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase

  • 44 odgovora
  • 11.233 pregleda

Najnovija ↓

Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 13:52 · pre 271 mesec #1
Code:

class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            Odeljenje a = new Odeljenje("Pera", "Ana", "Mika", "Sanja");

            // Ispisivanje Clanova niza preko klase Odeljenje
            a.Ispisivanje ();
            
            // Pozivam konstruktor klase TestClass
            new TestClass ();
        }
    }
    class Zaposleni
    {
        public Zaposleni(string imeZaposlenog)
        {
            ime = imeZaposlenog;
        }
        public string ime;
    }
    class Odeljenje
    {
        // Niz zaposlenih
        public Zaposleni [] m_zaposlenog;

        // Konstruktor
        public Odeljenje ()
        {
        }        

        // konstruktor koji upisuje clanove niza
        public Odeljenje(string zaposleni1, string zaposleni2, string zaposleni3, string zaposleni4)
        {
            //pravim niz od 4 ekipe
            m_zaposlenog = new Zaposleni [4];

            //Zaposlenima u nizu dajem imena
            m_zaposlenog[0] = new Zaposleni(zaposleni1);
            m_zaposlenog[1] = new Zaposleni(zaposleni2);
            m_zaposlenog[2] = new Zaposleni(zaposleni3);
            m_zaposlenog[3] = new Zaposleni(zaposleni4);
        }

        public void Ispisivanje ()
        {
            for (int i=1; i<=4; i++)
                Console.WriteLine ("Iz klase Odeljenje pozivam: "+m_zaposlenog[i-1].ime);

            Console.ReadLine ();
        }
    }
        
    // Test klasa
    class TestClass
    {
        public TestClass ()
        {
            Odeljenje odelj = new Odeljenje ();
            for (int i=0; i<4; i++)
                Console.WriteLine ("Iz klase Testclass pozivam: "+odelj.m_zaposlenog[i].ime);

            Console.ReadLine ();
        }
    }


Mozda je prevelik kod ali...

Iz klase Class1 sam poslao clanove nizu "Zaposleni [] m_zaposlenog" i kreirao niz koji se nalazi u klasi Odeljenje. Sada hocu tim clanovima da pristupim iz trece klase (npr. TestClass).

U konstruktoru TestClass pokusavam da pozovem public niz m_zaposlenog iz klase Grupa, preko koda:

Odeljenje odelj = new Odeljenje ();
for (int i=0; i<4; i++)
Console.WriteLine ("Iz klase Testclass pozivam: "+odelj.m_zaposlenog.ime);

E tu nastaje problem, jer mi C# prijavi gresku u toku rada programa:

"Object reference not set to an instance of an object."

Dakle, moje pitanje je: ako ne mogu ovako da pristupim sacuvanim podacima u promenljivoj "Zaposleni [] m_zaposlenog", kako mogu, i da li uopste mogu iz neke druge klase osim iz klase Odeljenje?
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 14:20 · pre 271 mesec #2
Hm ... Pogresio si poprilicno. Kao prvo pozvao si konsturuktor
Code:
Odeljenje()
a taj konstruktor ne inicijalizuje niz. To bi se u Javi manifestovalo kao NullPointerException. Dakle, moras da pozoves drugi konstruktor, onaj kome se predaju imena.

Uzgred, enkapsulacija je majka OO programiranja. Izbegavaj da atributi klase budu public. Dakle, "uvek" atribute deklarisi kao private, a pristup njima ide kroz get - set metode. To je bar u C# lepo reseno.
Ono "uvek" je namerno u navodnicima, jer nije bas uvek, postoji mnogo mnogo polemika, ali za pocetak shvati to kao dobru programersku praksu.
Potpis
OTPOR blokadi ulica, OTPOR blokiranom Beogradu, OTPOR blokiranoj Srbiji
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 14:36 · pre 271 mesec #3
Citat:
C# prijavi gresku u toku rada programa: "Object reference not set to an instance of an object."

Dakle, moje pitanje je: ako ne mogu ovako da pristupim sacuvanim podacima u promenljivoj "Zaposleni [] m_zaposlenog", kako mogu, i da li uopste mogu iz neke druge klase osim iz klase Odeljenje?

Što se greške tiče, u klasi TestClass ti ponovo instanciraš odeljenje (dakle to više nije ono isto odeljenje koje si napravio u Main()) i pozivaš prazni konstruktor koji ne radi ništa (niz nije inicijalizovan). Počni od početka da radiš profi i piši:
Code:

if (m_zaposlenog !=null) {
  for (int i = 0; i < m_zaposlenog.Length; i++) {
    m_zaposlenog[i].Pisi();
  }
}


Što se drugog pitanja tiče, da, možeš da pristupiš sačuvanim podacima. Da si u Main(), posle a.Ispisivanje() rekao
Code:
Console.WriteLine (a.m_zaposlenog[3].ime);
, to bi radilo.

Naravno, kao što je pomenuo Mr. Beograd, nije dobra praksa izlagati tek tako nizove sa kojima klasa interno radi da budu public.
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 14:41 · pre 271 mesec #4
U jeziku kao C# teško mogu da smislim situaciju kad bi polja trebalo da budu public, tim pre što postoje properties.

Relja:
Ovde je DT napisao nesto sa cim se ja ne slazem, pa sam mu obrisao poruku. ;) U stvari kliknuo sam na pogresno dugme - izmena umesto odgovora. Ah taj usability.


[Ovu poruku je menjao Reljam dana 27.07.2004. u 08:50 GMT]
Potpis
IOCC
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 14:53 · pre 271 mesec #5
Sasvim tako. Kao sto rekoh, enkapsulacija je jako bitna stvar. Jedina mi je zelja bila da posavetujem, a da nekako izbegnem polemiku oko objektnog dizajna. (Mada, kad malo bolje razmislim, gde cemo da polemisemo ako ne na forumu :) )

Mala digresija, prvo sto mi je upalo u oko to je public deklaracija atributa, a tek posle sam video sta i kako decko instancira i poziva.
Potpis
OTPOR blokadi ulica, OTPOR blokiranom Beogradu, OTPOR blokiranoj Srbiji
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 15:26 · pre 271 mesec #6
Citat:
Dragi Tata: U jeziku kao C# teško mogu da smislim situaciju kad bi polja trebalo da budu public, tim pre što postoje properties.

Ja lično ne volim propertije zbog mogućih sajd efekata. Reći ćete da je sve do kvalitetnog kodiranja, ali više volim kad sam jezik forsira kvalitetno kodiranje. Drugim rečima, u C# neko može u get sekciji nekog recimo int propertija da opali SQL kveri od 10 sekundi. Sa stanovišta nekog ko tu klasu koristi (a ne zna šta se u njoj dešava), dodela tipa "a.propName = 4" će trajati 10 sekundi. Ako, nasuprot tome, napravi metodu SetValueInDB(int v), neće izgledati čudno ako njeno izvršavanje traje 10 sekundi.

Ima dosta polemike na tu temu na netu.
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 15:36 · pre 271 mesec #7
Citat:
jablan: Ja lično ne volim propertije zbog mogućih sajd efekata. ...


Sasvim tako Jablane, ali ...
Meni je trebalo vremena da se naviknem (ako sam se uopste i moze reci da sam se navikao) i prihvatio sam tu praksu. Jer, uvek treba programirati u duhu jezika.
Ipak, primer ti nije bas ilustrativan. Jeste "... moze neko ..." Ali onda je to greska developera. Jer moze i property, koji ce da radi prosti (prosto prosiren) get - set, a za nesto poput toga se lepo napravi metoda smislenog imena.
Potpis
OTPOR blokadi ulica, OTPOR blokiranom Beogradu, OTPOR blokiranoj Srbiji
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 16:25 · pre 271 mesec #8
Hvala vam na brzom odgovoru. Kapiram ono za properties i da atributi budu private.

A ovo drugo...
Kada Jablan kaze:

Citat:

Što se drugog pitanja tiče, da, možeš da pristupiš sačuvanim podacima. Da si u Main(), posle a.Ispisivanje() rekao
Code:

Console.WriteLine (a.m_zaposlenog[3].ime);

, to bi radilo.


To znaci da napravljenom nizu (clanovima niza - "Pera", "Ana", "Mika", "Sanja") mogu da pristupim samo iz Main-a preko objekta "a" ili iz klase Odeljenje,a nema sanse da mu pristupim iz klase TestClass???

Pozdrav.
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 27.07.2004. u 16:51 · pre 271 mesec #9
Citat:
Dragi Tata:U jeziku kao C# teško mogu da smislim situaciju kad bi polja trebalo da budu public, tim pre što postoje properties.
Prvo, izvini za brisanje originalne poruke, nije bilo namerno. A sada malo o prop's ima:

Upravo suprotno. Sva polja koja trebaju korisnicima treba da budu public. Onda kada ti zatreba da nesto ima get / set accessore, onda to polje pretvoris u property. Ovo moze da se uradi bez ikakvih posledica po ostatak programa.

Potpuno je bespotrebno pisati ovakav kod:

int privateA;
public int publicA
{
get { return privateA; }
set { privateA = value; }
}

.NET ima mogucnost da bez posledica predjes sa polja na property. Vredi to iskoristiti.
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 28.07.2004. u 08:31 · pre 271 mesec #10
Citat:
stevva: To znaci da napravljenom nizu (clanovima niza - "Pera", "Ana", "Mika", "Sanja") mogu da pristupim samo iz Main-a preko objekta "a" ili iz klase Odeljenje,a nema sanse da mu pristupim iz klase TestClass???

Ne, pogrešno si me shvatio ili sam bio previše nejasan. Možeš da pristupiš i iz TestClass, ali ti nisi to radio, već si u TestClass ponovo kreirao odeljenje. Možeš da uradiš nešto ovako:
Code:

class Class1
{
  [STAThread]
  static void Main(string[] args)
  {
    Odeljenje a = new Odeljenje("Pera", "Ana", "Mika", "Sanja");

    // Ispisivanje Clanova niza preko klase Odeljenje
    a.Ispisivanje ();

    // Pozivam konstruktor klase TestClass
    new TestClass (a);
  }
}

// Test klasa
class TestClass
{
  public TestClass (Odeljenje o)
  {
    for (int i=0; i<4; i++)
      Console.WriteLine ("Iz klase Testclass pozivam: "+o.m_zaposlenog[i].ime);

    Console.ReadLine ();
  }
}

Valjda sam sad jasniji.
Citat:
Reljam: Upravo suprotno. Sva polja koja trebaju korisnicima treba da budu public. Onda kada ti zatreba da nesto ima get / set accessore, onda to polje pretvoris u property. Ovo moze da se uradi bez ikakvih posledica po ostatak programa.

Sa ovim se u potpunosti slažem. Nema potrebe pisati "prazne" propertije, a viđam da ljudi često to rade.
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 28.07.2004. u 09:09 · pre 271 mesec #11
hehe, relja me preduhitrio.. baš sam isto hteo da prokomentarišem, tj naslutio sam čak i šta će reći dok sam još čitao izmenjenu nemanjinu poruku.. ;)

elem, ja sam ovu osobinu voleo još u delphiju.. a delphi je imao još i poseban scope published koji se ponašao isto kao public, osim što je dopuštao samo propertije, pa si tako mogao sam sebe da kontrolišeš.. ;)


e sad, ovo što je relja rekao nije baš 100% tačno, jer postoji razlog zbog koga sam ja ipak svako public polje pretvarao u property. na sreću pa delphi čak i to okakšava kada se property direktno mapira na polje (znači bez get/set accessora), prostijom sintaxom tipa property Active: boolean read fActive write fActive;.

a razlog je taj što se property ipak ne može koristiti baš svuda kao i polje. jedan primer su recimo i parametri koji se prenose preko reference (i out u c#). i moram da priznam da sam pomalo bio razočaran što ovu mogućnost nisu ubacili u c#, jer mi se čini da su ipak imali više manevarskog prostora..

mislim, u delphiju se parametar prenosi (uglavnom) kao običan pointer (zbog efikasnosti, kompajliranja, etc), pa je nemoguće preneti podatke o potencijalnim aksesorima neophodnim za rad propertija, ali mi se to čini mnogo lakše izvodljivo kada se sve izvršava u VMu..

relja, ovo mi baš deluje kao zanimljivo pitanje.. da li možda možeš da iščačkaš nešto više o ovoj temi/odluci od .NET tima/iz interne dokumentacije? IMHO, bilo bi vrlo zgodno kada bi property mogao da se ponaša apsolutno isto kao i obično polje. ili bih bar voleo da saznam razloge zašto to nije poželjno/izvodljivo u .NET?


--
bože, ponekad sam sebe podsećam na onaj kliše iz "ratova programskih jezika", kada na kraju rasprave samo uleti delphi zealot i kaže "pih, mi sve to imamo već 10ak godina".. :-P
Potpis
blogče :: unescaped beta
  »
go-paste extenzija
  »
reč dana: backup
  »
bočne koalicije
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 28.07.2004. u 09:42 · pre 271 mesec #12
Zombie, nije mi najjasnije na sta si mislio (a upravo sam se vratio sa afterpartyja posle prvog dana DirectX Meltdown-a), tako da molim te daj primer u kodu field-a koj ne moze da se napise kao property. Pretpostavljam da mislis na field koji ces da koristis kao neki ref ili out parameter? Ajde da probamo, pa ako ne upali, znam ko zna zasto. :)
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 28.07.2004. u 10:35 · pre 271 mesec #14
ma da, mislio sam na najobičnije prosleđivanje propertija kao ref/out parametra..

Code:
class Shape {
    public int width { // get, set }
}

void AddOne(ref int val) {
    val++;
}

Shape s = new Shape();
AddOne(ref s.width);


koliko sam upoznat, ovo ne prolazi..


a u međuvremenu se setih još jednog razloga zašto je poželjno umesto javnih polja koristiti propertije (čak i ako direktno mapiraju neko polje), a to je nasleđivanje.

elem, polja se ne nasleđuju, a ponekad je potrebno promeniti način pristupa nekim poljima u nekoj kasnijoj klasi: (naravno, primer je banalan, ali zamislite neki komplikovaniji, real-life example)

Code:
class Shape {
    public int width;
}

class Rect : Shape {
    public int width { // get, set.. }
}

Shape s = new Rect();
s.width += 1;


elem, mene interesuje kako bi se C# ponašao sa ovako nečim? (ne mogu ovde trenutno da proverim)..

delphi će u sličnoj konstrukciji (valjda) samo javiti upozorenje o redeklaraciji Width, ali pristup neće ići preko aksesora nego će se direktno čitati/pisati Width polje Shape klase (što nije baš lepo).


a što se prednosti samih propertija tiče, ima i primera čisto sintaxne prirode, koji ipak mogu mnogo da doprinesu čitljivosti koda, kada je mnogo elegantnije koristiti ih: (malo "razrađen" primer koji je degojs dao na nemanjinom blogu ;)

Code:
a.setWidth(a.getWidth() + b.getWidth());
b.setWidth(b.getWidth() + 1);


mislim, uporedite to sa one-linerom a.width += b.width++; :-P

<rant>mada, ni u delphiju ovo ne bi moglo baš toliko elegantno, jer u njemu dodela nije expression već statement.</rant>


na kraju, sve se svodi na nivo apstrakcije kome težimo, i koji properties samo povećavaju. a apstrakcija je osnovni principi i glavna vodilja u programiranju (apstrakuj sve što može nezavisno da se promeni)..
Potpis
blogče :: unescaped beta
  »
go-paste extenzija
  »
reč dana: backup
  »
bočne koalicije
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 28.07.2004. u 14:03 · pre 271 mesec #15
Citat:
Reljam:
Potpuno je bespotrebno pisati ovakav kod:

int privateA;
public int publicA
{
get { return privateA; }
set { privateA = value; }
}

.NET ima mogucnost da bez posledica predjes sa polja na property. Vredi to iskoristiti.


OK, priznajem da si u pravu. Mada, C++/CLI uvodi nešto što se zove "trivial properties", pa možeš da napišeš prosto

Code:

property int publicA;


i to će da rezultuje potpuno istim kodom ispod haube.

Doduše, get/set metode (uključujući i propertyje) umeju da budu znak lošeg dizajna klase, ali to je opet priča za drugu temu.
Potpis
IOCC
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 28.07.2004. u 14:52 · pre 271 mesec #16
Citat:
-zombie-:
elem, mene interesuje kako bi se C# ponašao sa ovako nečim? (ne mogu ovde trenutno da proverim)..

delphi će u sličnoj konstrukciji (valjda) samo javiti upozorenje o redeklaraciji Width, ali pristup neće ići preko aksesora nego će se direktno čitati/pisati Width polje Shape klase (što nije baš lepo).


Isto kao i Delphi. U stvari, tvojom logikom, ovako nešto bi trebalo da prođe:

Code:

class Shape {
    public int width;
}

class Rect : Shape {
    override public int width { // get, set.. }
}


ali naravno javlja grešku pri kompajliranju
Potpis
IOCC
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 28.07.2004. u 19:53 · pre 271 mesec #17
Treba ti new deklaracija da bi "ukrao" identifikator u nasleđenoj klasi, a inače se potpuno isto ponaša sa i bez new, tj tretira ih kao dva različita polja.

Code:
public class Daddy {
    public int Polje;    }

public class Sonny: Daddy {
    public new int Polje { 
        set{ base.Polje = value;} 
        get{ return base.Polje;}
    }
}


ovo rešava stvar sa promocijom polja, i Polje je publikovano kao property u Sonny klasi, ali nažalost polimorfizam mu nije jača strana, tj kad se pojavi side-code u set accessor-u javljaju se problemi:

Code:
public class Daddy {
    public int Polje;
}

public class Sonny: Daddy
{
    private int SqrPolje;
    public new int Polje { 
        set{    base.Polje = value; 
            SqrPolje = value*value;} 
        get{ return base.Polje;}
    }
}

class Class1
{
    [STAThread]
    static void Main(string[] args)
    {
        Daddy s = new Sonny();
        s.Polje = 2;
    }
}


Polje postane 2, ali SqrPolje ostaje 0. Upravo iz ovog razloga nije dozvoljen override za promociju polja u property.
Ima još jedan caka u korist property-a, a to je registrovanje net klasa kao COM objekata, tada klijent vidi samo property-e (COM ne podržava polja). Kad se postavi pitanje "šta kao polja a šta kao property" tu je sve (kao i uvek) stvar dobrog planiranja...


Inače apropo prosleđivanja property-a kao ref parametara, to sumnjam da će ikad biti. CLI za smeštanje vrednosti u value ref parametar koristi stind (store indirect) komandu, dok se smeštanje u property obavlja sa callvirt nad set_xxxx skrivenim metodom, tj set accessorom. Pošto ti za ovo drugo treba i referenca na sam objekat :), kako će metoda sa ref parametrom da razlikuje ta dva slučaja? Ne može čak ni da tretira null-reference kao upotrebu non-property-a, pošto onda neće moći da se razlikuje static property i non-property :) Mrka kapa, čini mi se...
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: Pozivanje non-static promenljivih koje cuvaju podatke iz druge klase 29.07.2004. u 00:26 · pre 271 mesec #20
Citat:
degojs: Moraće da rekompajliraju, ali ne i da menjaju svoj kod.

Što je ok ako je sav source pod tvojom kontrolom, ali ako "prodaješ" neke kontrole ili druge public assembly-e koji će završavati u tuđim GACovima, ta promena će učiniti da stari i novi assembly budu nekompatibilni, automatski moraš da digneš major i/ili minor broj u oznaci verzije da bi GAC zadržao obe verzije.
A onda ide spika sa klijentima:
- zašto nas terate na novu verziju, šta to ima novo?
- pa znate, promenili smo polje da bude property 8)
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Odgovori
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme