2008-10-15 36 views
44

Làm thế nào để bạn có được một thể hiện của lớp ActionScript Class từ một thể hiện của lớp đó?Làm thế nào để tôi nhận được từ một thể hiện của một lớp đối tượng Class trong ActionScript 3?

Trong Python, đây sẽ là x.__class__; trong Java, x.getClass();.

Tôi biết rằng certain terrible hacks tồn tại để thực hiện việc này, nhưng tôi đang tìm kiếm một cơ sở ngôn ngữ được xây dựng sẵn, hoặc ít nhất là một thói quen thư viện được xây dựng trên một cái gì đó đáng tin cậy.

Trả lời

69

Bạn có thể lấy nó thông qua thuộc tính 'hàm tạo' của lớp Object cơ sở. tức là:

var myClass:Class = Object(myObj).constructor; 
+0

Theo tôi biết đó là đá quý của riêng tôi, mặc dù tài liệu Adobe cho lớp Object đề cập đến thuộc tính hàm tạo và nó là gì. Tôi chưa bao giờ thấy nó được sử dụng theo cách đó ở bất cứ nơi nào khác. – Gerald

+1

Một số cuộc thảo luận khác tại đây: http://joshblog.net/2009/05/11/retrieve-the-class-used-to-instantiate-an-object-in-as3/ Một giải pháp thay thế nhỏ sẽ là làm: var classRef: Class = myObj ["constructor"] làm Class; Điều này cũng được thực hiện kiểm tra trình biên dịch nghiêm ngặt. Không chắc chắn cái nào hoạt động tốt hơn. phòng tương tự – mikechambers

+6

Điều này không hoạt động trên các đối tượng phân lớp Proxy, chẳng hạn như XML. Xem câu trả lời này - http://stackoverflow.com/questions/468925/in-actionscript3-how-do-you-get-a-reference-to-an-objects-class/472300#472300 –

14

Bất kỳ lý do nào bạn không thể thực hiện việc này?

var s:Sprite = new flash.display.Sprite(); 

var className:String = flash.utils.getQualifiedClassName(s); 
var myClass:Class = flash.utils.getDefinitionByName(className) as Class; 

trace(className); // flash.display::Sprite 
trace(myClass); // [class Sprite] 

var s2 = new myClass(); 
trace(s2); // [object Sprite] 

Tôi không biết cách nào để tránh làm tròn thông qua Chuỗi, nhưng nó sẽ hoạt động tốt.

+2

Điều này sẽ hiệu quả, nhưng hiệu suất cho getQualifiedClassName và getDefinitionByName là khá kém. phòng tương tự – mikechambers

14

Câu trả lời được chấp nhận (và hiện phổ biến nhất) có một số sai sót. Câu trả lời phục vụ cho trường hợp sử dụng cụ thể này, nhưng các bình luận đã mở rộng câu trả lời cho một giải pháp có vẻ chung chung.

Nhưng đây không phải là giải pháp an toàn loại trong một số trường hợp nhất định và không giải quyết tất cả các đối tượng có thể. Ý tưởng cho rằng XML không được hỗ trợ đã được giải quyết tốt ở đây và ở nơi khác, nhưng ý tưởng an toàn kiểu thì không.

Giả thiết được thực hiện là nó là đối tượng lớp được tạo bởi lập trình viên. Dưới đây là một số thử nghiệm mà tôi đã thiết lập (điều này ở chế độ nghiêm ngặt, nhưng một thử nghiệm cục bộ). Lưu ý các kết quả int kiểm tra:

var sprite:Sprite = new Sprite(); 
var xml:XML = new XML(); 
var testInt:int = 2; 
var testClass:TestClass = new TestClass(); 
var testAnon:Object = {}; 

