Câu hỏi Tại sao tôi nên đi cho giao diện trong C # khi tôi có thể thực hiện các phương pháp trực tiếp


Tôi biết rằng đây là một câu hỏi rất cơ bản, nhưng một người phỏng vấn hỏi tôi một cách rất lừa và tôi đã bất lực: (

Tôi chỉ biết định nghĩa vật lý hoặc lý thuyết cho một giao diện và cũng đã thực hiện nó trong nhiều dự án mà tôi đã làm việc. Nhưng tôi thực sự không hiểu tại sao và điều này hữu ích như thế nào.

Tôi cũng không hiểu một điều trong giao diện. ví dụ: chúng tôi sử dụng

conn.Dispose(); cuối cùng là chặn. Nhưng tôi không thấy lớp đó đang triển khai hoặc kế thừa IDisposable giao diện (SqlConnection) ý tôi là lớp học. Tôi tự hỏi làm thế nào tôi có thể chỉ cần gọi tên phương thức. Cũng trong cùng một điều, tôi không hiểu phương thức Dispose hoạt động như thế nào bởi vì, chúng ta cần phải thực hiện cơ thể hàm với việc thực hiện riêng của chúng ta cho tất cả các phương thức giao diện. Vậy giao diện được chấp nhận hoặc đặt tên như hợp đồng như thế nào? Những câu hỏi này tiếp tục trôi chảy trong tâm trí của tôi cho đến bây giờ và thẳng thắn mà tôi chưa bao giờ thấy bất kỳ chủ đề tốt nào có thể giải thích câu hỏi của tôi theo cách mà tôi có thể hiểu được.

MSDN như thường trông rất đáng sợ và không có dòng duy nhất là rõ ràng ở đó (Folks, vui lòng tha thứ cho những người đang phát triển cấp cao, tôi mạnh mẽ cảm thấy rằng bất kỳ mã hoặc bài viết nên đạt được tâm trí của bất cứ ai nhìn thấy nó, do đó giống như nhiều người khác nói, MSDN không được sử dụng).

Người phỏng vấn nói:

Anh ấy có 5 phương pháp và anh ấy rất vui khi thực hiện nó trực tiếp trong lớp, nhưng nếu bạn phải vào lớp Tóm tắt hoặc giao diện, cái nào bạn chọn và tại sao? Tôi đã trả lời anh ta tất cả các chất liệu mà tôi đọc trong nhiều blog nói rằng lợi thế và bất lợi của cả hai lớp trừu tượng và giao diện, nhưng anh ta không thuyết phục, anh ta đang cố gắng hiểu "Tại sao giao diện" nói chung. "Tại sao lớp trừu tượng" nói chung ngay cả khi tôi có thể thực hiện cùng một phương pháp chỉ một lần và không thay đổi nó.

Tôi thấy không có nơi nào trong mạng, tôi có thể nhận được một bài viết mà có thể giải thích rõ ràng về giao diện và chức năng của nó. Tôi là một trong những lập trình viên nhiều, những người vẫn chưa biết về giao diện (tôi biết lý thuyết và phương pháp tôi đã sử dụng) nhưng không hài lòng rằng tôi hiểu rõ ràng.


76
2018-06-06 13:05


gốc


Giao diện là một trong những tôi đã đấu tranh để hiểu cũng có. Câu hỏi hay. - Brian
lập trình cho một hợp đồng trừu tượng hơn là thực hiện cụ thể .... Tóm lại, nó có nghĩa là bạn có thể thay thế bất kỳ đối tượng nào thực hiện một giao diện khi một giao diện được yêu cầu. - Mitch Wheat
SqlConnectionkế thừa System.ComponentModel.Component công cụ nào IDisposable. - Lee
@ MitchWheat - Nó không có nghĩa là một ví dụ, câu hỏi hỏi làm thế nào SqlConnection dụng cụ IDisposable. - Lee
Oh Lee, điều đó làm tôi hiểu cảm ơn bạn. Nhưng tôi vẫn không thấy làm thế nào hoặc nơi "Định vị" phương pháp chức năng được xác định. - Learner


Các câu trả lời:


Giao diện là tuyệt vời khi bạn muốn tạo ra một cái gì đó như nó:

 using System;

namespace MyInterfaceExample
{
    public interface IMyLogInterface
    {
        //I want to have a especific method that I'll use in MyLogClass
        void WriteLog();       
    }

    public class MyClass:IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyClass was Logged");
        }
    }

    public class MyOtherClass :IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyOtherClass was Logged");
            Console.Write("And I Logged it different, than MyClass");
        }
    }

    public class MyLogClass
    {
        //I created a WriteLog method where I can pass as parameter any object that implement IMyLogInterface.
        public static void WriteLog(IMyLogInterface myLogObject)
        {
            myLogObject.WriteLog(); //So I can use WriteLog here.
        }
    }

    public class MyMainClass
    {
        public void DoSomething()
        {
            MyClass aClass = new MyClass();
            MyOtherClass otherClass = new MyOtherClass();

            MyLogClass.WriteLog(aClass);//MyClass can log, and have his own implementation
            MyLogClass.WriteLog(otherClass); //As MyOtherClass also have his own implementation on how to log.
        }
    }
}

