2009-07-17 42 views
7

Tôi có tình trạng này là khi AbstractMethod phương pháp được gọi từ ImplementClass Tôi muốn thực thi mà MustBeCalled phương pháp trong AbstractClass được gọi. Tôi chưa từng gặp tình huống này trước đây. Cảm ơn bạn!Làm thế nào để thực hiện một cuộc gọi phương thức (trong lớp cơ sở) khi phương thức ghi đè được gọi?

public abstract class AbstractClass 
{ 
    public abstract void AbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    public override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+0

Làm thế nào về khi AbstractClass.AbstractMethod được gọi bởi lớp con một sự kiện được gọi để gọi AbstractClass.MustBeCalled. Nhưng một lần nữa vẫn không chắc chắn làm thế nào để làm điều đó. – Jeff

Trả lời

8

Một lựa chọn sẽ có lớp Abstract làm sự kêu gọi theo cách này. Nếu không, không có cách nào trong C# để yêu cầu một lớp kế thừa để thực hiện một phương thức theo một cách nào đó.

public abstract class AbstractClass 
{ 
    public void PerformThisFunction() 
    { 
     MustBeCalled(); 
     AbstractMethod(); 
    } 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 

    //could also be public if desired 
    protected abstract void AbstractMethod(); 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 

Việc làm này tạo ra các phương pháp phải đối mặt với công chúng mong muốn trong lớp trừu tượng, tạo cho lớp trừu tượng hơn như thế nào và theo thứ tự những thứ được gọi là, trong khi vẫn cho phép các lớp bê tông để cung cấp chức năng cần thiết.

+0

*** Cảm ơn bạn. *** – Jeff

+0

Tôi cũng đã sử dụng mẫu này. Tôi tin rằng đây thực sự là một trong những mẫu thiết kế của Gang Of Four, nhưng tôi không có cuốn sách của tôi ở đây để xác nhận điều đó. – MedicineMan

+0

Làm thế nào về việc nâng cao sự kiện khi Base.AbstractMethod() được gọi? – Jeff

-1

Tại sao bạn không thể gọi phương thức trong lớp AbstractMethod() của lớp Thực hiện?

6

Làm thế nào về

public abstract class AbstractClass 
{ 
    public void AbstractMethod() 
    { 
     MustBeCalled(); 
     InternalAbstractMethod(); 
    } 

    protected abstract void InternalAbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void InternalAbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+1

Trong triển khai này, tôi không nghĩ rằng bạn đã buộc người dùng phải gọi MustBeCalled. Khi AbstractClass.AbstractMethod được gọi, ImplementClass.AbstractMethod được gọi, nhưng MustBeCalled thì không. Tôi tin rằng yshuditelu có giải pháp tốt hơn – MedicineMan

0

Một điều các giải pháp trước bỏ qua là ImplementClass có thể xác định lại MethodToBeCalled và không gọi MustBeCalled -

public abstract class AbstractClass 
{ 
    public abstract void AbstractMethod(); 

    private void MustBeCalled() 
    { 
     //will be invoked by MethodToBeCalled(); 
     Console.WriteLine("AbstractClass.MustBeCalled"); 
    } 

    public void MethodToBeCalled() 
    { 
     MustBeCalled(); 
     AbstractMethod(); 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    public override void AbstractMethod() 
    { 
     Console.WriteLine("ImplementClass.InternalAbstractMethod"); 
    } 

    public new void MethodToBeCalled() { 
     AbstractMethod(); 
    } 
} 

Nếu chỉ C# cho phép các phương pháp không ghi đè để được niêm phong - như từ khóa thức Java!

Cách duy nhất tôi có thể nghĩ để khắc phục điều này là sử dụng ủy quyền thay vì thừa kế, vì các lớp có thể được định nghĩa là bị niêm phong. Và tôi đang sử dụng không gian tên và công cụ sửa đổi truy cập "nội bộ" để ngăn chặn việc cung cấp triển khai mới khi triển khai các lớp. Ngoài ra, phương pháp ghi đè phải được định nghĩa là được bảo vệ, nếu không người dùng có thể gọi nó trực tiếp.

namespace Something 
{ 

    public sealed class OuterClass 
    { 
     private AbstractInnerClass inner; 

     public OuterClass(AbstractInnerClass inner) 
     { 
      this.inner = inner; 
     } 

     public void MethodToBeCalled() 
     { 
      MustBeCalled(); 
      inner.CalledByOuter(); 
     } 

     public void MustBeCalled() 
     { 
      //this must be called when AbstractMethod is invoked 
      System.Console.WriteLine("OuterClass.MustBeCalled"); 
     } 
    } 

    public abstract class AbstractInnerClass 
    { 
     internal void CalledByOuter() 
     { 
      AbstractMethod(); 
     } 

     protected abstract void AbstractMethod(); 
    } 
} 

public class ImplementInnerClass : Something.AbstractInnerClass 
{ 
    protected override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
     System.Console.WriteLine("ImplementInnerClass.AbstractMethod"); 
    } 

    public new void CalledByOuter() 
    { 
     System.Console.WriteLine("doesn't work"); 
    } 
} 
+0

Thực tế là một lớp dẫn xuất có thể đổ bóng MethodToBeCalled sẽ không đặt ra một vấn đề cho mã sử dụng đối tượng lớp dẫn xuất như là một lớp cơ sở. Tôi nghĩ rằng hệ thống phân cấp phương pháp có thể được cải thiện nếu các phương thức "overridable private" được cho phép; Tôi không biết có lý do kỹ thuật nào mà họ không thể. Một phương thức overridable riêng chỉ có thể được gọi từ lớp cơ sở, hoặc từ bên trong một lớp thừa kế của phương thức tương tự. Do đó nó sẽ không thể gọi mã trong việc thực hiện cơ sở ngoại trừ từ bên trong một cuộc gọi cấp cơ sở đến phiên bản có nguồn gốc cao nhất. – supercat

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