2008-08-10 27 views
5

Những gì tôi muốn làm là một cái gì đó như sau:Có thể thêm hành vi vào lớp ActionScript 3 không động mà không kế thừa lớp không?

FooClass.prototype.method = function():String 
{ 
    return "Something"; 
} 

var foo:FooClass = new FooClass(); 
foo.method(); 

Đó là để nói, tôi muốn mở rộng một lớp được tạo ra với một phương pháp duy nhất, không thông qua thừa kế nhưng qua nguyên mẫu.

Lớp được tạo từ WSDL, đây không phải là lớp động và tôi không muốn chạm vào mã được tạo vì nó sẽ bị ghi đè.

Ngắn câu chuyện ngắn, tôi muốn có sự tương đương về mặt đạo đức với các phương pháp mở rộng C# 3: s cho AS3.

Chỉnh sửa: Tôi chấp nhận câu trả lời của aib, vì nó phù hợp với những gì tôi yêu cầu nhất - mặc dù sau đó phản ánh nó không thực sự giải quyết được vấn đề của tôi, nhưng đó là lỗi của tôi khi đặt câu hỏi sai. :) Ngoài ra, upmods cho những gợi ý tốt.

+0

@aib đúng, tôi đã phạm sai lầm khi tôi thử nghiệm. Tôi quên rằng các mẫu thử nghiệm chỉ có thể truy cập trên lớp và không phải trên mỗi đối tượng, vì vậy đối với tôi, tôi có lỗi thời gian chạy. Tuy nhiên, giải pháp wrapper của tôi không phải là phân lớp, nó đang gói. Lớp wrapper chỉ mở rộng bản gốc để nó có cùng kiểu. – Theo

Trả lời

3

Có, một điều như vậy là có thể.

Thực tế, ví dụ của bạn rất gần với giải pháp.

Hãy thử

foo["method"](); 

thay vì

foo.method(); 
1

@aib là tiếc không chính xác. Giả sử chế độ nghiêm ngặt (chế độ trình biên dịch mặc định) không thể sửa đổi nguyên mẫu của các loại lớp không động trong ActionScript 3. Tôi thậm chí không chắc chắn rằng nó có thể ở chế độ không nghiêm ngặt.

Đang bao gồm tùy chọn? Về cơ bản bạn tạo ra một lớp mà có một trong những đối tượng mà bạn nhận được từ các dịch vụ web và chỉ chuyển tiếp tất cả các phương pháp các cuộc gọi đến đó, nhưng cũng có phương pháp riêng của mình:

public class FooWrapper extends Foo { 

    private var wrappedFoo : Foo; 

    public function FooWrapper(foo : Foo) { 
     wrappedFoo = foo; 
    } 

    override public function methodFromFoo() : void { 
     wrappedFoo.methodFromFoo(); 
    } 

    override public function anotherMethodFromFoo() : void { 
     wrappedFoo.anotherMethodFromFoo(); 
    } 

    public function newMethodNotOnFoo() : String { 
     return "Hello world!" 
    } 

} 

Khi bạn muốn làm việc với một Foo, nhưng cũng có phương pháp bổ sung mà bạn cần bạn quấn ví dụ Foo trong một FooWrapper và làm việc với đối tượng đó thay thế. Đây không phải là giải pháp thuận tiện nhất, có rất nhiều đánh máy và nếu thay đổi mã được tạo ra, bạn phải thay đổi lớp FooWrapper bằng tay, nhưng trừ khi bạn có thể sửa đổi mã được tạo để bao gồm phương pháp bạn muốn hoặc thực hiện các lớp học năng động, tôi không thấy làm thế nào nó có thể được thực hiện.

Một giải pháp khác là thêm một bước vào quy trình xây dựng của bạn để sửa đổi nguồn của các lớp được tạo. Tôi cho rằng bạn đã có một bước để tạo mã từ một WSDL, vì vậy những gì bạn có thể làm là thêm một bước sau đó chèn các phương thức mà bạn cần.

4

@Theo: Làm thế nào bạn có thể giải thích sự làm việc tiếp theo trong 3.0.0.477 với mặc định flex-config.xml (< nghiêm ngặt > đúng </nghiêm ngặt >) và thậm chí là một tham số -compiler.strict truyền cho mxmlc?

Foo.as:

package 
{ 
    public class Foo 
    { 
     public var foo:String; 

     public function Foo() 
     { 
      foo = "foo!"; 
     } 
    } 
} 

footest.như:

package 
{ 
    import flash.display.Sprite; 

    public class footest extends Sprite 
    { 
     public function footest() 
     { 
      Foo.prototype.method = function():String 
      { 
       return "Something"; 
      } 

      var foo:Foo = new Foo(); 
      trace(foo["method"]()); 
     } 
    } 
} 

Lưu ý rằng OP cho biết thừa kế không thể chấp nhận được, như đã sửa đổi mã được tạo. (. Nếu đó không phải là trường hợp, thêm "năng động" để định nghĩa lớp lẽ sẽ là giải pháp đơn giản nhất)

2

Tùy thuộc vào bao nhiêu phương pháp lớp học của bạn có, điều này có thể làm việc:

Lớp Thực tế:

public class SampleClass 
{ 
    public function SampleClass() 
    { 
    } 

    public function method1():void { 
     Alert.show("Hi"); 
    } 

nhanh Wrapper:

var actualClass:SampleClass = new SampleClass(); 

var QuickWrapper:Object = { 
    ref: actualClass, 
    method1: function():void { 
     this.ref.method1(); 
    }, 
    method2: function():void { 
     Alert.show("Hello!"); 
    } 
}; 

QuickWrapper.method1(); 
QuickWrapper.method2(); 
1

khỉ vá là một (không thanh nha) tùy chọn.

Ví dụ: giả sử bạn không thích thực tế là Flex 3 SpriteAsset.as trả về chỉ số đường viền mặc định là [7,7,7,7] (không giống như flex 2). Để sửa lỗi này, bạn có thể:

  1. Tạo một bản sao của SpriteAsset.as và thêm nó vào dự án của bạn tại /mx/core/SpriteAsset.as
  2. Chỉnh sửa bản sao cục bộ của bạn để sửa chữa bất kỳ vấn đề bạn tìm
  3. Chạy ap của bạn

Google "flex monkey patch" để biết thêm ví dụ và hướng dẫn.

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