Trong ví dụ của tôi, tôi có thể là một nhà phát triển viết MyLogClassvà các nhà phát triển khác, có thể tạo ra các lớp học và khi họ muốn đăng nhập, họ triển khai giao diện IMyLogInterface. Đó là khi họ hỏi tôi những gì họ cần phải thực hiện để sử dụng WriteLog() phương pháp trong MyLogClass. Câu trả lời họ sẽ tìm thấy trong giao diện.


68
2018-06-06 13:30



Hey trông giống như một thành phần rất tốt cho tôi để hiểu, tôi thực sự đánh giá cao nó, cảm ơn rất nhiều :) :) - Learner
Câu hỏi của tôi là nếu bạn đang instantiating MyClass và MyOtherClass tại sao bạn không đơn giản gọi aClass.WriteLog() tại sao thêm bước bổ sung đó. Việc thực hiện WriteLog() sẽ vẫn khác nhau cho mỗi lớp nhưng bạn đã có đối tượng, vậy tại sao lại chuyển nó tới lớp xử lý? - Zach M.
Hm có thể là nếu bạn đặt ví dụ đăng nhập của mình lên nugget thì sẽ đơn giản hơn nếu người khác sử dụng logger của bạn, mà không biết chi tiết .. nhưng mặt khác, vẫn không phải là một lớp phổ thông, (tôi có thể viết giao diện với đăng nhập và cấp độ allert) giao diện vẫn chỉ trong phạm vi của bạn. Vì vậy, bên cạnh chính mình cho những người được hưởng lợi từ nó? - user3800527
Đây không phải là một ví dụ cho mô hình chiến lược? - SHRI
@ ZachM. Nếu tôi đúng, Câu trả lời có nghĩa là, anh ta sẽ không khởi tạo các lớp, nhưng các nhà phát triển khác sẽ khởi tạo các lớp và chuyển nó thành tham số MyLogClass  WriteLog phương pháp. Vì vậy, phương pháp của anh ta có thể xử lý bất kỳ đối tượng nào thực hiện IMyLogInterface . Đây là một bài đăng thú vị khác. - stom


Giao diện là những hợp đồng mà người thực hiện phải tuân theo. Lớp trừu tượng cho phép các hợp đồng cộng với việc triển khai được chia sẻ - điều mà Giao diện không thể có. Các lớp có thể thực hiện và kế thừa nhiều giao diện. Các lớp chỉ có thể mở rộng một lớp trừu tượng duy nhất.

Tại sao giao diện

  • Bạn không có triển khai mã mặc định hoặc chia sẻ
  • Bạn muốn chia sẻ các hợp đồng dữ liệu (dịch vụ web, SOA)
  • Bạn có các triển khai khác nhau cho từng trình triển khai giao diện (IDbCommandSqlCommand và OracleCommand triển khai giao diện theo những cách cụ thể)
  • Bạn muốn hỗ trợ đa thừa kế.

Tại sao lại trừu tượng


37
2018-06-06 13:14



@ Tôi đọc hầu hết những gì bạn đã gõ vào blog, nhưng tôi đang cố gắng để hiểu thực tế. Tôi đã thực hiện dịch vụ WCF, giao diện tiếp xúc (Nhưng nó chỉ là một ứng dụng độc lập một mình không có thượng lưu hoặc hạ lưu). Do đó tôi không thể hiểu nó đúng mặc dù tôi đã thiết kế và triển khai các giao diện rất tốt. Câu hỏi của tôi là, thực tế, bạn chỉ cần chia sẻ hợp đồng tên phương thức có nghĩa là đúng? Trong bài viết của bạn ở trên giao diện, điểm thứ 2 nói về chia sẻ, có nghĩa là bạn có thể đưa ra một ví dụ thời gian thực thực tế về điều này - Learner
Để có một ví dụ thực tế về giao diện và SOA, chúng tôi chia sẻ giao diện WCF của chúng tôi (DataContracts) trong .NET Assembly (ví dụ. Contracts.Shared.dll) để người dùng .NET khách hàng có thể dễ dàng tương thích bằng cách sử dụng ChannelFactory (tránh tạo mã thông qua Thêm tham chiếu dịch vụ, v.v.) hoặc sử dụng Thêm tham chiếu dịch vụ với các loại được chia sẻ - SliverNinja - MSFT


