2012-03-11 13 views
4

私はちょうどOOPのプログラミングを開始しましたが、私はスコープに問題があります。 次のプロジェクトでは、私は、アプリケーションと呼ばれるmasterClassを持っています。 AppクラスにはScreenクラスがあり、ScreenクラスとNavigationクラスが子クラスになっています。ナビゲーションクラスから、どの画面を表示するかを制御したい。私はこれを行う方法を知っている...あなたの助けが本当に高く評価されOOPで親クラスにアクセスする正しい方法

完全に私の意図を理解することが

をコードを確認してください、私は本当にただ汚いソリューションをプログラミングしていない学ぶことを愛するかもしません。 )しかし、すべての提案は大歓迎です!パブリック関数を呼び出すことにより、あなたは基本的に(あなたがスクリーン配列でやっているように)引数として参考文献に渡すことで、下向きに(子の親を)伝えたい

// Main Class // 
public class App extends Sprite 
{ 
    private var screens:Array; 
     private var screen1:Screen; 
     private var screen2:Screen; 
     private var screen3:Screen; 
     private var screen4:Screen; 

    public var currentScreen:String; 
    // 



    private var navigation:Navigation; 

    public function App() 
    { 
     init(); 
    } 

    private function init():void { 
     buildScreens(); 

     buildNavigation(); 
    } 

    private function buildScreens():void { 
     screen1 = new Screen(); 
     screen1.name = 'startScreen'; 
     currentScreen = screen1.name; 
     addChild(screen1); 

     screen2 = new Screen(); 
     screen2.name = 'irrelevantA'; 

     screen3 = new Screen(); 
     screen3.name = 'irrelevantB'; 

     screen4 = new Screen(); 
     screen4.name = 'irrelevantC'; 


     screens = new Array(screen1, screen2, screen3, screen4); 


    } 

    private function buildNavigation():void { 
     navigation = new Navigation(screens); 
    } 
} 

// Screen Class // 
public class Screen extends Sprite 
{ 
    public function Screen() 
    { 
     // creates a new screen 
    } 
} 


// Navigation Class // 
public class Navigation extends Sprite 
{ 
    private var buttons:Array; 

    public function Navigation(screens:Array) 
    { 
     addButtons(screens); 
    } 

    private function addButtons(screens:Array):void { 
     buttons = new Array(); 

     for each(var screen:Screen in screens) { 
      var button:Button = new Button(); 
      button.link = screen.name; 
      button.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown); 
      buttons.push(button); 
     } 
    } 

    private function mouseDown(e:MouseEvent):void { 
     // THIS IS WHAT MY QUESTION IS ABOUT: How should I talk to the parent class in an OOP correct way? 
     // and how can I add and remove a screen in the App class from here? 

     // Here some of my tries 
     // I don't think using parent to get there is a good way because next time it might be; parent.parent.parent 
     trace(e.target.parent.parent.currentScreen); 
     this.parent.currentScreen; 
     stage.App.currentScreen; 
     App.currentScreen; 


     //--------------------------------- 
    } 
} 

// Button Class // 
public class Button extends Sprite 
{ 
    public var link:String; 

    public function Button() 
    { 
     // creates a new button 
    } 
} 

答えて

7

子オブジェクトから親クラスに直接アクセスする場合は、強力な結合を作成します。これは正確にはではありません。適切なシステムではが必要です。アプリケーションオブジェクトに直接アクセスするのではなく、イベントリスナーやカスタムイベントを使用して、変更をたとえばナビゲーション。

例を示します。ボタンがクリックされたときに、ナビゲーションの発送にそれを聞かせて、その後

public class MyCustomEvent extends Event { 

    public static const MENU_ITEM_SELECTED : String = "MENU_ITEM_SELECTED"; 
    public var selectedItem:String; 
} 

public class Navigation extends Sprite() { 
    // ... 
    private function onButtonClicked(ev:Event) : void { 
     ev.stopPropagation(); 
     var custEvent:MyCustomEvent = new MyCustomEvent(MyCustomEvent.MENU_ITEM_SELECTED); 
     custEvent.selectedItem = ev.target.name; 
     this.dispatchEvent (custEvent); 
    } 
    // ... 
} 

