2015-09-25 71 views
1

我是一个18岁的学徒在C#编程(specificly在OOP“结构”)无法实现的接口

目前,我正在努力学习界面的使用/有用性,但..我有一个非常难以实际使用接口,我决定开始处理Project Euler的问题。我想处理这些问题的方法是尝试和实现接口或任何我需要学习的东西,以便获得一些经验。

我目前在Problem 2,但我想不出一种实现接口的方法。

所以一般我想问的是,什么,我怎么能做到这一点(请不要给我最后的结果,我只想找一个想法或帮助上手)

什么我觉得自己被困在一个洞里,无法继续下去,所以我会喜欢一些灵感,例子或者任何可以获得简洁而好的信息的东西! :)

提前,非常感谢您的帮助/建设性的批评。

-最好的问候,尼克拉斯

+3

其实,问题2不需要你实现接口,右侧? – Sweeper

+5

接口在那些小应用程序中并非有用。这更多的是关于大型应用程序。 – MajkeloDev

+5

对于这样的问题,你需要研究'递归'而不是接口。当需要与其他模块进行通信时,接口非常有用,因此您可以使用接口来提供一组需要在其中的方法。看看[这里](https://msdn.microsoft.com/en-us/library/3b5b8ezk(v = vs.90).aspx)了解更多关于此事的信息。另外作为一个经验法则,这是决定代码设计的情况,而不是相反的情况。 – npinti

回答

3

斐波纳契序列是......好......一个序列。因此,它可以:

  1. 返回一个项目的索引

  2. 返回一个数字

我建议用一个方法GetNextElement()创建接口ISequence

public interface ISequence 
{ 
    int GetNextElement(); 
} 

然后,可以在一个FibonacciSequence类实现此接口:

public class FibonacciSequence : ISequence 
{ 
    private int _lastElement1 = 0; 
    private int _lastElement2 = 1; 

    public int GetNextElement() 
    { 
     int result = _lastElement1 + _lastElement2; 
     _lastElement1 = _lastElement2; 
     _lastElement2 = result; 

     return result; 
    } 
} 

这将允许你实现其他序列,如算术级数等

P.S.我必须承认,为特定问题做接口并不是最好的想法,但为了学习的目的 - 为什么不呢! :)

+0

我喜欢这个想法,因为有几个任务可以产生序列。现在,OP可以编写输出和输入程序,以及以通用方式处理序列并“插入”具体实现的程序。因为在我们之中,我可能只是将锅炉板代码复制到我的下一个小项目中。 –

+1

然后你可以有不同的类来实现这个接口。例如:'public class StandardSequence:ISequence {private int _lastElement = 0; public int GetNextElement(){return _lastElement ++; }}' – Corak

+0

'public class RandomSequence:ISequence {private static readonly _random = new Random(); public int GetNextElement(){return _random.Next(); }}' – Corak

1

在我看来,接口是一个软件工程工具。你可以在项目欧拉问题上使用它们吗?绝对!毕竟它们是一种工具......但它们的用处很小,而且非常值得商榷。

如果您想了解接口如何应用于现实世界,我强烈建议您学习Design Patterns。

一些资源,让你开始:

  • Wikipedia - 免费资源,但你离开你的设备
  • Head First Design Patterns - 最好的软件工程的书我读过......涵盖设计模式以及与节目接口的实际使用。请注意,本书的编程语言是Java,但这确实没有关系。无论语言如何,OOP都是面向对象的。

这是不是所有有说的接口,你要知道,但它是你看到所使用的接口一个共同真实的场景。

0

而不是使用ISequence之类的,我宁愿实现类似的东西:

public static class Sequences { 
    // Instead of reinveting the wheel (ISequence etc.), let's return 
    // IEnumerable<long> which is specially designed for such a cases 
    public static IEnumerable<long> Fibonacci(long first, long second) { 
     yield return first; 
     yield return second; 

     while (true) { 
     long result = first + second; 

     first = second; 
     second = result; 

     yield return result; 
     } 
    } 
    } 

    ... 

    // Test: 10 first Fibonacci numbers: 
    // 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 
    Console.Write(String.Join(", ", Sequences.Fibonacci(1, 2).Take(10))); 

    ... 

    // Now having Fibonacci as IEnumerable<long> 
    // you can easily answer a lot of questions via Linq: 
    long result = Sequences.Fibonacci(1, 2) 
    .TakeWhile(item => item < 4000000) // up to 4 millions 
    .Where(item => item % 2 == 0)  // take even items only 
    .Sum();       // sum them up 

实现任何接口只是实施接口的缘故是一个不好的做法。

+0

这里的关键当然不是接口对这个问题没有用处,而是说.NET *已经创建了适当的接口*,因此OP不需要(实际上不应该)为了相同的目的创建他自己的新界面。 – Servy

0

接口本质上是一个契约 - 如果你会描述实现接口(即结核)应该提供的代码的特征,那么蓝图。

接口可能是一个难以完全掌握的话题,而无需理解他们的应用。

这里有几个:

多重继承

C#不支持多重继承,即从多个类派生所以实现多个接口是真的在这里你唯一的选择。

惩戒框架

惩戒框架所使用的地方要模仿对象的行为,但实际上没有运行。例如,当你单元测试一些软件而不连接到真实的服务或数据库时,你可能想要这样做。您只需简单地放入界面,然后描述给定输入的预期输出,并创建一个模拟对象,其行为与结核完全相同。

IOC

反转控制的是一个机制,使接口代替结核整个相关的代码基础使用。具体实现因框架而异,但通常它们涉及某种工厂,您可以根据需要定义您正在使用的接口和结核,然后实现接口的结核会遍历所有层。好的是,您可以在工厂轻松更换结核,而无需更新上游代码。


一些示例代码,其中一个程序可以处理任何结石因变量和参数被定义为接口而不是结核:

public class Teaching 
    {  
     public void RunTests() 
     { 
      ObjectA a = new ObjectA(); 
      ObjectB b = new ObjectB(); 
      IContract c = new ObjectA(); 
      IContract d = new ObjectB(); 

      Test1(a); 
      Test1(b); // Won't compile 

      Test2(b); 
      Test2(a); // Won't compile 

      // Test3 can handle either concretion    
      Test3(c); 
      Test3(d); 
     } 

     private void Test1(ObjectA obj) 
     { 
      Console.WriteLine(obj.GetExcited("Yeah")); 
     } 

     private void Test2(ObjectB obj) 
     { 
      Console.WriteLine(obj.GetExcited("Yeah")); 
     } 

     private void Test3(IContract obj) 
     { 
      Console.WriteLine(obj.GetExcited("Yeah")); 
     } 

    } 

    public class ObjectA : IContract 
    { 

     public string GetExcited(string data) 
     { 
      return data + "!"; 
     } 
    } 

    public class ObjectB : IContract 
    { 

     public string GetExcited(string data) 
     { 
      return data + "!!"; 
     } 
    } 

    public interface IContract 
    { 
     string GetExcited(string data); 
    }