2011-05-01 58 views
2

我可以访问子类的子类的静态变量吗?我不想实例化它,只是想获取变量,因为它已经被子类初始化了。AS3的子类的引用子类没有实例化?

例如:

package 
{ 
    public class A extends MovieClip { 
     private var classB:B = new B(); 

     public function A() { 
      //**ACCESS B.C.MYVAR** 
     } 
    } 
} 

package 
{ 
    public class B extends MovieClip { 
     private var classC:C = new C(); 
    } 
} 

package 
{ 
    public class C extends MovieClip { 

     public static var MYVAR = 1; 
    } 
} 

谢谢!

回答

1

要访问一个公共静态 var你可以通过Class.property在同一个包中的任何地方这样做。

因此,要访问C类中定义的MYVAR,您可以使用C.MYVAR。

您不需要创建一个类的实例来访问它中的静态属性或函数 - 只要它们是公共的。

我不建议使用静态,但在极少数情况下,例如“工具”类或类似的东西。一个很好的例子是内置的Math类。

我在保持常量,像这样的例子一类主要是使用静态:

package 
{ 
    public class Elements 
    { 
     public static const FIRE:String = "FIRE_ELEMENT"; 
     public static const WATER:String = "WATER_ELEMENT"; 
     public static const ICE:String = "ICE_ELEMENT"; 
    } 
} 

再后来我利用这个像这样:

var myelement:String = Elements.WATER; 
+0

感谢您的回答马蒂,从C调用公共变量不是静态的呢?这可能吗?我拥有的是从B发出的事件,让我知道C发生了变化,但是我需要在事件发送时从A中检索C中的变量。我希望你能理解我刚写的东西。 – 2011-05-01 11:00:26

+0

@蒂姆乔伊斯你还想在你的评论中回答这个问题吗? – Taurayi 2011-05-01 12:14:24

1

的答案已经被接受这个问题,但我的答案是回应蒂姆乔伊斯在他接受的答案评论中提出的问题:

Thanks for th e回答Marty, 关于从C调用公共变量 是不是静态的?这可能吗?我有什么 我从B 派发的事件让我知道C发生了变化,但我需要在调度事件时从A中检索C 中的变量。 男子我希望你能理解我刚写的东西 。

以下是我创建回答这个问题一个小的Flash应用程序:

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 

    public class Main extends Sprite 
    { 
     private var _popcornMicrowave:PopcornMicrowave; 

     public function Main():void 
     { 
      if (stage) init(); 
      else addEventListener(Event.ADDED_TO_STAGE, init); 

     }// end function 

     private function init(e:Event = null):void 
     { 
      removeEventListener(Event.ADDED_TO_STAGE, init); 

      // 1 minute and 30 seconds 
      var delay:Number = PopcornMicrowave.MINUTE + (PopcornMicrowave.SECOND * 30); 

      _popcornMicrowave = new PopcornMicrowave(delay); 

      trace(_popcornMicrowave.popcorn.isReady); // output: false 

      _popcornMicrowave.startTimer(); 

      _popcornMicrowave.addEventListener(Event.COMPLETE, onPopcornMicrowaveComplete); 

     }// end function 

     private function onPopcornMicrowaveComplete(e:Event):void 
     { 
      _popcornMicrowave.removeEventListener(Event.COMPLETE, onPopcornMicrowaveComplete); 

      trace(_popcornMicrowave.popcorn.isReady) // output: true 

     }// end function 

    }// end class 

}// end package 

import flash.events.Event; 
import flash.events.EventDispatcher; 
import flash.events.TimerEvent; 
import flash.utils.Timer; 

internal class PopcornMicrowave extends EventDispatcher 
{ 
    public static const SECOND:Number = 1000; 
    public static const MINUTE:Number = SECOND * 60; 

    private var _popcorn:Popcorn; 
    private var _timer:Timer; 

    public function get popcorn():Popcorn { return _popcorn } 

    public function PopcornMicrowave(delay:Number = MINUTE) 
    { 
     _popcorn = new Popcorn(); 
     _timer = new Timer(delay, 1); 

    }// end function 

