2012-03-11 2 views
4

Я только начал программировать ООП, и я столкнулся с проблемой области. В следующем проекте у меня есть masterClass под названием App. В App-классе есть экраны: экран-класс и класс навигации, так как это дети. Из класса навигации я хочу контролировать, какие экраны будут отображаться. Я не знаю, как это сделать ...Доступ к родительскому классу в правильном порядке 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. 
    } 
} 

За все это, ни на экране, ни навигации должны ничего знать о каких-либо других объектов, связанных, так что вы можете легко заменить каждый из них, не нарушая Рез t системы.

+0

wow: D это действительно уровень для меня :) Я думаю, мне придется прочитать это несколько раз, чтобы действительно понять. Ссылки об управлении инверсией и свободном соединении читаю завтра. Спасибо за этот очень полный ответ. Только один вопрос; то, что я узнал о ООП, было то, что все объекты имеют свои обязанности. Я думал, что навигация тогда будет обрабатывать ВСЕ код, который связан с навигацией. То, как я вижу это сейчас, заключается в том, что класс 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

Со всеми этими явными зависимостями в ваших дочерних классах у вас будет какое-то время, чтобы поддерживать и повторно использовать ваш код. Вы действительно хотите изучить некоторые продвинутые темы OO, особенно свободные связи: http://en.wikipedia.org/wiki/Loose_coupling and inversion of control: http://en.wikipedia.org/wiki/Inversion_of_control – weltraumpirat

+1

@weltraumpirat - Спасибо за ссылки, похоже, у меня есть кое-какие чтения :) –

+0

Спасибо за быстрый ответ! Решение легко понять :). Я также сделаю кое-что еще по этому поводу: D – SKuijers

Смежные вопросы