Oprettet fre. d. 27. august 2010 kl. 15:49:48

amews_aj
amews_aj (21.175 point. Point ude: 100)
www.amews.net

Static vs accessor/mutator

Hej,

Hvis man nu har en class "MySuperClass" og en række subclasses "MySubClass1" "MySubClass2" ... "MySubClassN".
Derudover haves en "PrimaryClass" som opretter x antal objekter af de forskellige subclasses til MySuperClass.
Disse subclasses skal så tilgå samme information, fx en score.

Hvordan vil det mest hensigtsmæssigt laves?

Løsning 1:
Lav en static instansvariabel i "MySuperClass" der indeholder den delte information. Alle subclasses kan herved læse/opdatere. (Bemærk ingen brug af tråde, så burde ikke være interferens problemer).

Løsning 2:
Lav private instansvariabel i PrimaryClass, og en tilhørende accessor og mutator method. Ved oprettelse af objekter af de forskellige subclasses til MySuperClass fra PrimaryClass, sendes en reference (via "this") til PrimaryClass. Via denne reference kan subclasses så bruger get/set method til at tilgå den delte information.


Umiddelbar er løsning 1 jo langt den simpleste, men jeg mener at have hørt at man oftest gerne vil undgå brug af static da man mister fordele fra OOP.

1. Hvilken løsning er at foretrække, og hvorfor?
2. Hvornår vil man gerne undgå static? At dele informationer via static er vel først problematisk når objekter fra forskellige tråde skal tilgå informationen?

Skrevet fre. d. 27. august 2010 kl. 16:20:36| #1

arne_v
arne_v (1.005.623 point)
Jeg er lidt forvirret.

klasser != instanser

Du kan have 25 instanser af 7 sub klasser.

Instanser af subklasser er automatisk instanser af super klassen.

Du kan naturligvis sende en ref til en instans af klasse X over i alle subklassernes/super klassens constructor og gemme den i en instans variabel.

Skrevet fre. d. 27. august 2010 kl. 16:34:01| #2

amews_aj
amews_aj (21.175 point)
www.amews.net
klasser != instanser
Nej, hvor mener du da jeg siger det?

Altså jeg mener, jeg kan jo i superklassen lave en statisk variabel, og dermed tilgå denne fra subklasserne. Således vil alle instanser heraf kunne tilgå samme information.
Ellers, kunne jeg i en særskilt klasse (Primary) oprette en privat instansvariabel, og sende en reference med når jeg fra Primary opretter instanser af andre selvstændige klasser. Dermed kan de tilgå fælles information via set/get metoder i Primary klassen. Derved undgås brug af statiske variabler.

Bemærk Primary er selvstændig, og ikke sub/superklasse til nogen af de andre klasser.

Skrevet fre. d. 27. august 2010 kl. 16:39:03| #3

arne_v
arne_v (1.005.623 point)
Det er meget bedre at sende en ref over i constructors.

Skrevet fre. d. 27. august 2010 kl. 16:40:18| #4

arne_v
arne_v (1.005.623 point)
At gemme i en static i super klassen synes jeg kun giver mening, hvis der kun er 1 instans af hver klasse.

Skrevet fre. d. 27. august 2010 kl. 16:46:50| #5

amews_aj
amews_aj (21.175 point)
www.amews.net
1.Kan du uddybe mere hvorfor det er bedre? Hvad er det dårlige ved at bruge en statisk variabel?
2.Hvorfor skulle det ikke give mening ved flere instanser/objekter af hver klasse?

Skrevet fre. d. 27. august 2010 kl. 17:51:03| #6

arne_v
arne_v (1.005.623 point)
Du har grundliggende en model hvor en instans af en "holder klasse" refererer til M instanser af subklasser til en bestemt klasse.

Saa laengde der kun er 1 instans af "holder klassen", saa vil det at gemme noget static passe med modellen, men faar du mere end en instans af den, saa giver static en anden funktionalitet.

Skrevet fre. d. 27. august 2010 kl. 17:53:26| #7

arne_v
arne_v (1.005.623 point)
Jeg tror saa at det vil vaere paenere at have en separat klasse X til data og have en ref til den i "holder klasse" instansen og sende den med over til instanserne af subklasserne fremfor at sende en ref til instansen af "holder klassen" selv med over.

Det vil bl.a. goere det nemmere at unit teste.

Skrevet fre. d. 27. august 2010 kl. 18:06:02| #8


Skrevet søn. d. 29. august 2010 kl. 04:12:51| #9