Một lý do tôi sử dụng giao diện là vì nó làm tăng tính linh hoạt của mã. Giả sử chúng ta có một phương thức lấy đối tượng của lớp Account như tham số, chẳng hạn như:

  public void DoSomething(Account account) {
  // Do awesome stuff here.
}

Vấn đề với điều này, là tham số phương thức được cố định theo hướng thực hiện một tài khoản. Điều này là tốt nếu bạn không bao giờ cần bất kỳ loại tài khoản nào khác. Lấy ví dụ này, thay vào đó sử dụng giao diện tài khoản làm tham số.

public void DoSomething(IAccount account) {
  // Do awesome stuff here.
}

Giải pháp này không cố định đối với việc triển khai, điều đó có nghĩa là tôi có thể chuyển nó thành SuperSavingsAccount hoặc ExclusiveAccount (cả hai đều triển khai giao diện IAccount) và nhận được hành vi khác nhau cho mỗi tài khoản được triển khai.


29
2018-03-08 12:45



Giải thích tốt đẹp - Hari


Trong một từ - vì Đa hình!

Nếu bạn "Program to a Interface, không phải là một thực hiện" hơn bạn có thể tiêm các đối tượng khác nhau mà chia sẻ cùng một giao diện (loại) vào phương thức như một đối số. Bằng cách này, mã phương thức của bạn không được kết hợp với bất kỳ việc thực hiện nào của một lớp khác có nghĩa là nó luôn mở để làm việc với các đối tượng mới được tạo ra của cùng một giao diện. (Nguyên tắc mở / đóng)

  • Nhìn vào Dependency Injection và chắc chắn đọc Các mẫu thiết kế - Các thành phần của phần mềm hướng đối tượng tái sử dụng bởi GOF.

15
2017-11-27 23:09





enter image description here

Trong ví dụ này, PowerSocket không biết gì về các đối tượng khác. Tất cả các đối tượng đều phụ thuộc vào Power được cung cấp bởi PowerSocket, do đó chúng triển khai IPowerPlug và do đó chúng có thể kết nối với nó.

Giao diện rất hữu ích vì chúng cung cấp các hợp đồng mà các đối tượng có thể sử dụng để làm việc cùng nhau mà không cần biết bất kỳ điều gì khác về nhau.


4
2017-08-25 12:18





C # không có kiểu gõ vịt - chỉ vì bạn biết một phương thức nào đó được thực hiện trên một tập các lớp cụ thể không có nghĩa là bạn có thể xử lý tất cả chúng giống nhau về việc gọi phương thức đó. Việc thực hiện một giao diện cho phép bạn xử lý tất cả các lớp đang triển khai thực hiện nó như cùng một loại điều, liên quan đến giao diện đó định nghĩa.


3
2018-06-06 13:12



Bạn có thể nhận được loại ducktyping trong .net4 với các loại năng động. - Tony Hopkinson


Bạn chỉ có thể kế thừa từ một lớp trừu tượng. Bạn có thể kế thừa từ nhiều giao diện. Điều này xác định những gì tôi sử dụng cho hầu hết các trường hợp.

Ưu điểm của lớp trừu tượng sẽ là bạn có thể thực hiện cơ sở. Tuy nhiên, trong trường hợp IDisposable, việc cài đặt mặc định là vô dụng, vì lớp cơ sở không biết cách dọn dẹp mọi thứ đúng cách. Do đó, một giao diện sẽ phù hợp hơn.


1
2018-06-06 13:14





Với giao diện, bạn có thể thực hiện các thao tác sau:

1) Tạo các giao diện tách biệt, cung cấp các đường cắt khác nhau cho việc triển khai của bạn, cho phép giao diện gắn kết hơn.

2) Cho phép nhiều phương thức có cùng tên giữa các giao diện, bởi vì này, bạn không có triển khai xung đột, chỉ là chữ ký.

3) Bạn có thể phiên bản và thoát khỏi giao diện độc lập của bạn thực hiện, đảm bảo một hợp đồng được đáp ứng.

4) mã của bạn có thể dựa vào trừu tượng hơn là concretion, cho phép tiêm phụ thuộc thông minh, bao gồm tiêm thử nghiệm Mocks vv.

