2009-02-17 2 views
0

Я создаю приложение приличного размера в ASP.NET/VB.NET с различными объектами ... Я никогда не использовал интерфейсы раньше, а другой программист отказался, когда я упомянул об этом его. Может ли кто-нибудь дать мне краткий обзор того, как они используются, для чего они используются, и почему я буду использовать их? Может быть, мне не нужно использовать их для этого проекта, но если они помогут, я, конечно, с удовольствием попробую.ASP.NET: незнакомы с интерфейсами

Большое спасибо!

ответ

7

Как только вы «получите» интерфейсы, ООП действительно встает на свои места. Проще говоря, интерфейс определяет набор сигнатур открытых методов, вы создаете класс, который реализует эти методы. Это позволяет вам обобщать функции для любого класса, который реализует определенный интерфейс (например, классы, которые имеют одинаковые методы), даже если эти классы не обязательно сходятся друг от друга.

Module Module1 

    Interface ILifeform 
     ReadOnly Property Name() As String 
     Sub Speak() 
     Sub Eat() 
    End Interface 

    Class Dog 
     Implements ILifeform 

     Public ReadOnly Property Name() As String Implements ILifeform.Name 
      Get 
       Return "Doggy!" 
      End Get 
     End Property 

     Public Sub Speak() Implements ILifeform.Speak 
      Console.WriteLine("Woof!") 
     End Sub 

     Public Sub Eat() Implements ILifeform.Eat 
      Console.WriteLine("Yum, doggy biscuits!") 
     End Sub 
    End Class 

    Class Ninja 
     Implements ILifeform 

     Public ReadOnly Property Name() As String Implements ILifeform.Name 
      Get 
       Return "Ninja!!" 
      End Get 
     End Property 

     Public Sub Speak() Implements ILifeform.Speak 
      Console.WriteLine("Ninjas are silent, deadly killers") 
     End Sub 

     Public Sub Eat() Implements ILifeform.Eat 
      Console.WriteLine("Ninjas don't eat, they wail on guitars and kick ass") 
     End Sub 
    End Class 

    Class Monkey 
     Implements ILifeform 


     Public ReadOnly Property Name() As String Implements ILifeform.Name 
      Get 
       Return "Monkey!!!" 
      End Get 
     End Property 

     Public Sub Speak() Implements ILifeform.Speak 
      Console.WriteLine("Ook ook") 
     End Sub 

     Public Sub Eat() Implements ILifeform.Eat 
      Console.WriteLine("Bananas!") 
     End Sub 
    End Class 


    Sub Main() 
     Dim lifeforms As ILifeform() = New ILifeform() {New Dog(), New Ninja(), New Monkey()} 
     For Each x As ILifeform In lifeforms 
      HandleLifeform(x) 
     Next 

     Console.ReadKey(True) 
    End Sub 

    Sub HandleLifeform(ByVal x As ILifeform) 
     Console.WriteLine("Handling lifeform '{0}'", x.Name) 
     x.Speak() 
     x.Eat() 
     Console.WriteLine() 
    End Sub 
End Module 

Ни один из классов выше, не опускаются друг от друга, но мой метод HandleLifeform обобщается работать на всех из них - или действительно любой класс, который реализует интерфейс ILifeform.

+0

Это лучшее описание, которое я видел для этой концепции. Спасибо большое! – Jason

+1

и ниндзя полностью плачут на гитарах, потому что они полностью сладкие. – Jason

+0

Brilliantly Put ... еще один момент, который следует отметить, заключается в том, что вы можете протестировать соответствие данного интерфейса и объектов литья в заданный интерфейс, например: If TypeOf (object) - это ILifeForm Then CType (объект, ILifeform) .Speak –

2

Интерфейсы в основном позволяют вам определить контракт типа без указания его реализации.

Идея состоит в том, что если вы знаете, что данный тип реализует определенный интерфейс, он гарантирует, что определенные методы и свойства являются членами этого типа.

Таким образом, любой тип, который реализует следующий интерфейс:

Interface ISpinnable 
    Sub Spin() 
End Interface 

должны реализовать метод Spin. Но вызывающий объект этого типа, который реализует ISpinnable, не заботится о как, он реализован, он просто заботится о том, что метод существует. Вот тип, который реализует ISpinnable:

Class Top Implements ISpinnable 
    Sub Spin() 
     ' do spinning stuff 
    End Sub 
End Class 

Преимущество этого в том, что вы можете создать метод аргументы типа ISpinner и позволяют вызывающей эти методы для передачи любого типа к вам до тех пор, как он реализует интерфейс. Ваш метод больше не привязан к конкретному типу, который использует вызывающий.

+0

