18. juni 2006 - 10:31Der er
8 kommentarer og 1 løsning
Uendelig løkke - hvorfor, monstro?
Hej eksperter.
Jeg arbejder på at opbygge et "vinduesmiljø" i Flash. Problemet er, at den ryger ind i en uendelig løkke.
Jeg har 2 klasser: Arkiv og Vindue + 1 index-fla-fil.
Hieraki: Arkiv -> Vindue
I index.fla står udelukkende: arkiv = new Arkiv();
I Arkiv.as har jeg bl.a. følgende metode: public function Arkiv() { // Konstruktør // Dette er variabler, der knytter sig til instancet af ARKIV trace("Arkiv oprettet"); baggrundsfarve = "FFFFFF"; baggrundsbillede = null; rammeudseende = 1; rammegennemsigtighed = 50; oploesningX = System.capabilities.screenResolutionX; oploesningY = System.capabilities.screenResolutionY; opretbaggrund(); // vinduesinitialisering(); }
...og...
public function vinduesinitialisering() { // Dette er produktoversigten var oversigt = new Vindue(); <---- Denne forårsager uendelig løkke... oversigt.librarynavn = "vis_oversigt"; oversigt.instancenavn = "visoversigt_mc"; oversigt.niveau = 100; oversigt.posX = 320; oversigt.posY = 50; oversigt.opretvindue(); // Selve VINDUET er oprettet - men vi skal også oprette en instance af produktoversigten INDENI "oversigt" - den har jo sin egen klasse //... }
Vindue.as klassen består bl.a. af følgende metode: class Vindue extends Arkiv { private var posX; private var posY; private var sizeC; private var sizeD; //...
public function opretvindue() { // Ikke en konstruktør, da librarynavn, instancenavn m.m. ikke er sat ved objektets oprettelse this.librarynavn = _root.attachMovie(this.librarynavn, this.instancenavn, this.niveau, {_x:this.posX, _y:this.posY} ); // Det oprettede vindue skal også kunne flyttes: this.librarynavn.flytteareal_mc.onPress = function() { startDrag(this._parent); } this.librarynavn.flytteareal_mc.onRelease = function() { stopDrag(); } } }
Hvad er hensigten så? Jo, index.fla opretter et objekt af Arkiv. Herefter skal et objekt af Vindue oprettes af Arkiv. vinduesinitialisering virker også - men KUN hvis "extends Arkiv" udelades. Uhensigtsmæssigheden er dog så, at objektet "oversigt" IKKE oprettes som child til objektet "arkiv"
Problemet opstår, i samme sekund, "var oversigt = new Vindue" i vinduesinitialiseringen afvikles. Følgende sker: ... Arkiv oprettet Arkiv oprettet Arkiv oprettet Arkiv oprettet Arkiv oprettet Arkiv oprettet 256 levels of recursion were exceeded in one action list. This is probably an infinite loop. Further execution of actions has been disabled in this movie.
Hvad er årsagen, monstro? Et child-objekt opretter da ikke en ny instance parent-klassen, vel? Eller er der nogle basale OOP-principper, jeg har misforstået?
Nu er jeg ikke specielt stærk i Flash, men jeg kan da se at din konstruktion vil gå galt i andre OOP sprog (som f.eks. Java eller C#).
Grunden er at konstruktøren i en underklasse altid starter med at kalde konstruktøren i superklassen.
Når du i vinduesinitialisering() har denne linje:
var oversigt = new Vindue();
betyder det at den kalder Vindue-klassens konstruktør. Dermed kaldes altså Arkiv-klassens konstruktør, og den kalder så vinduesinitialisering(). Der har du din uenelige løkke.
Synes godt om
Slettet bruger
18. juni 2006 - 12:22#2
Ahh javel, ja... :-)
Det fungerer jo bare super. Følgende er gjort:
- arkiv.opretbaggrund() og arkiv.vinduesinitialisering() kaldes fra index.fla. - Herudover er min konstruktør til Arkiv fjernet
Tak for hjælpen - og smid endelig et svar, så du kan få point.
I OOP kan et childobjekt godt få adgang til parentobjektets metoder, right? Men ikke den anden vej?
Dvs. hvis jeg har mange vinduer, vil det være mest hensigtsmæssigt at placere en metode til f.eks. vinduespositionering oppe i parent-klassen, som vinduerne så kan nå?
...og: Jeg kan ikke fra "roden" kalde f.eks. arkiv.oversigtsvindue.flytvindue(), eller?
Synes godt om
Slettet bruger
18. juni 2006 - 12:39#5
OK, det var vist lidt kaotisk beskrevet. Jeg prøver lige igen:
Hvis jeg vil kunne f.eks. flytte og reducere størrelsen på mine vinduer - hvor bør metoderne til dette ligge?
Metoder i din "parent"-klasse er tilgængelige for alle klasser der arver fra denne - ikke omvendt, det er derfor subklasser kaldes specialiseringer, og superklasser kaldes generaliseringer. :)
Hvis "flytVindue" er noget alle vinduer kan, så skal det være en metode i superklassen, hvis det er noget kun specielle "flytbare" vinduer skal kunne, skal det være en metode i den rette specialisering (subklasse).
I dit eksempel har du kun en Vindue-klasse, og den arver fra Arkiv-klassen.
I den sammenhæng er spørgsmålet uinteressant: Den funktionalitet, som objekter af Vindue-klassen skal bruge, kan lige så godt være implementeret i Arkiv- som i Vindue-klassen.
Hvis du derimod har flere forskellige typer af Vindue?-klasser, som hver især arver fra Arkiv:
class Vindue extends Arkiv { ... }
class VindueType2 extends Arkiv { ... }
class VindueType3 extends Arkiv { ... }
- så er spørgsmålet mere relevant, og svaret er:
Funktionalitet som er fælles for Vindue, VindueType2 og VindueType3 bør implementeres i Arkiv-klassen.
Funktionalitet som er helt specifik for f.eks. VindueType2-klassen skal implementeres der.
Hvis du opdager at du ender med at sidde og skrive den samme kode mere end én gang, så bør du overveje om det ikke er fordi at den i virkeligheden hører hjemme i superklassen.
Synes godt om
Slettet bruger
18. juni 2006 - 13:09#9
Cool!
Tusind tak til alle for information - den er særdeles relevant for min OOP-forståelse :D
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.