arne_v
arne_v (1.005.623 point)
Prøv og kør disse her to programmer og se hvilken du synes giver bedst mening:


import java.util.ArrayList;
import java.util.List;

public class WrongWay {
    public static void main(String[] args) {
        WWHolder a = new WWHolder("AAA");
        System.out.println("AAA:");
        a.print();
        WWHolder b = new WWHolder("BBB");
        System.out.println("BBB:");
        b.print();
        System.out.println("AAA again:");
        a.print();
    }
}

class WWHolder {
    public static String magic;
    private List<WWP> lst;
    public WWHolder(String s) {
        magic = s;
        lst = new ArrayList<WWP>();
        lst.add(new WWC1());
        lst.add(new WWC2());
    }
    public void print() {
        for(WWP o : lst) {
            o.print();
        }
    }
}

abstract class WWP {
    public abstract void print();
}

class WWC1 extends WWP {
    @Override
    public void print() {
        System.out.println("I am a C1 in " + WWHolder.magic);
    }
}

class WWC2 extends WWP {
    @Override
    public void print() {
        System.out.println("I am a C2 in " + WWHolder.magic);
    }
}



import java.util.ArrayList;
import java.util.List;

public class RightWay {
    public static void main(String[] args) {
        RWHolder a = new RWHolder("AAA");
        System.out.println("AAA:");
        a.print();
        RWHolder b = new RWHolder("BBB");
        System.out.println("BBB:");
        b.print();
        System.out.println("AAA again:");
        a.print();
    }
}

class RWHolder {
    private String magic;
    private List<RWP> lst;
    public RWHolder(String s) {
        magic = s;
        lst = new ArrayList<RWP>();
        lst.add(new RWC1(this));
        lst.add(new RWC2(this));
    }
    public void print() {
        for(RWP o : lst) {
            o.print();
        }
    }
    public String getMagic() {
        return magic;
    }
}

abstract class RWP {
    public abstract void print();
}

class RWC1 extends RWP {
    private RWHolder h;
    public RWC1(RWHolder h) {
        this.h = h;
    }
    @Override
    public void print() {
        System.out.println("I am a C1 in " + h.getMagic());
    }
}

class RWC2 extends RWP {
    private RWHolder h;
    public RWC2(RWHolder h) {
        this.h = h;
    }
    @Override
    public void print() {
        System.out.println("I am a C2 in " + h.getMagic());
    }
}

Skrevet søn. d. 29. august 2010 kl. 13:04:05| #10

amews_aj
amews_aj (21.175 point)
www.amews.net
Jeg kan godt se din pointe, men i det tilfælde jeg bruger det kan jeg ikke helt se ulempen.

Prøver lige at forklare det lidt mere, inden jeg evt. skriver koden (hvis du vil have den, så sig til).

Altså, vi har en World, som opretter flere instanser af Player.
Player er en subclass af Actor, og indeholder en statisk variabel static int team1Score, team2Score.
Når en Player scorer, opdateres scoren ved dens tilhørende team ved at bruge den statiske varibel i superklassen.
Når spillet er ovre kan scoren aflæses.

Her er jo ikke tale om kald fra World der opdaterer den statiske variabel, og situationer som den du demonstrerede vil jo ikke finde sted.
Er der noget galt i her at anvende en statisk variabel? I så fald hvorfor?

PS: Det er vel korrekt at en statisk variabel der skal bruges i subklassen skal være protected ?

Skrevet søn. d. 29. august 2010 kl. 14:59:45| #11

arne_v
arne_v (1.005.623 point)
Det lyder som en endnu større katastrofe end det eksempel jeg lavede.

Men inden jeg bixer et nyt eksempel som muligvis heller ikke passer med din kode - kan du så ikke lige outline din klasse struktur lidt bedre.

"Player er en subclass af Actor"

og

"Når en Player scorer, opdateres scoren ved dens tilhørende team ved at bruge den statiske varibel i superklassen."

synes jeg virker inkonsistente.

Skrevet søn. d. 29. august 2010 kl. 15:18:05| #12

amews_aj
amews_aj (21.175 point)
www.amews.net
Ikke lige det bedste kodeeksempel, men prøv at se på dette:


public class MyTest {
    public static void main(String[] args) {
        MySubClass player1 = new MySubClass(1);
        MySubClass player2 = new MySubClass(1);
        MySubClass player3 = new MySubClass(2);
        MySubClass player4 = new MySubClass(2);

        player1.incrementScore();
        player2.incrementScore();
        player3.incrementScore();

    }
}