最後に、アプリケーションはカスタムイベントを処理し、異なる画面を立ち上げてみましょうまず、カスタムイベントを作成します:

public class App { 
    // ... 
    public function createNavigation() : void { 
     navigation = new Navigation(); 
     navigation.addEventListener (MyCustomEvent.MENU_ITEM_SELECTED, onMenuItemSelected); 
     // ... more stuff happening 
    } 
    // ... 

    private function onMenuItemSelected (ev:MyCustomEvent) : void { 
     switchToScreen (ev.selectedItem); 
    } 

    private function switchToScreen (name:String) : void { 
     // choose screen by name, etc. 
    } 
} 
このすべてのために

、どちらの画面で、またナビゲーションは関与その他のオブジェクトについて何を知っている必要がありますので、あなたは簡単に解像度を壊すことなく、それぞれを置き換えることができますシステムの

+0

うわー:これは本当に私にとってレベルアップです:)私は本当に理解するためにこれを数回読まなければならないと思います。私は明日読んでいます反転制御と緩いカップリングについてのリンク。この非常に完全な答えをありがとう。 ただ1つの質問です。私がOOPについて学んだのは、すべてのオブジェクトにはそれぞれ独自の責任があるということでした。私はナビゲーションが次にナビゲートしているすべてのコードを処理すべきだと考えました。私が今見ているのは、Appクラスが実際にナビゲーションの一部を実際に行っているということです。それとも間違っているのですか? ありがとうございます! – SKuijers

+0

申し訳ありませんが、私は私の皿の上にたくさんありましたが、これに答えることを完全に忘れました...あなたはそれをこのように見なければなりません:この例のナビゲーションは、ほんの一束のボタンです。ユーザーのマウスクリックを処理し、クリックされた内容をアプリケーションに通知します。実際にアプリケーションの状態を変更するのは、アプリケーション自体(または専用のコントローラコンポーネントですが、これは別の話です)の責任です。 – weltraumpirat

+0

この回答は大きなリードのように見えますが、私は詳細を持ってほしかったです。 Flashで複雑なナビゲーションシステムを構築する方法に関する有益な記事を見つけることがどれほど難しいかは信じられません。 – Noahdecoco

0

と上向きに(親の子)。

ので、このようなあなたの場合、何かに:

のAppクラス:

private function buildNavigation():void { 
    navigation = new Navigation(this, screens); 
} 
//etc 
public function changeScreen(newScreen:int):void{ 
    //Your logic for adding/removing screens goes here 
} 

ナビゲーションクラス:明らかに

private var app:App 

public function Navigation(app:App, screens:Array) 
    { 
     this.app = app 
     addButtons(screens); 
    } 

    private function addButtons(screens:Array):void { 
     buttons = new Array(); 

     for each(var screen:Screen in screens) { 
      var button:Button = new Button(); 
      button.link = screen.name; 
      button.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown); 
      buttons.push(button); 
     } 
    } 

    private function mouseDown(e:MouseEvent):void { 
     app.changeScreens(2); 
    } 
} 

、例えば(あなたのニーズに合わせて実装を変更、 Appクラスへの参照があるので、スクリーン配列への別の参照を渡す必要があるかどうかを検討してください)。これは、あなたがどのように通信できるかの例に過ぎません。

+3

子クラスに明示的な依存関係がある場合は、コードを維持して再利用することが大切です。あなたは本当にいくつかの先進的なオブジェクト指向のトピックに見てみたい、特に疎結合:http://en.wikipedia.org/wiki/Loose_couplingと制御の反転:http://en.wikipedia.org/wiki/Inversion_of_control – weltraumpirat

+1

@weltraumpirat - リンクをありがとう、私はいくつかの読書を持っているように見えます:) –

+0

クイック応答ありがとう!ソリューションは理解しやすいです:)。 D – SKuijers

関連する問題