在一个面向对象的正确的方式进入一个父类面向对象、正确、方式

2023-09-09 21:47:45 作者:阳光下的温暖

我刚开始编程OOP和我遇到一个范围问题。 在接下来的项目中,我有一个名为app大师。应用程序级的有屏幕:屏幕类和导航类,因为它的孩子。在导航类我想控制它的屏幕会显示出来。我不知道如何做到这一点?

请检查code充分理解我的意图

您的帮助实在是AP preciated,我很想真正学习编程,而不是只是一个肮脏的解决方案:)但是所有的建议都欢迎!

  //主类//
公共类应用程序扩展Sprite
{
    私人VAR屏幕:阵列;
        私人VAR屏蔽1:屏幕;
        私人VAR屏蔽2:屏幕;
        私人VAR画面3:屏幕;
        私人VAR screen4:屏幕;

    公共变种currentScreen:字符串;
    //



    私人VAR导航:导航;

    公共函数应用()
    {
        在里面();
    }

    私有函数的init():无效{
        buildScreens();

        buildNavigation();
    }

    私有函数buildScreens():无效{
        屏幕截图1 =新画面();
        screen1.name =启动画面;
        currentScreen = screen1.name;
        的addChild(屏幕截图1);

        画面2 =新画面();
        screen2.name ='irrelevantA';

        画面3 =新画面();
        screen3.name ='irrelevantB';

        screen4 =新画面();
        screen4.name ='irrelevantC';


        屏幕=新阵列(屏蔽1,画面2,画面3,screen4);


    }

    私有函数buildNavigation():无效{
        导航=新的导航(屏幕);
    }
}

// Screen类//
公共类屏幕扩展Sprite
{
    公共职能屏幕()
    {
        //创建一个新的屏
    }
}


//导航类//
公共类导航扩展Sprite
{
    私人VAR按钮:数组;

    公共功能导航(画面:阵列)
    {
        addButtons(屏幕);
    }

    私有函数addButtons(画面:阵列):无效{
        按钮=新的Array();

        每个(VAR屏:屏在屏幕){
            VAR按钮:按钮=新按钮();
            button.link = screen.name;
            button.addEventListener(的MouseEvent.MOUSE_DOWN,鼠标按下);
            buttons.push(按钮);
        }
    }

    私有函数MOUSEDOWN(E:的MouseEvent):无效{
        //这是我的问题是关于:我应该如何与父类中的一个面向对象的正确方法?
        //我怎么可以添加和从这里在App类中删除屏幕?

        //这里是一些我的尝试
        //我不认为用父母那里是一个很好的,因为下一次也许是这样; parent.parent.parent
        跟踪(e.target.parent.parent.currentScreen);
        this.parent.currentScreen;
        stage.App.currentScreen;
        App.currentScreen;


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

//按钮类//
公共类按钮扩展Sprite
{
    公共变种链接:字符串;

    公共功能按钮()
    {
        //创建一个新的按钮
    }
}
 
12 面向对象 继承与多态

解决方案

如果您是直接从子对象访问父类中,创建强耦合 - 这正是你的不的希望在精心打造的系统。最好不要直接访问应用程序对象,而是利用事件侦听器和自定义的活动,以促进从例如更改导航。

下面是一个例子。首先,创建一个自定义事件:

 公共类MyCustomEvent扩展事件{

    公共静态常量MENU_ITEM_SELECTED:字符串=MENU_ITEM_SELECTED;
    公共变种将selectedItem:字符串;
}
 

那么,让导航调度它,单击一个按钮时:

 公共类导航扩展Sprite(){
    // ...
    私有函数onButtonClicked(EV:事件):无效{
        ev.stopPropagation();
        VAR custEvent:MyCustomEvent =新MyCustomEvent(MyCustomEvent.MENU_ITEM_SELECTED);
        custEvent.selectedItem = ev.target.name;
        this.dispatchEvent(custEvent);
    }
    // ...
}
 

最后,让应用程序处理自定义事件和造就了不同的画面:

 公共类应用{
    // ...
    公共职能createNavigation():无效{
        导航=新导航();
        navigation.addEventListener(MyCustomEvent.MENU_ITEM_SELECTED,onMenuItemSelected);
        // ...更多的事情发生
    }
    // ...

    私有函数onMenuItemSelected(EV:MyCustomEvent):无效{
        switchToScreen(ev.selectedItem);
    }

    私有函数switchToScreen(参数name:String):无效{
        //通过名称选择画面等
    }
}
 

有关这一切,无论是画面,还是导航必须了解所涉及的其他对象的东西,这样你就可以轻松地更换每一个,而不会破坏系统的其余部分。

I just started programming OOP and I'm running into a scope problem. In the following project, I have a masterClass called App. The App-class has Screens:Screen-class and a Navigation-class as it's children. From the navigation class I want to control which screens will be displayed. I don't know how to do this...

Please check the code to fully understand my intentions

Your help is really appreciated, I'd love to really learn programming and not just a dirty solution :) but all suggestions are welcome!

// 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
    }
}

解决方案

If you directly access parent classes from child objects, you create strong coupling - which is exactly what you don't want in a well-built system. It is best not to access the application object directly, but to use event listeners and custom events to promote changes from e.g. the navigation.

Here's an example. First, create a custom event:

public class MyCustomEvent extends Event {

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

Then, let the navigation dispatch it, when a button is clicked:

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);
    }
    // ...
}

Finally, let the application handle the custom event and bring up a different screen:

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.
    }
}

For all of this, neither the screen, nor the navigation have to know anything about any other objects involved, so you can easily replace each one without breaking the rest of the system.