class MySuperClass {
    static int team1score = 0;
    static int team2score = 0;

    public MySuperClass() {

    }

    public int getScore(int team) {
        if ( team == 1 ) return team1score;
        else return team2score;
    }
   

}

class MySubClass extends MySuperClass {
    private int team;


    public MySubClass(int team) {
        this.team = team;
    }
   
    public void incrementScore() {
        if ( team == 1 ) team1score++;
        else team2score++;
       
        System.out.println(&quot;New score team &quot; + team + &quot;: &quot; + getScore(team));

    }
}

Skrevet søn. d. 29. august 2010 kl. 15:18:51| #13

amews_aj
amews_aj (21.175 point)
www.amews.net
Og så har eksperten erstattet " med &quot; - men det kan du vel let se...

Skrevet søn. d. 29. august 2010 kl. 15:23:34| #14

arne_v
arne_v (1.005.623 point)
Der er to ting galt med den model:

1) Spiller (MySubClass) er ikke en sub klasse til Kamp (MySuperClass).

2) Brugen af static gør at du ikke kan håndtere mere end en kamp korrekt, hvilket er præcis det samme problem som mit eksempel illustrerede.

Skrevet søn. d. 29. august 2010 kl. 15:34:36| #15

amews_aj
amews_aj (21.175 point)
www.amews.net
1. MySubClass er der subklasse til MySuperClass.
class MySubClass extends MySuperClass {...}

2. Nej korrekt, hvis man oprettede flere kampe på en gang, ville det gå galt. Men så længe det ikke er meningen er der så noget galt? Der er selvfølgelig det galt at man mister muligheden for flere kampe, hvilket vel netop er den stærke side ved at anvende OOP...

3. Egentlig kan man vel også sige at det er forkert at lade superklassen for players holde styr på scoren? I hvert fald ved denne struktor

MainClass ----- &gt;  Games                    Players
                    /_\                    /_\  /_\
                    |                      |    |
                    |                      |    |
                  Game ------- &gt; PlayerType1    |
                      \------------------------ &gt; PlayerType2

Det er jo ikke Players der skal holde styr på scoren i spillet, men vel den enkelte Game-instans? Derfor bør de enkelte playere vel kalde en metode i Game (via reference sendt via constructor), som opdaterer en score gemt i Game?
Ved ikke om det er forståeligt?

Skrevet søn. d. 29. august 2010 kl. 15:35:26| #16

amews_aj
amews_aj (21.175 point)
www.amews.net
/_\ = nedarver
>  = anvendelse

Skrevet søn. d. 29. august 2010 kl. 15:37:09| #17

arne_v
arne_v (1.005.623 point)
re 1)

Ja - jeg kan godt se at du har brugt extends, men sådan forholder det sig ikke i virkeligheden. Ens objekt model skal modelere virkeligheden.

Skrevet søn. d. 29. august 2010 kl. 15:38:39| #18

amews_aj
amews_aj (21.175 point)
www.amews.net
Hvad mener du med det?

Skrevet søn. d. 29. august 2010 kl. 15:38:58| #19

arne_v
arne_v (1.005.623 point)
re 2)

Jeg har lidt svært ved at se noget software der på langt sigt kun skal understøtte 1 kamp. Det holder ikke.

Skrevet søn. d. 29. august 2010 kl. 15:40:43| #20

amews_aj
amews_aj (21.175 point)
www.amews.net
Nej præcis. Nu er dette en eksempel-øvelsesopgave, og derfor er det ikke meningen det skal kunne mere, men ja i den virkelige verden - på længere sigt - vil det jo ikke holde. Skal jo netop sørge for fleksibiliteten..

Skrevet søn. d. 29. august 2010 kl. 15:41:14| #21

arne_v
arne_v (1.005.623 point)
Så vidt jeg kan se skal du have:

Kamp
Hold
Spiller

klasser.

En kamp indeholder to hold.

Et hold indeholder 11 spillere (hvis fodbold andet antal hvis noget andet).

Jeg tror at jeg ville putte score metoden i Kamp klassen med en Spiller som argument.

Skrevet søn. d. 29. august 2010 kl. 15:41:55| #22

arne_v
arne_v (1.005.623 point)
NB: Har du overvejet selvmål ?  (det gør spiller -> resultat lidt mere grumset !)

Skrevet søn. d. 29. august 2010 kl. 15:45:11| #23

amews_aj
amews_aj (21.175 point)
www.amews.net
(4)