trace("classname 1 = " + getQualifiedClassName(sprite)); 
trace("myclass 1 = " + getDefinitionByName(getQualifiedClassName(sprite))); 
trace("constructor a 1 = " + Object(sprite).constructor); 
trace("constructor a 1 = " + (Object(sprite).constructor as Class)); 
trace("constructor b 1 = " + sprite["constructor"]); 
trace("constructor b 1 = " + (sprite["constructor"] as Class)); 
trace("..."); 
trace("classname 2 = " + getQualifiedClassName(xml)); 
trace("myclass 2 = " + getDefinitionByName(getQualifiedClassName(xml))); 
trace("constructor a 2 = " + Object(xml).constructor); 
trace("constructor a 2 = " + (Object(xml).constructor as Class)); 
trace("constructor b 2 = " + xml["constructor"]); 
trace("constructor b 2 = " + (xml["constructor"] as Class)); 
trace("..."); 
trace("classname 3 = " + getQualifiedClassName(testInt)); 
trace("myclass 3 = " + getDefinitionByName(getQualifiedClassName(testInt))); 
trace("constructor a 3 = " + Object(testInt).constructor); 
trace("constructor a 3 = " + (Object(testInt).constructor as Class)); 
trace("constructor b 3 = " + testInt["constructor"]); 
trace("constructor b 3 = " + (testInt["constructor"] as Class)); 
trace("..."); 
trace("classname 4 = " + getQualifiedClassName(testClass)); 
trace("myclass 4 = " + getDefinitionByName(getQualifiedClassName(testClass))); 
trace("constructor a 4 = " + Object(testClass).constructor); 
trace("constructor a 4 = " + (Object(testClass).constructor as Class)); 
trace("constructor b 4 = " + testClass["constructor"]); 
trace("constructor b 4 = " + (testClass["constructor"] as Class)); 
trace("..."); 
trace("classname 5 = " + getQualifiedClassName(testAnon)); 
trace("myclass 5 = " + getDefinitionByName(getQualifiedClassName(testAnon))); 
trace("constructor a 5 = " + Object(testAnon).constructor); 
trace("constructor a 5 = " + (Object(testAnon).constructor as Class)); 
trace("constructor b 5 = " + testAnon["constructor"]); 
trace("constructor b 5 = " + (testAnon["constructor"] as Class)); 
trace("..."); 

Với TestClass định nghĩa là:

package 
{ 
    public class TestClass 
    { 
    } 
} 

Kết quả:

classname 1 = flash.display::Sprite 
myclass 1 = [class Sprite] 
constructor a 1 = [class Sprite] 
constructor a 1 = [class Sprite] 
constructor b 1 = [class Sprite] 
constructor b 1 = [class Sprite] 
... 
classname 2 = XML 
myclass 2 = [class XML] 
constructor a 2 = 
constructor a 2 = null 
constructor b 2 = 
constructor b 2 = null 
... 
classname 3 = int 
myclass 3 = [class int] 
constructor a 3 = [class Number] 
constructor a 3 = [class Number] 
constructor b 3 = [class Number] 
constructor b 3 = [class Number] 
... 
classname 4 = src::TestClass 
myclass 4 = [class TestClass] 
constructor a 4 = [class TestClass] 
constructor a 4 = [class TestClass] 
constructor b 4 = [class TestClass] 
constructor b 4 = [class TestClass] 
... 
classname 5 = Object 
myclass 5 = [class Object] 
constructor a 5 = [class Object] 
constructor a 5 = [class Object] 
constructor b 5 = [class Object] 
constructor b 5 = [class Object] 
... 

Ngoài bất kỳ thử nghiệm hiện tại, có lý do khá tốt để sử dụng getDefinitionByName qua constructor phương pháp. Phương pháp getDefinitionByName phép:

  • Adobe để phát triển các giải pháp nội bộ cho (hiện tại và tương lai) khu vực có vấn đề
  • bạn sẽ không cần phải thay đổi mã của bạn cho sự phát triển Adobe tương lai
  • bạn không cần phải phát triển hai (hoặc nhiều hơn) các phương thức riêng biệt của thuyết trình động.

Nó có thể chậm hơn bây giờ, nhưng trong tương lai có thể có những cải thiện từ phía Adobe sẽ giải quyết vấn đề tốc độ.

(Ví dụ, nó được sử dụng để được rằng uint là xa chậm hơn trong cho-vòng hơn int, vì vậy rất nhiều mã chuyển đổi đã được thiết lập để sử dụng nhanh hơn int. Đó là một vấn đề khá đơn giản để giải quyết, vì vậy Adobe cố định nó, và bây giờ có rất nhiều mã nhảy qua một số vòng không cần thiết để đạt được một mục tiêu đã lỗi thời.)

Vì phương pháp getDefinitionByName hoạt động chính xác trong mọi trường hợp, mã nên được phát triển bằng phương pháp đó và sau đó làm việc để Adobe sửa lỗi tốc độ.

Các vấn đề liên quan