2015-06-13 17 views
16

Khi tôi gọi phương thức ghi đè từ hàm tạo siêu lớp, tôi không thể nhận giá trị của thuộc tính lớp con một cách chính xác.Gọi phương thức ghi đè từ cấp siêu trong số

dụ

class A 
{ 
    constructor() 
    { 
     this.MyvirtualMethod(); 
    } 

    protected MyvirtualMethod(): void 
    { 

    } 
} 

class B extends A 
{ 
    private testString: string = "Test String"; 

    public MyvirtualMethod(): void 
    { 
     alert(this.testString); // This becomes undefined 
    } 
} 

Tôi muốn biết làm thế nào để ghi đè lên một cách chính xác chức năng trong nguyên cảo.

+5

gọi method ảo trong constructor được coi là một thực tế xấu trong bất kỳ ngôn ngữ OOP: https://google.com/search?q=virtual+method+in+constructor –

Trả lời

11

Trình tự thực hiện là:

  1. A 's constructor
  2. B' s constructor

Việc chuyển nhượng xảy ra trong B 's constructor sau A' s constructor- _super -has được gọi là:

function B() { 
    _super.apply(this, arguments); // MyvirtualMethod called in here 
    this.testString = "Test String"; // testString assigned here 
} 

Vì vậy, những điều sau đây sẽ xảy ra:

var b = new B();  // undefined 
b.MyvirtualMethod(); // "Test String" 

Bạn sẽ cần phải thay đổi mã của bạn để đối phó với điều này. Ví dụ, bằng cách gọi this.MyvirtualMethod() trong constructor của B, bằng cách tạo ra một phương thức factory để tạo đối tượng và sau đó thực thi hàm, hoặc bằng cách truyền chuỗi đó vào constructor của A và làm việc bằng cách nào đó ... có rất nhiều khả năng.

+0

OO yea .. hiểu rồi. Cảm ơn. Tôi nghĩ rằng các tài sản khởi tạo trước khi các nhà xây dựng. – Sency

+0

Chúng ta không ở đây trong trường hợp 'new.target' có thể hữu ích không? – GameAlchemist

24

Chìa khóa đang gọi phương thức của cha mẹ bằng super.methodName();

class A { 
    // A protected method 
    protected doStuff() 
    { 
     alert("Called from A"); 
    } 

    // Expose the protected method as a public function 
    public callDoStuff() 
    { 
     this.doStuff(); 
    } 
} 

class B extends A { 

    // Override the protected method 
    protected doStuff() 
    { 
     // If we want we can still explicitly call the initial method 
     super.doStuff(); 
     alert("Called from B"); 
    } 
} 

var a = new A(); 
a.callDoStuff(); // Will only alert "Called from A" 

var b = new B() 
b.callDoStuff(); // Will alert "Called from A" then "Called from B" 

Try it here

5

Nếu bạn muốn có một lớp siêu để gọi một chức năng từ một lớp con, cách sạch nhất là xác định một mô hình trừu tượng, theo cách này bạn một cách rõ ràng biết phương pháp này tồn tại ở đâu đó và phải được ghi đè bởi một phân lớp.

Đây là là một ví dụ, thông thường bạn không gọi một phương thức phụ trong các nhà xây dựng như trường hợp phụ không được khởi tạo chưa ... (lý do tại sao bạn có một "không xác định" trong ví dụ của câu hỏi của bạn)

abstract class A { 
    // The abstract method the subclass will have to call 
    protected abstract doStuff():void; 

    constructor(){ 
    alert("Super class A constructed, calling now 'doStuff'") 
    this.doStuff(); 
    } 
} 

class B extends A{ 

    // Define here the abstract method 
    protected doStuff() 
    { 
     alert("Submethod called"); 
    } 
} 

var b = new B(); 

Thử nghiệm nó Here

Và nếu như @Max bạn thực sự muốn tránh triển khai phương pháp trừu tượng ở khắp mọi nơi, chỉ cần loại bỏ nó. Tôi không khuyên bạn nên tiếp cận này bởi vì bạn có thể quên bạn đang ghi đè phương pháp.

abstract class A { 
    constructor() { 
     alert("Super class A constructed, calling now 'doStuff'") 
     this.doStuff(); 
    } 

    // The fallback method the subclass will call if not overridden 
    protected doStuff(): void { 
     alert("Default doStuff"); 
    }; 
} 

class B extends A { 
    // Override doStuff() 
    protected doStuff() { 
     alert("Submethod called"); 
    } 
} 

class C extends A { 
    // No doStuff() overriding, fallback on A.doStuff() 
} 

var b = new B(); 
var c = new C(); 

Thử Here

+0

Giải pháp này bạn sẽ buộc phải định nghĩa phương thức này trong mọi lớp con ngay cả khi không cần thiết. – Max

+0

@Max đó là mục đích duy nhất của tóm tắt. Tôi đặt một ví dụ trong câu trả lời của tôi cho bạn –

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