2009-08-25 23 views
5

Có một cái gì đó như thế này này:Làm thế nào để thực hiện một lớp cơ sở với một phương pháp và chưa buộc các lớp có nguồn gốc để ghi đè lên nó?

public abstract class AAA 
{ 
    protected abstract virtual string ToString() // Error 
    { 
    // Base Stuff 
    } 
} 

public abstract class BBB : AAA 
{ 
    public override string ToString() 
    { 
    // Use base.ToString(); 
    // More Stuff 
    } 
} 

Tôi đọc bài đăng khác (abstract method in a virtual class) phù thủy là khá giống như câu hỏi của tôi, nhưng có một sự khác biệt nhỏ. Tôi muốn AAA.ToString() để có một hành vi cơ sở buộc lớp dẫn xuất ghi đè lên nó.

Tôi biết tôi có thể làm điều gì đó như thế này (cuộn xuống) nhưng tôi đang tìm kiếm một cách thích hợp.

public abstract class AAA 
{ 
    public abstract string ToString(); 
    protected string ToString2() 
    { 
    // Base Stuff 
    } 
} 

public class BBB : AAA 
{ 
    public override string ToString() 
    { 
    // Use base.ToString2(); 
    // More Stuff 
    } 
} 

tôi cũng có thể có thể làm cho một giao diện IAAA và xây dựng lớp BBB tôi như

public class BBB : AAA, IAAA { ... } 

nhưng không nhìn đúng với tôi.

Trả lời

5

cách tiếp cận của bạn về cơ bản cách thích hợp ...

Edit:

"đặc điểm kỹ thuật" của bạn là:

  1. hành vi mặc định
  2. bắt buộc ghi đè

Bây giờ, kể từ khi bạn ứng dụng tai để muốn "hành vi mặc định" để luôn luôn được thực hiện, bạn cần

public string ToString() 
{ 
    // placeholder for some default behaviour 

    string result = doToString(); 

    // placeholder for some more default behaviour 

    return result; 
} 

protected abstract string doToString(); 

chỉ này hoạt động nếu bạn biết những gì các lớp cơ sở đang làm nói chung, và muốn cung cấp việc thực hiện cho doToString() trong lớp dẫn xuất. Điều này được gọi là mẫu thiết kế Template Method.

Tuy nhiên, nếu bạn đang tìm kiếm một cách để đòi hỏi đơn vị thực hiện của một lớp được thừa kế để gọi base.ToString() trong việc thực hiện của ToString(), sau đó không có cách nào để làm điều này. Bằng cách cho phép ghi đè, bạn cung cấp cho việc kiểm soát lớp dẫn xuất đối với việc thực hiện nó.

Bạn có thể ghi lại đề xuất của mình để luôn gọi base.ToString(), nhưng đó là về nó.

Sử dụng giao diện xác định hợp đồng công khai cho lớp học của bạn. Điều này không mang lại cho bạn bất kỳ lợi ích bổ sung nào so với mẫu Phương thức mẫu, vì bạn vẫn cần phải lấy được từ một lớp cơ sở để có được triển khai "mặc định".

Bạn có bất kỳ chi tiết nào về những gì bạn đang cố gắng cung cấp trong lớp cơ sở của mình là "hành vi mặc định" không? Có lẽ điều đó sẽ giúp đưa ra một giải pháp tốt hơn. Nhìn vào câu hỏi được tham chiếu, đây thực chất là cách tiếp cận tương tự.

+0

Cảm ơn, chỉnh sửa của bạn khiến tôi nhận ra một cái gì đó quan trọng! Ngay cả khi tôi sẽ tìm ra một cách kỳ diệu để định nghĩa ToString() trong lớp cơ sở và ép buộc ghi đè trong lớp dẫn xuất, đơn giản là không có cách nào tôi có thể ép buộc ghi đè để sử dụng ToString()! Tôi cũng tìm thấy bài đăng này của một MVP về buộc ghi đè: http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/c25b6477-b990-4284-abaf-801ddf18207c .Cảm ơn một lần nữa sir. – Tipx

+0

Rất vui khi được phục vụ. Đó là bài viết của Marc Gravell ... ông cũng được biết đến trên SO quá :) –

+0

Làm thế nào để so sánh với câu trả lời OP được đăng dưới đây? – Armbrat

0

Không, không thể biến chức năng ảo hiện tại thành chức năng trừu tượng. Cách duy nhất để thực thi điều này là tạo một hàm khác trừu tượng, như bạn đã đề xuất. Đây được cho là một cách tiếp cận phù hợp hơn (và tôi đồng ý với điều đó).

2

Tôi chỉ phát hiện ra những việc cần làm để có được chính xác hành vi của tôi muốn:

public abstract class AAA 
{ 
    protected abstract string ToStringSpecific(); 
    protected string ToString() 
    { 
    // Base Stuff 
    ... 
    // Use this.ToStringSpecific(); 
    } 
} 

public class BBB : AAA 
{ 
    protected override string ToStringSpecific() 
    { 
    // Specific Stuff 
    } 
} 
+0

Tôi nghĩ bạn nên chỉnh sửa câu hỏi gốc của mình ... – Armbrat

+0

Tôi thực sự sẽ chỉnh sửa câu hỏi (và tiêu đề) để có thể giúp ai đó tìm thấy chủ đề này, nhưng tôi sẽ để giải pháp của tôi ở đây. (Nếu nó không nên được thực hiện theo cách này, sẽ không có nút "Anwser Câu hỏi của bạn") – Tipx

+0

Tôi chỉ đọc lại phần thứ hai của bình luận của tôi và nó "âm thanh" kiêu ngạo. Tôi xin lỗi vì điều đó, tôi không có ý định, và tôi không thể chỉnh sửa bình luận. Tôi xin lỗi. – Tipx

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