Спасибо за этот пример .. так скажем, я строю систему обработки заказов. У меня есть общий порядок, который состоит из счетов-фактур, заказов на покупку и кредитных форм. Могу ли я иметь формы реализовать что-то вроде IForm с такими методами, как Save(), Print() и т. Д.? – Jason

+0

Точно! Это похоже на твердое применение интерфейсов. –

1

Интерфейс - это контракт без реализации. Он позволяет определить, как будет выглядеть тип без указания того, что такое реализация этого типа.

Это позволяет использовать различные реализации интерфейса, которые отвечают вашим конкретным потребностям.

Хорошим примером является интерфейс IComparer(Of T). У вас может быть одна реализация, которая будет сравнивать два элемента на основе которых больше, а затем другое, которое вернет значение, основанное на меньшем.

Затем вы можете передать один или другой метод статической сортировки класса Array для сортировки ваших товаров в порядке возрастания или убывания соответственно.

+0

Спасибо за ваш ответ! Это помогает мне понять немного лучше. – Jason

3

Поскольку основы уже были покрыты, давайте перейдем к практическим примерам.

Скажем, у меня будет словарь, в котором хранятся строковые ключи и объекты Person, и я передам этот словарь (фактически, ссылку на него) некоторым методам, которые у меня есть.

Теперь, мой способ приема будет выглядеть примерно так

Imports System.Collections.Generic 
Public Sub DoSomething(ByVal myDict As Dictionary(Of String, Person)) 
    ' Do something with myDict here 
End Sub 

правильно?

Но что, если кто-то изобретает новый класс словарей с высокой производительностью? Я должен обернуться и изменить каждую ссылку на словарь в FastDictionary!

Однако, если бы я закодирован на интерфейс, в первую очередь, я бы не иметь эту проблему:

Imports System.Collections.Generic 
Public Sub DoSomething(ByVal myDict As IDictionary(Of String, Person)) 
    ' Do something with myDict here 
End Sub 

Теперь он принимает любой словарь!

1

Один из интерфейсов может быть полезен при просмотре массива объектов разных типов, но имеющих один и тот же интерфейс. Не могу сказать, что для VB, но в C# вы можете использовать удобный оператор «is», чтобы определить, реализует ли тип объекта данный интерфейс, и безопасно обращаться к методам этого интерфейса путем кастинга. К сожалению для C#, но я постараюсь положить некоторые комментарии в =))

//we declare 3 different interfaces each requiring to implement one method 
        interface IProgrammer 
        { 
         void WriteCode(); 
        } 

        interface ITester 
        { 
         void FindBugs(); 
        } 

        interface IWorker 
        { 
         void StartShift(); 
        } 

     // each programmer will be able to start his shift and write code 
        class Programmer : IWorker, IProgrammer 
        { 

         public void StartShift() 
         { 
          // ... 
         } 

         public void WriteCode() 
         { 
          // ... 
         } 

        } 

     // each tester will be able to start his shift and find bugs 

        class Tester : IWorker, ITester 
        { 
         public void StartShift() 
         { 
          // ... 
         } 

         public void FindBugs() 
         { 
          // ... 
         } 
        } 

      //then in code you can rely on objects implementing the interface to 
      // be able to do tasks interface requires to do 
        static void Main() 
        { 
         IWorker[] workers = new IWorker[3]; 
         workers[0] = new Programmer(); 
         workers[1] = new Tester(); 
         workers[2] = new Tester(); 

     // now we can browse through array of different workers because they all share 
     // the IWorker interface 
        foreach(IWorker worker in workers) 
        { 
         // All IWorkers can StartShift so we access its methods without casts 
         worker.StartShift(); 
         if(worker is IProgrammer) 
         { 
          // Since that worker also implements IProgrammer 
          // we cast worker as IProgrammer and access IProgrammer method(s) 
          (worker as IProgrammer).WriteCode(); 
         } 
         if(worker is ITester) 
         { 
          // Same, 
          // we cast worker as ITester and access ITester method(s) 
          // handy! =) 
          (worker as ITester).FindBugs(); 
         } 
        } 
+0

это очень полезно! Спасибо большое :) – Jason

1

Классическим примером является уровень данных, где вы используете его для поддержки нескольких формат базы данных. Это было очень полезно, прежде чем ORMappers вошли в картину в основном программировании.

Ваш интерфейс просто говорит, какой тип метода и свойств имеет ваш объект, сам объект должен реализовать эти методы.

IMyDatabase myDb; 

switch case myDbFormat { 
    case "mysql": 
     myDb = new MyDbMySql(); 
     break; 
    case "mssql" : 
     myDb = new MyDbMsSql(); 
     break;  
} 

myDb.SaveToDatabase(some data) 

Конечно, классы myDb должны реализовать интерфейс ImyDatabase. Я предполагаю, что вы можете видеть, насколько это полезно :).

Смежные вопросы