Có nhiều lý do tôi chắc chắn hơn, đây chỉ là một vài lý do.

Một lớp trừu tượng cho phép bạn có một cơ sở cụ thể một phần để làm việc, điều này không giống như một giao diện nhưng có những phẩm chất riêng của nó như khả năng tạo một phần triển khai bằng cách sử dụng mẫu phương thức mẫu.


1
2018-06-06 13:15



Bạn đã bỏ qua điều quan trọng nhất: triển khai một giao diện làm cho lớp của bạn có thể sử dụng được bằng bất kỳ mã nào cần triển khai giao diện đó, mà không có mã trong câu hỏi phải biết bất kỳ điều gì về lớp của bạn. - supercat


Cả hai lớp trừu tượng và giao diện là hợp đồng.

Ý tưởng của một hợp đồng là bạn chỉ định một số hành vi. Nếu bạn nói bạn đã triển khai, bạn đã đồng ý với hợp đồng.

Sự lựa chọn của trừu tượng trên interrface là.

Bất kỳ hậu duệ không trừu tượng nào của lớp trừu tượng sẽ thực hiện hợp đồng.

đấu với

Bất kỳ lớp nào triển khai giao diện sẽ thực hiện hợp đồng.

Vì vậy, bạn sử dụng trừu tượng khi bạn muốn chỉ định một số hành vi mà tất cả con cháu phải thực hiện và lưu bản thân xác định một giao diện riêng biệt, nhưng bây giờ mọi thứ đáp ứng hợp đồng tổng hợp này phải là hậu duệ.


1
2018-06-06 13:28





Tôi tin rằng nhiều máu đã đổ ra khi hỏi những câu hỏi này, và nhiều người cố gắng giải quyết vấn đề này bằng cách giải thích những thuật ngữ giống như robot mà không người bình thường nào có thể hiểu được.

Vì vậy, đầu tiên. để tìm hiểu lý do tại sao giao diện và lý do tại sao trừu tượng bạn cần phải tìm hiểu chúng là gì. Tôi đã học được điều này khi áp dụng Lớp Nhà máy. bạn tìm thấy một tuturial tốt trên liên kết này

Bây giờ chúng ta hãy đào sâu vào liên kết mà tôi đã đưa ra.

Bạn có Xe lớp có thể thay đổi theo yêu cầu của người dùng (như thêm Xe tải, Xe tăng, Máy bay, v.v. Và chúng tôi có

public class clsBike:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Bike");
    }
    #endregion
}

public class clsCar:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Car");
    }
    #endregion
}

và cả hai đều có IChoice hợp đồng chỉ đơn giản nói rằng lớp của tôi nên có phương thức mua

public interface IChoice
{
    string Buy();
}

Bây giờ, bạn thấy, giao diện đó chỉ thực thi phương thức Buy() nhưng để cho lớp kế thừa quyết định phải làm gì khi thực hiện nó. Đây là giới hạn của Giao diện, sử dụng giao diện thuần túy, bạn có thể sẽ lặp lại một số tác vụ mà chúng tôi có thể thực hiện tự động bằng cách sử dụng abstact. Trên ví dụ của chúng ta hãy nói, mua mỗi chiếc xe đều được giảm giá.

public abstract class Choice
{
    public abstract string Discount { get; }
    public abstract string Type { get; }
    public string Buy()
    {
       return "You buy" + Type + " with " + Discount;
}
public class clsBike: Choice
{
    public abstract string Discount { get { return "10% Discount Off"; } }
    public abstract string Type { get { return "Bike"; } }
}

public class clsCar:Choice
{
    public abstract string Discount { get { return " $15K Less"; } }
    public abstract string Type { get { return "Car"; } }
}

Bây giờ sử dụng Class Factory, bạn có thể đạt được điều tương tự nhưng trong việc sử dụng abstract, bạn để cho lớp cơ sở thực thi Buy() phương pháp.

Tóm tắt : Giao diện hợp đồng cho phép lớp kế thừa thực hiện     trong khi Lớp trừu tượng Các hợp đồng có thể khởi tạo việc thực hiện (có thể ghi đè lên bởi lớp Inherit)


1
2017-11-11 12:51





Giao diện cho phép trình thiết kế lớp tạo các phương thức sẵn có rất rõ ràng cho người dùng cuối. Chúng cũng là một phần không thể tách rời của đa hình.


0
2018-06-06 13:10



Cũng nói trên tuyên bố thứ nhất của bạn. Nhưng tôi dint hiểu tuyên bố thứ 2 của bạn, bạn có thể vui lòng xây dựng với một ví dụ thời gian thực xin vui lòng? - Learner