    public function startTimer():void 
    { 
     if (!_timer.running) 
     { 
      _timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete); 
      _timer.start(); 

     }// end if 

    }// end function 

    private function onTimerComplete(e:TimerEvent):void 
    { 
     _timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete); 

     _popcorn.setIsReady(true); 

     dispatchEvent(new Event(Event.COMPLETE)); 

    }// end function 

}// end class 

internal class Popcorn 
{ 
    private var _isReady:Boolean; 

    public function get isReady():Boolean { return _isReady } 

    public function Popcorn() { } 

    internal function setIsReady(boolean:Boolean):void 
    { 
     _isReady = boolean 

    }// end function 

}// end class 
1

静态变量可以很容易地从任何地方引用。无论是访问其中一个子类(或子子类...)还是完全依赖于所讨论的静态变量的完全不同的类,都可以通过以下方式访问它:

现在
public function someFunction():void { 
    //Direct Access: Most typical way - accessing a public static var/const, 
    //your local-variable should match the data-type of the static 
    //variable you're accessing. 
    var localVar:String = ClassName.StaticVarName; 

    //Dynamic Access: An alternative that can be handy for verifying 
    //variables that exists, and then use them once confirmed: 
    if(ClassName["StaticVarName"]!=null) { 
    trace("Found value: " + ClassName["StaticVarName"]); 
    } 

    //Iterative Access: If you're looking to iterate through each static 
    //variables of a certain class, you can collect those by accessing its 
    //description XML document (E4X access that is). 
    var classDescription:XML = describeType(ClassName); 
    var classVarNames:XMLList = classDescription.variable.attribute("name"); 
    for each(var classVarName:String in classVarNames) { 
    trace("Found class var: " + classVarName); 
    } 
} 

,才能访问你的类层次结构埋了几级下降实例变量,你可以尝试这样的事:

// File: A.as 
package { 
    public class A { 
     public function A() { 

     } 

     public function doSomething():void { 
      switch(Object(this).constructor) { 
       case B: trace(B(this).methodOnlyInB()); break; 
       case C: trace(C(this).variableOnlyInC); break; 
       default: trace("You are simply in 'A'!"); break; 
      } 
     } 
    } 
} 

// File: B.as 
package { 
    public class B extends A { 
     public function B() { 
      super(); 
     } 

     public function methodOnlyInB():String { 
      return "You are calling a 'B' method!"; 
     } 
    } 
} 

// File: C.as 
package { 
    public class C extends B { 
     public var variableOnlyInC:String = "You are tracing a 'C' variable"; 

     public function C() { 
      super(); 
     } 
    } 
} 

// File: TestABC.as 
var a:A = new A(); 
var b:B = new B(); 
var c:C = new C(); 

a.doSomething(); //Should trace: You are simply in 'A'! 
b.doSomething(); //Should trace: You are calling a 'B' method! 
c.doSomething(); //Should trace: You are tracing a 'C' variable! 

有“问题”下得去这条路线的一个位。这会让你写“糟糕的代码”。一个超级应该不是知道它的任何子类业务,他们应该在某些条件下应该做什么。它的一条规则是,几乎所有的编程设计模式都试图鼓励(并且出于很好的理由),并且违反这个规则可能会花费大量的时间,精力和拉长头发。

像这样的情况需要“控制器”类。基本上,从其他地方实例化的类将有责任分析A/B/C对象(例如:与A.doSomething()的switch语句如何执行此操作类似)。这样可以让你的子类从混乱中解脱出来,并为扩展和实体代码留下更多空间。

希望能回答您所有的变量访问需求! :)

+1

感谢bigp。这绝对有助于我不断寻求编写更精简,有意义的代码。我将会搜索一些控制器的源代码。 – 2011-05-02 18:56:41

+0

没问题蒂姆!为了避免在疯狂追逐中(或者在这种情况下是疯狂追逐谷歌)发送你,Controller这个术语最常用于MVC设计模式,但在这种情况下,我主要是指另外一个类,负责解释“实例是A,实例是B等”。场景。这种解释也可以在单独的类中的静态方法内执行,而不一定在这个单独的类的实例方法中执行。 – bigp 2011-05-04 13:49:56