Ja, præcis. Som i ovenstående eksempel vel i Game klassen, da man kan forestille sig flere forskellige subclasses af Games (Forskellige spil).
I Player giver det i hvert fald næppe mening.

(5)
Dog hvis der er tale om spil hvor hver spiller bidrager med en score, så kunne man vel også gemme en lokal score i hver spiller, og hente denne score fra Game klassen, og eksempelvis addere resultatet. Men (4) er vel stadig en væsentlig mere fleksibel løsning?

Skrevet søn. d. 29. august 2010 kl. 15:45:51| #24

amews_aj
amews_aj (21.175 point)
www.amews.net
(6)
Hvad mener du for øvrigt med "Jeg tror at jeg ville putte score metoden i Kamp klassen med en Spiller som argument. "
Spiller som argument?

Skrevet søn. d. 29. august 2010 kl. 16:29:21| #25

arne_v
arne_v (1.005.623 point)
At jeg tror mere på:

enInstansAfKamp.score(enInstansAfPlayer);

end:

enInstansAfPlayer.score(enInstansAfKamp);

Skrevet søn. d. 29. august 2010 kl. 16:30:07| #26

arne_v
arne_v (1.005.623 point)
Selvom det kun er en øvelse, så tror jeg at du skal undgå de static. Det er kun problemer.

Skrevet søn. d. 29. august 2010 kl. 17:49:39| #27

amews_aj
amews_aj (21.175 point)
www.amews.net
Ja, så du vil altså:
1. have scoren som en private variabel i Kamp-klassen
2. Give reference til "this" med når Player's oprettes fra Kamp-klassen (altså sende reference til kampklassen med som argument ved kald af constructor)
3. Når score skal opdateres, kalde en mutator metode i Kamp-klassen vha. referencen til Kamp-klassen. ala enInstansAfKamp.score(enInstansAfPlayer);

Har jeg forstået dig rigtigt?
Vil du mene det er den optimale løsning?
Ligeledes metoder som end-game osv. skal vel styres af Kamp-klassen..?

PS: HVIS (hvilket jeg ikke længere har tænkt mig) man bruger statiske variabler til dette, er det så ikke korrekt at en statisk variabel der skal bruges i subklassen skal være protected ? Private er jo for beskyttet, og public er vel for åben.

Skrevet ons. d. 01. september 2010 kl. 02:53:06| #28

arne_v
arne_v (1.005.623 point)
re 1)

yes - to private int

re 2)

jeg vil mene at spillere er tilknyttet et hold og at to hold tilknyttes en kamp

re 3)

ja

re PS)

ja

Skrevet fre. d. 17. september 2010 kl. 20:34:32| #29

amews_aj
amews_aj (21.175 point)
www.amews.net
Har haft meget travlt i den sidste tid, så helt glemt at svare tilbage her.

Tak for din tid og forklaring.
Smid et svar :)

Skrevet fre. d. 17. september 2010 kl. 20:38:15| #30

arne_v
arne_v (1.005.623 point)
kommer her

Skriv et indlæg




Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] [img]link til billede[/img]
Web- og emailadresser omdannes automatisk til links

Log ind

   

   

Seneste spørgsmål

Gentegne JPanel ved tryk på JButton

Oprettet den 8. februar 2012 kl. 22.15
odsgaard giver 30 point for svar | Giv et svar »

Eksempel på kommunikation med webserver

Oprettet den 7. februar 2012 kl. 09.23
larsande giver 30 point for svar | Giv et svar »

Java JDK compiler til BlueJ

Oprettet den 3. februar 2012 kl. 14.26
andersmnielsen giver 60 point for svar | Giv et svar »

Seneste guides

Installer win 7
Den gode bruger


   




Tips & Tricks fra PC World

Teaser billede

Her er fem sjove danske websider du skal kende

Trænger dine lattermuskler til en omgang fitness på dansk? Vi viser vej til fem websider fyldt med humor og vanvittig satire.


Anmeldelser fra PC World

Teaser billede

Test: Denne super-tablet er iPads hårdeste konkurrent

Eee Pad Transformer Prime er frygtindgydende med sin quadcore processor og evne til at trylle sig om til bærbar. Apple bør kigge i bagspejlet, for Asus' tablet-pc kommer buldrende - og gør det...


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Nu kan du snart hente Windows 8

Den nye offentlige betaversion af Windows 8 er klar i denne måned.


Nyheder fra Computerworld

Teaser billede

Måske snart slut med Androids helt store problem

Android-platformen har længe været plaget af et særligt problem. Men måske er problemet nu ved at være elimineret.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger