2012-12-30 28 views
27

Tôi đã xem các diễn đàn đọc mã bố cục sau và các bài đăng trên blog khác và được điều chỉnh để đặt một số câu hỏi.C# Lớp trừu tượng triển khai Giao diện

public interface IService<T> 
{ 
    int Add(T entity); 
    void Update(T entity); 
} 

public abstract class ServiceBase<T> : IService<T> 
{ 
    public int Add(T entity) { ... } 
    public void Update(T entity) { ... } 
} 

public interface ICarService : IService<Car> 
{ 
} 

public class SomeBaseClass : ServiceBase<Car>, ICarService 
{ 
    public int Add(Car entity); 
    public void Update(Car entity); 
} 

Điều tôi không hiểu là lợi ích của việc có lớp trừu tượng ngụ ý giao diện. Đối với tôi nó chỉ cảm thấy một chút lặp đi lặp lại và tôi không thể hiểu được lợi ích của việc có một lớp trừu tượng thực hiện giao diện.

  1. Tại sao lớp trừu tượng ServiceBase<T> chỉ định nghĩa là không cần phải kế thừa giao diện IService? Việc này có tăng gấp đôi mã không?
  2. Tại sao phải SomeBaseClass cũng ngụ ý số ICarService? Liệu ServiceBase có đủ không?

Trả lời

32

Quảng cáo 1: Lớp cơ sở trừu tượng bổ sung cho phép bạn phát triển giao diện mà không vi phạm triển khai. Giả sử không có lớp cơ sở trừu tượng và bạn sẽ mở rộng giao diện, giả sử bằng cách thêm phương thức mới. Sau đó, triển khai của bạn đã bị hỏng, bởi vì lớp của bạn không triển khai giao diện nữa.

Sử dụng lớp cơ sở trừu tượng bổ sung, bạn có thể tách biệt: Nếu bạn thêm phương thức mới vào giao diện, bạn có thể cung cấp triển khai ảo trong lớp cơ sở và tất cả các lớp con của bạn có thể giữ nguyên và có thể được chấp nhận để phù hợp với giao diện mới tại thời điểm sau đó.

Hơn nữa, kết hợp này cho phép bạn xác định hợp đồng (sử dụng giao diện) và cung cấp một số cơ chế mặc định (sử dụng lớp cơ sở trừu tượng). Bất kỳ ai tốt với các giá trị mặc định đều có thể kế thừa từ lớp cơ sở trừu tượng. Bất cứ ai muốn kiểm soát tốt siêu duper về bất kỳ chi tiết nhỏ có thể thực hiện các giao diện bằng tay.

Quảng cáo 2: Từ quan điểm kỹ thuật, không có NEED để triển khai giao diện trong lớp cuối cùng. Nhưng điều này, một lần nữa, cho phép bạn phát triển mọi thứ riêng biệt với nhau. A CarService là chắc chắn là Service<Car>, nhưng có thể nó còn hơn thế nữa. Có lẽ chỉ cần CarService một số nội dung bổ sung không nên đi vào giao diện chung cũng như không vào lớp cơ sở dịch vụ.

Tôi đoán đó là lý do tại sao ;-)

+1

Một điều tôi đã thông báo là trong SomeBaseClass tôi luôn luôn nhận được một cảnh báo về các phương pháp mà nói 'X giấu được thừa hưởng thành viên Y. Sử dụng từ khóa mới nếu ẩn các được dự định'. Vì lớp trừu tượng có 'Thêm', giao diện dịch vụ có 'Thêm', nó không biết phải làm gì. – fes

+1

Bạn có ý gì bởi "nó" trong câu cuối cùng? Cảnh báo trình biên dịch hoàn toàn đúng ở đó ... –