精华内容
下载资源
问答
  • C#中的接口实现多态

    2014-11-14 16:05:00
    接口实际上是一种契约或者约定,例如,插头三脚两脚,但他们都一个相同的功能,就是绝缘与通电,这也是全世界插头所共同遵守规则。此时,我可以定义一个约定,说:凡是设计插头都要遵守以下约定:...

    〇、引言

    接口,属于方法的抽象,它只定义方法,而不包含任何实现,既然没有实现,接口存在的意义是什么呢?

    接口实际上是一种契约或者约定,例如,插头有三脚的,有两脚的,但他们都有一个相同的功能,就是绝缘与通电,这也是全世界的插头所共同遵守的规则。此时,我可以定义一个约定,说:凡是设计插头的都要遵守以下约定:提供绝缘的办法,提供通电的办法。对应到C#中,就是在接口中定义两个函数,一个为绝缘,一个为通电。所有插头的类都要继承这个接口,这样就会强迫所有类实现绝缘与通电两个方法,而具体如何实现,则因不同插头而不同。

    一、接口实现多态。

    多态是面向对象编程中十分重要的一个性质,它的设计思想是:只有对象自己知道具体如何执行特定的操作,通过规定 执行这些操作的通用方式,还可以促进了代码重用。例如每种文档都有自己的打印方式,但是不应该定义switch来选择不同的文档不同输出,而应该利用多态性,在基类中设计Print(); 当有需要打印任务时候就调用Print()。

    多态可以使用类的继承很容易的实现,但是多态也可以利用接口实现。代码如下:

    1、首先定义一个接口,功能是返回一组字符串,代表着信息。

     1 // <copyright file="IListable.cs" company="TNT">
     2 // Copyright (c) TNT. All rights reserved.
     3 // </copyright>
     4 // <author>Li Mingjian</author>
     5 // <date> 2014-11-14 </date>
     6 // <summary>显示一行数据的接口</summary>
     7 namespace InterfaceMultiState
     8 {
     9     using System;
    10     using System.Collections.Generic;
    11     using System.Linq;
    12     using System.Text;
    13 
    14     /// <summary>
    15     /// A interface of show a row data
    16     /// </summary>
    17     /// <see cref=""></see>
    18     /// <remarks>
    19     /// <c>创建人:Li 
    20     /// 创建日期:2014-11-14
    21     /// 版本:1.0</c>
    22     /// </remarks>
    23     interface IListable
    24     {
    25         // 返回一行中的每一列数据
    26         string[] Columnvalues
    27         {
    28             get;
    29         }
    30     }
    31 }
    View Code

    然后,将会继续写两个类:Contact与Publishion,显然一个是关于人员的,一个是关于书籍的,这两个类都继承接口IListable,当需要输出信息时,直接利用接口的多态,将类的实例转型为接口类型,统一输出。接口实例便实现多态,在找对应的输出。

    2、定义Contact类,其从抽象类PdaItem抽象而来,同时继承接口IListable:

       PdaItem如下:

     1 // <copyright file="PdaItem.cs" company="TNT">
     2 // Copyright (c) TNT. All rights reserved PdaItem.cs.
     3 // </copyright>
     4 // <author>Li Mingjian</author>
     5 // <date> 2014-11-14 </date>
     6 // <summary>联系人抽象类</summary>
     7 namespace InterfaceMultiState
     8 {
     9     using System;
    10     using System.Collections.Generic;
    11     using System.Linq;
    12     using System.Text;
    13 
    14     /// <summary>
    15     /// A abstract class of contact or others
    16     /// </summary>
    17     /// <see cref=""></see>
    18     /// <remarks>
    19     /// <c>创建人:Li 
    20     /// 创建日期:2014-11-14
    21     /// 版本:1.0</c>
    22     /// </remarks>
    23     public abstract class PdaItem
    24     {
    25         /// <summary>
    26         /// <c>Initializes a new instance of the PdaItem class.</c>
    27         /// </summary>
    28         /// <param name="name">The name</param>
    29        public PdaItem(string name)
    30        {
    31        } // PadItem
    32 
    33        /// <summary>
    34        /// Gets or sets virtual attribute:Name
    35        /// </summary>
    36        public virtual string Name { get; set; }
    37     } // class
    38 } // namespace InterfaceMultiState
    PadItem

    Contact类如下:

     1 // <copyright file="Contact.cs" company="TNT">
     2 // Copyright (c) TNT. All rights reserved Contact.cs.
     3 // </copyright>
     4 // <author>Li Mingjian</author>
     5 // <date> 2014-11-14 </date>
     6 // <summary>联系人抽象类</summary>
     7 namespace InterfaceMultiState
     8 {
     9     using System;
    10     using System.Collections.Generic;
    11     using System.Linq;
    12     using System.Text;
    13 
    14     /// <summary>
    15     /// A Contact class with set and show member information
    16     /// </summary>
    17     /// <see cref=""></see>
    18     /// <remarks>
    19     /// <c>创建人:Li 
    20     /// 创建日期:2014-11-14
    21     /// 版本:1.0</c>
    22     /// </remarks>
    23     internal class Contact : PdaItem, IListable
    24     { 
    25         /// <summary>
    26         /// Initializes a new instance of the Contact class.
    27         /// </summary>
    28         /// <param name="firsteName">The firstname</param>
    29         /// <param name="lastName">The lastname</param>
    30         /// <param name="address">The address</param>
    31         /// <param name="phone">The phone</param>
    32         public Contact(string firsteName, string lastName, string address, string phone)
    33             : base(null)
    34         {
    35             this.FirstName = firsteName;
    36             this.LastName = lastName;
    37             this.Address = address;
    38             this.Phone = phone; 
    39         } // public Contact()
    40 
    41         /// <summary>
    42         /// Gets Header include: First Name. Last Name. Phone. Address
    43         /// </summary>
    44         public static string[] Headers
    45         {
    46             get
    47             {
    48                 return new string[]
    49                 {
    50                     "First Name          ", "Last Name          ",
    51                     "Phone           ",
    52                     "Address                                     "
    53                 }; // return
    54             }
    55         } // Headers
    56 
    57         /// <summary>
    58         /// Gets or sets firstname
    59         /// </summary>
    60         public string FirstName { get; set; }
    61 
    62         /// <summary>
    63         /// Gets or sets lastname
    64         /// </summary>
    65         public string LastName { get; set; }
    66 
    67         /// <summary>
    68         /// Gets or sets address
    69         /// </summary>
    70         public string Address { get; set; }
    71 
    72         /// <summary>
    73         /// Gets or sets phone
    74         /// </summary>
    75         public string Phone { get; set; }
    76 
    77         /// <summary>
    78         /// Gets information of member
    79         /// </summary>
    80         public string[] Columnvalues
    81         {
    82             get
    83             {
    84                 return new string[]
    85                 {
    86                     this.FirstName,
    87                     this.LastName,
    88                     this.Phone,
    89                     this.Address
    90                 }; // return
    91             } // get
    92         } // Columbalues
    93     } // class Contact
    94 } // namespace InterfaceMultiState
    Contact

    3、定义publishtion类,继承接口IListable

     

     1 // <copyright file="Publication.cs" company="TNT">
     2 // Copyright (c) TNT. All rights reserved Publication.cs.
     3 // </copyright>
     4 // <author>Li Mingjian</author>
     5 // <date> 2014-11-14 </date>
     6 // <summary>联系人抽象类</summary>
     7 namespace InterfaceMultiState
     8 {
     9     using System;
    10     using System.Collections.Generic;
    11     using System.Linq;
    12     using System.Text;
    13 
    14     /// <summary>
    15     /// A Publication class with set and show books information
    16     /// </summary>
    17     /// <see cref=""></see>
    18     /// <remarks>
    19     /// <c>创建人:Li 
    20     /// 创建日期:2014-11-14
    21     /// 版本:1.0</c>
    22     /// </remarks>
    23     internal class Publication : IListable
    24     {
    25         /// <summary>
    26         /// Initializes a new instance of the Publication class
    27         /// </summary>
    28         /// <param name="title">The title of book</param>
    29         /// <param name="author">The author</param>
    30         /// <param name="year">The year of published</param>
    31         public Publication(string title, string author, int year)
    32         {
    33             this.Title = title;
    34             this.Author = author;
    35             this.Year = year;
    36         }
    37 
    38         /// <summary>
    39         /// Gets Header include: Title Author Year
    40         /// </summary>
    41         public static string[] Headers
    42         {
    43             get
    44             {
    45                 return new string[]
    46                 {
    47                     "Title                  ",
    48                     "Author             ",
    49                     "Year"
    50                 }; // return
    51             }
    52         } // Headers
    53 
    54         /// <summary>
    55         /// Gets or sets title
    56         /// </summary>
    57         public string Title { get; set; }
    58 
    59         /// <summary>
    60         /// Gets or sets author
    61         /// </summary>
    62         public string Author { get; set; }
    63 
    64         /// <summary>
    65         /// Gets or sets year
    66         /// </summary>
    67         public int Year { get; set; }
    68 
    69         /// <summary>
    70         /// Gets information of book
    71         /// </summary>
    72         public string[] Columnvalues
    73         {
    74             get
    75             {
    76                 return new string[]
    77                 {
    78                     this.Title,
    79                     this.Author,
    80                     this.Year.ToString(),
    81                 }; // return
    82             } // get
    83         } // Columbalues
    84     } // class
    85 } // namespace InterfaceMultiState
    Publishtion

    4、编写一个输出类,用来控制输出,这个类提供了一个对外的静态函数

    1 public static void List(string[] headers, IListable[] items)

    用来根据传入的参数进行输出,注意第二个参数的类型,是一个接口类型。此类的重点是如何输出items.Columnvalues

     1 // <copyright file="ConsoleListControl.cs" company="TNT">
     2 // Copyright (c) TNT. All rights reserved ConsoleListControl.cs.
     3 // </copyright>
     4 // <author>Li Mingjian</author>
     5 // <date> 2014-11-14 </date>
     6 // <summary>联系人抽象类</summary>
     7 namespace InterfaceMultiState
     8 {
     9     using System;
    10     using System.Collections.Generic;
    11     using System.Linq;
    12     using System.Text;
    13 
    14     /// <summary>
    15     /// out put string[] to console
    16     /// </summary>
    17     /// <see cref=""></see>
    18     /// <remarks>
    19     /// <c>创建人:Li 
    20     /// 创建日期:2014-11-14
    21     /// 版本:1.0</c>
    22     /// </remarks>
    23     internal class ConsoleListControl
    24     {
    25         /// <summary>
    26         /// out put information to console
    27         /// </summary>
    28         /// <param name="headers">The headers</param>
    29         /// <param name="items">A group of item</param>
    30         public static void List(string[] headers, IListable[] items)
    31         {
    32             int[] columWidths = DisplayHeader(headers);
    33 
    34             for (int count = 0; count < items.Length; count++)
    35             {
    36                 string[] values = items[count].Columnvalues;
    37 
    38                 DisplayItemsRow(columWidths, values);
    39             } // for
    40         } // List
    41 
    42         /// <summary>
    43         /// out put headers to console
    44         /// </summary>
    45         /// <param name="headers">The header of one entity</param>
    46         /// <returns type="int[]">The columWidth</returns>
    47         private static int[] DisplayHeader(string[] headers)
    48         {
    49             int[] columWidth = new int[headers.Length];
    50             string head = string.Empty;
    51 
    52             for (int count = 0; count < headers.Length; count++)
    53             {
    54                 head += headers[count];
    55                 columWidth[count] = headers[count].Length;
    56             } // for
    57 
    58             Console.WriteLine(head);
    59 
    60             return columWidth;
    61         } // DisplayHeader
    62 
    63         /// <summary>
    64         /// out put items' value to console
    65         /// </summary>
    66         /// <param name="columWidth">The columWidth</param>
    67         /// <param name="values">Item values</param>
    68         private static void DisplayItemsRow(int[] columWidth, string[] values)
    69         {
    70             string value = string.Empty;
    71 
    72             for (int count = 0; count < values.Length; count++)
    73             {
    74                 int strLen = values[count].Length;
    75                 values[count] = values[count].PadRight(columWidth[count]);
    76                 value += values[count];
    77             } // for
    78 
    79             Console.WriteLine(value);
    80         } // DisplayItemsRow
    81     } // class
    82 }
    View Code

    5、主函数中:

     1 // <copyright file="Program.cs" company="TNT">
     2 // Copyright (c) TNT. All rights reserved Program.cs.
     3 // </copyright>
     4 // <author>Li Mingjian</author>
     5 // <date> 2014-11-14 </date>
     6 // <summary>联系人抽象类</summary>
     7 namespace InterfaceMultiState
     8 {
     9     using System;
    10     using System.Collections.Generic;
    11     using System.Linq;
    12     using System.Text;
    13 
    14     /// <summary>
    15     /// A access of the whole project
    16     /// </summary>
    17     /// <see cref=""></see>
    18     /// <remarks>
    19     /// <c>创建人:Li 
    20     /// 创建日期:2014-11-14
    21     /// 版本:1.0</c>
    22     /// </remarks>
    23     public class Program
    24     {
    25         /// <summary>
    26         /// entry of process
    27         /// </summary>
    28         /// <param name="args">The args</param>
    29         private static void Main(string[] args)
    30         {
    31             Contact[] contacts = new Contact[6];
    32             contacts[0] = new Contact("Dick", "Traci", "123. Main St.", "123-123-1234");
    33             contacts[1] = new Contact("Aick", "Traci", "123. Main St.", "123-123-1234");
    34             contacts[2] = new Contact("Bick", "Traci", "123. Main St.", "123-123-1234");
    35             contacts[3] = new Contact("Cick", "Traci", "123. Main St.", "123-123-1234");
    36             contacts[4] = new Contact("Eick", "Traci", "123. Main St.", "123-123-1234");
    37             contacts[5] = new Contact("Fick", "Traci", "123. Main St.", "123-123-1234");
    38 
    39            // 将类的实例当作接口类型传入
    40             ConsoleListControl.List(Contact.Headers, contacts);
    41 
    42             Publication[] publicatons = new Publication[3];
    43             publicatons[0] = new Publication("HerryPotter", "Luolin", 1998);
    44             publicatons[1] = new Publication("XiYou", "WuChengEn", 1326);
    45             publicatons[2] = new Publication("DaXue", "Unkonwn", 239);
    46 
    47             // 将类的实例当作接口类型传入,包含了一次隐式转型
    48             ConsoleListControl.List(Publication.Headers, publicatons);
    49         } // Main
    50     } // class
    51 } // namespace InterfaceMultiState
    View Code

    注意到里面的:

    1 // 将类的实例当作接口类型传入
    2  ConsoleListControl.List(Contact.Headers, contacts);

    第二个参数是接口类型,显然存在一次转型,而输出的时候确实是按照contact的形式输出的。

    输出结果如下:

    转载于:https://www.cnblogs.com/tntboom/p/4097539.html

    展开全文
  • 对于接口测试

    2020-05-19 15:15:13
    1、系统内部模块接口的测试 模块接口测试主要包括以下内容: 1) 各个模块连接集成起来时候,穿越模块接口的数据会不会丢失。 2)各个子功能组合起来,能否达到预期要求。 3) 一个模块的功能是否对另外一个模块...

    一接口的分类:
    外部接口:
    内部接口:
    第三方接口:如微信支付,支付宝支付
    1:UI自动化执行一个测试用例10S
    接口测试用例执行的话,需要的时候是毫秒级的
    2:2、接口测试是属于集成测试 测试介入越早越好 越在项目早期发现问题,其修复问题的成本越低
    1、系统内部模块接口的测试 模块接口测试主要包括以下内容:
    1) 各个模块连接集成起来的时候,穿越模块接口的数据会不会丢失。 2)各个子功能组合起来,能否达到预期要求。
    3) 一个模块的功能是否对另外一个模块的功能产生不利的影响。
    4)全局数据结构是否有问题。
    5) 模块的积累误差是否达到了不可接受的程度。
    6)系统环境的测试
    2、外部系统与系统的交互:
    比如 app—支付宝 ,app–微信等不同系统之间的交互测试

    1.2 接口测试内容
    单接口功能测试
    多接口的联调
    接口性能测试

    开发环境、测试环境、模拟环境SIT 、线上环境 UAT
    系统内部集成测试(System Integration Testing) SIT
    用户验收测试(User Acceptance Testing) UAT
    SIT在前,UAT在后,UAT测完才可以上线。

    接口用例的设计思路
    如图所示:
    在这里插入图片描述
    覆盖入参的同时要覆盖出参

    1.3 接口测试策略
    1.接口逻辑测试
    接口逻辑测试是指根据业务逻辑、输入参数、输出值的描述,对正常输入情
    况下所得的输出值是否正确的测试,也就是测试对外提供的接口服务是否正
    常工作。
    2.模块接口测试
    模块接口测试是为了保证数据的安全及程序在异常情况下的逻辑的正确性而
    进行的测试。 模块接口测试的主要包括以下四个方面:
    1) 空值(Null)输入,检查模块接口对空值(Null)的反应能力。
    2) 参数属性的测试,输入一个未赋值的参数会出现的情况。
    3) 异常的测试,制造一些异常的测试场景,测试异常描述是否清晰。
    4) 参数的个数设计与模块接口参数的个数不一致时,检查模块接口的反应能
    力。包括以下两种情况:
    a、模块接口参数的个数不一致(或多于原设计的参数个数,或少于原设计的

    数个数);
    b、模块接口参数的类型不一致(字符型和数值型混用)

    展开全文
  • 功能属于番外,不是必须。长度大概3章节。难度不高,也算给大家休息一下。 这个功能是什么意思呢?简单点说,就是一个接口保存好之后,你保存请求数据都是正常。但是错误用例也就是无效等价类中,具体...

    本功能属于番外,不是必须的。长度大概3章节。难度不高,也算给大家休息一下。

        这个功能是什么意思呢?简单点说,就是一个接口保存好之后,你保存的请求数据都是正常的。但是错误的用例也就是无效等价类中,具体参数格式不同的要怎么测呢?正常来说有以下几种类型:整形,字符串,单字符,超长字符串,为空,全空格,有中文,纯英文,含标点符号,数组,sql注入,不符合需求规则的 等等等等。一个超全面的接口测试,几乎要把所有参数都依次替换成这些不同的格式来请求,看看是否会引起服务器报错甚至更加严重的后果。

        当我们用手工来测试的时候,这几乎是不可能办到的事,举个例子,假如接口有10个字段,要替换的各种不同格式测试数据是20个,那么你一共要测试10 * 20 = 200个测试用例。但是真的有人这么测么?现实中基本没有。原因就在于这个成本太高了,性价比极低。

        在我们传统的测试理论-11种用例设计方法中,哪怕一个简单的功能都可能要写出几百条甚至上千条用例,如果真的可以实现如此全面的覆盖,理论上没有bug会遗漏了。但是实际中无法做到真正覆盖的根本原因在于国内的高节奏敏捷迭代的大环境,这种工匠精神,细细打磨的事注定做不起来。不过技术是不断发展的,高成本的痛点早晚会被技术所解决,测试同学们也不要指望着说国内it行业的那么多大神总会有人来解决,因为他们的精力被放在了更加重要的事上,这个行业只能靠我们自己想办法了。

        我在之后的各种章节中,会有意无意的讲解这些降低成本的新解决方案。

    比如这个接口异常自动测试功能,我们的做法其实就是用代码简单的进行依次替换,比如10个字段,我们用20个测试数据依次替换的时候,其他9个字段保持用户保存在接口库中的正确值。然后请求20次,每次的结果如果出现问题,那么很显然极大概率就是这个字段的问题。这也是集成测试的半个思想。

         那么为什么要做这个非必须的功能呢?因为我们做的好歹也是个接口测试平台,那就要有平台的样子,各种新工具,新设计 只要业务有帮助,我们就上。在系列一开始的时候就说过,我们做的是平台,所以不要去和postman这种cs单机工具去比,也不要和jmeter去比性能测试,也不要和charles/fiddler去比抓包,也不要和jenkins去比监控,我们的优势和特点是:多人协作,历史保存,约束流程,符合公司内的小工具和设计,接口管理等一系列的综合体。比如这个自动异常测试功能,就是其他工具不具备的。我们之后还会讲许多这种新的技术功能。

         好,现在我们打开P_apis.html,找到异常测试的按钮,给它加上onclick,

    函数名我们就叫做error_test,传入接口id做为参数。

        我们在下面找个风水好的地方,声明这个函数:

        不要着急写,我们先考虑一下,我们测试完之后,这个巨量的测试结果要显示在哪?肯定应该有个div来承载这些返回值,所以我们先写好这个div:

    这个新div的id我叫做error_div,style属性呢直接复制调试层的div即可:

    这个div默认同样也是隐藏的,在我们的js函数error_test中,我们给div变成显示状态即可。

                如图,我们现在要考虑一些事情:

    1. 这么巨大的返回值量,一次请求基本是不可能把请求体返回来的。比如有100次请求,我们最好是发送100次请求,每次只获取一个返回值,依次显示到这个div里,所以我们是先把div给显示出来,再循环发送100次请求,每次得到返回值,都展示在这个div中即可。

    2. 那我们可以先做好前端的样式,先展示一次请求的返回值展示的demo看看。然后再在js中让其自动生成所有次请求的展示效果。

    div中我们如下设计:

    如上图,我手动写了三段请求的展示效果,然后我们看看如何:

    貌似还不错,那让我们接下来继续开发吧..

    因为我们每次发送请求,传给后台的参数都是替换后的,这就意味着我们要在前端js里处理 复杂的替换功能:

    我们可以先只完成这个复杂的替换代码,不真的去请求后台。

    我们在一开始传入这个js的参数中只有接口id,当我们进行n次请求时,后台是可以根据这个id来拿到接口的一切数据的,但是我们要测的是真实是不同的请求体,所以我们现在还需要原始的请求体,原始的请求体配合上 要替换的测试数据,才能组装成最新的请求体 。然后和接口id一起给到后台。

        那么在我们调用这个js函数的onclick里,加上原始请求体吧:

    这里要进行注意的是,这个单双引号,千万别加错了!

    同样js函数也要加上:

     

    现在我们还缺少什么呢?就是要替换的数据何在?

    我们的设计是给出默认的,用户还可以根据需要自行修改。所以存放的应该是一个可修改的input框。

    在我们的div中加上这个输入框吧:

    我们给它写上预置的几个值:

    注意我们前面忘记增加了文案颜色为黑色的属性设置,这里补上了:

    看看效果:

    可复制的源码如下:

    {# 异常值测试 #}<div id="error_div" style="display: none;border-radius:5px;width: 80%;position: absolute;left: 10%;top: 10%;background-color: #3c4043;box-shadow: 4px 4px 8px grey;color: white;padding-left: 10px;">    <h4>接口:<small id="error_api_name"></small> 的异常值测试结果如下:</h4>    <strong>待替换数据:(用英文逗号隔开)</strong>    <input id="ready_error_data" type="text" style="color: black;border-radius: 5px;width: 99%"    value="'a',123,'',' ','./?*&^','中文'"    > <br><br>        <span>替换:username -> 123</span>    <textarea style="width: 99%;height: 50px;border-radius: 5px;color: black">    </textarea>
        <span>替换:username -> "aaa"</span>    <textarea style="width: 99%;height: 50px;border-radius: 5px;color: black">    </textarea>
        <span>替换:username -> "哈哈哈"</span>    <textarea style="width: 99%;height: 50px;border-radius: 5px;color: black">    </textarea>
    </div>

    好,到这为止。今天的前端样式算是完成了。

     

    大家可以自行稍微修饰优化。明天继续本功能实现

    展开全文
  • JDK升级目的有以下几个:增加新的功能、修复bug、性能优化、简化代码等几个方面,Lambda表达式就是属于简化代码,用于简化匿名实现类,提供一种更加简洁写法。Lambda表达式在Swift语言中称之为代码块,Lambda...

    Lambda表达式


    一:简介

    JDK的升级的目的有以下几个:增加新的功能、修复bug、性能优化、简化代码等几个方面,Lambda表达式就是属于简化代码,用于简化匿名实现类,提供一种更加简洁的写法。Lambda表达式在Swift语言中称之为代码块,Lambda表达式可以认为是一种特殊的接口,该接口必须只有一个抽象方法。

    语法

    (参数类型 参数名, 数参数类型 参数名2...) -> { 
        // code
    };

    小括号()中的内容就是方法中的参数列表包括参数类型、参数名,其中参数类型是可以省略的,当参数个数只有一个时也可以省略掉小括号;
    花括号{}中的内容就是方法中的方法体,当方法体中只有一行代码时可以省略{},当方法体中只有一行代码并且需要返回值时也可以省略掉return;
    由于Lambda表达式是匿名实现类的简写,是一种特殊的接口,当赋值给一个变量时也少不掉分号;

    Lambda表达式的作用

    • 简化匿名实现类的书写
    • 作为函数中的参数来传递

    二:示例

    示例1:两个参数,一个返回值

    IHello 一个很普通的接口,但接口中只能有一个抽象方法

    public interface IHello {
        String sayHello(String name, String msg);
    }

    Main

    public class Main {
        public static void main(String[] args) {
            // 将一个Lambda表达式赋值给一个接口,说明Lambda表达式就是一种接口数据类型,只不过该接口只能有一个抽象方法
            // 参数列表可以省略参数类型,可以写成(name, msg),
            // 在JDK1.8中有个叫做类型推断的东西,可以自动推断出参数的类型,
            // 因为IHello中只有一个抽象方法,知道方法了就知道参数列表了,从而就能推出参数类型来
            IHello iHello = (String name, String msg) -> {
                String hello = name + ": " + msg;
                return hello;
            };
            // 调用接口的方法
            String content = iHello.sayHello("mengday", "happy new year everyone!");
            System.out.println(content);
        }
    }

    示例2:一个参数,一个返回值

    public interface IHello {
        String sayHello(String name);
    }

    Main

    public class Main {
        public static void main(String[] args) {
            // 参数列表可以省略参数类型,当只有一个参数时可以省略小括号 (String name) --> (name) --> name
            // 当方法体中只有一行代码并且有返回值时可以同时省略花括号和return
            // { return name + ": " + "happy new year everyone!";} --> name + ": " + "happy new year everyone!";
            IHello iHello = name -> name + ": " + "happy new year everyone!";
    
            String content = iHello.sayHello("mengday");
            System.out.println(content);
        }
    }

    示例3:没有参数,没有返回值

    public interface IHello {
        void sayHello();
    }
    public class Main {
        public static void main(String[] args) {
            // 当表达式没有参数时一对小括号是不能省略掉的
            IHello iHello = () -> System.out.println("mengday: happy new year everyone!");
            iHello.sayHello();
        }
    }

    从这三个示例中我们发现我们只定义了接口,并没有定义实现类,而是通过Lambda表达式来代替了实现类。
    注意:Lambda接口只能有一个抽象方法,可以同时拥有多个静态方法和默认方法。


    示例4:Lambda表达式参数

    public interface IHello {
        void sayHello(String name);
    }
    public class Main {
    
        public static void sayHello(IHello iHello, String name) {
            iHello.sayHello(name);
        }
    
        public static void main(String[] args) {
    
            IHello iHello = name -> {
                String content = name + ": " + "happy new year everyone!";
                System.out.println(content);
            };
    
            // 这里可以把iHelo看成一个匿名实现类来传递参数
            sayHello(iHello, "mengday");
    
            // 如果去掉变量的接收,直接将Lambda表达式传递到参数中,此时Lambda表达式更像是一个函数
            // 也就是说JDK1.8竟然可以将一个函数作为参数传递到方法中,这是之前版本做不到的
            // 将函数作为方法的参数传递,一般用于回调函数,将回调函数传递到方法中
            sayHello(name -> {
                String content = name + ": " + "happy new year everyone!";
                System.out.println(content);
            }, "mengday");
        }
    }

    示例5:集合排序示例

    public static void main(String[] args) {
    
         // 写法一:使用匿名内部类
         // 好好学习,天天向上
         List<String> words = Arrays.asList("good", "good", "study", "day", "day", "up");
    
         // public static <T> void sort(List<T> list, Comparator<? super T> c)
         Collections.sort(words, new Comparator<String>() {
             @Override
             public int compare(String s1, String s2) {
                 // 降续排序
                 return s2.compareTo(s1);
             }
         });
    
         System.out.println(words);
    
    
         // 写法二:使用Lambda表达式
         // 咱俩谁跟谁
         words = Arrays.asList("we", "two", "who", "and", "who");
         Collections.sort(words, (String s1, String s2) -> {return s2.compareTo(s1);});
         System.out.println(words);
    
    
         // 写法三:使用Lambda表达式(简写)
         // 有事起奏,无事退朝
         words = Arrays.asList("if", "you", "have", "something", "to", "say", "then", "say!",
                 "if", "you", "have", "nothing", "to", "say", "go", "home!");
         Collections.sort(words, (s1, s2) -> s2.compareTo(s1));
         System.out.println(words);
     }

    函数式接口@FunctionalInterface


    从我们自定义的IHello示例来看,Lambda表达式其实是一种接口类型的数据类型,严格的说Lambda表达式的数据类型是:函数式接口,是一种特殊的接口,该接口使用@FunctionalInterface注解来标记(不是必须的,可以不用该注解标记,IHello接口就没有使用该注解标记, ),并且接口中只能有一个抽象方法,可以有多个静态方法或者默认方法, 每一个该类型的lambda表达式都会被匹配到这个抽象方法。

    @FunctionalInterface
    public interface Comparator<T> {
        int compare(T o1, T o2);
        // 其它static、default方法
    }
    

    @FunctionalInterface: 该注解没啥太大含义,该注解是给编译器做检查使用的,如果使用了该注解,编译器就会检查该接口中的抽象方法是不是只有一个,如果有多个就会报错:在接口Xxx中找到多个非覆盖抽象方法

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface FunctionalInterface {}

    我们完善一下我们的IHello, 使用@FunctionalInterface注解

    @FunctionalInterface
    public interface IHello {
        void sayHello(String name);
    }

    我们可以将lambda表达式当作任意只包含一个抽象方法的接口类型,也就是说我们的IHello接口无论叫什么名字,接口中的方法无论叫什么名字都无所谓(只是可读性更好些),因此可以再进行抽象化一下,JDK1.8中提供了这样的函数式接口,我们也不需要再定义IHello接口了,JDK1.8中提供了Supplier、Consumer、Function、BiFunction,这几个是比较常用的

    Supplier< T > 供应商:没有参数,有返回值

    @FunctionalInterface
    public interface Supplier<T> {
        T get();
    }

    Consumer< T > 消费者: 只有一个参数,没有返回值

    @FunctionalInterface
    public interface Consumer<T> {
        void accept(T t);
    }

    Function< T, R > 函数:一个参数,一个返回值

    @FunctionalInterface
    public interface Function<T, R> {
        R apply(T t);
    }

    BiFunction< T, U, R > 二元函数:两个参数,一个返回值

    @FunctionalInterface
    public interface BiFunction<T, U, R> {
        R apply(T t, U u);
    }

    Comparator< T > 比较器:接收两个参数,返回比较的结果

    @FunctionalInterface
    public interface Comparator<T> {
        int compare(T o1, T o2);
    }

    使用以上四大函数式接口来取代自定义的接口IHello

    public class Main {
        private static String end = ".";
    
        public static void main(String[] args) {
            // 直接使用JDK1.8提供的接口,不需要再定义IHello接口, 直接使用JDK提供的接口来接收Lambda表达式
            Supplier<String> supplier = () -> "mengday: happy new year everyone!";
            String result = supplier.get();
            System.out.println(result);
    
            Consumer<String> consumer = (name) -> System.out.println(name + ": " + "happy new year everyone!");
            consumer.accept("mengday");
    
            Function<String, String> func = (name) -> name + ": " + "happy new year everyone!";
            String hi = func.apply("mengday");
            System.out.println(hi);
    
    
            // 在代码块的内部可以访问静态全局变量
            // 在代码块中可以访问外边局部变量
            // 在代码块的内部可以修改全局静态变量
            // 在代码块内部是不能访问接口中的其它方法的
            String split = ": ";
            BiFunction<String, String, String> biFunction = (String name, String msg) -> {
                end = "!";
                String hello = name + split + msg + end;
                return hello;
            };
            String hello = biFunction.apply("mengday", "happy new year everyone");
            System.out.println(hello);
    
            // 根据字符串长度比较大小
            Comparator<String> comparator = (s1, s2) -> s1.length() - s2.length();
            int compare = comparator.compare("abc", "ab");
            System.out.println(compare);
        }
    }

    Predicate< T > 断言 谓词: 用于测试一个条件的真假

    
    package java.util.function;
    import java.util.Objects;
    
    @FunctionalInterface
    public interface Predicate<T> {
        // 在给定的参数上评估这个谓词
        boolean test(T t);
    
        // 返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND
        default Predicate<T> and(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) && other.test(t);
        }
    
        // 返回表示此谓词的逻辑否定的谓词,相当于not
        default Predicate<T> negate() {
            return (t) -> !test(t);
        }
    
        // 返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑或
        default Predicate<T> or(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) || other.test(t);
        }
    
        // 返回根据 Objects.equals(Object, Object)测试两个参数是否相等的谓词
        static <T> Predicate<T> isEqual(Object targetRef) {
            return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object);
        }
    }
    

    Main

    public static void main(String[] args) {
        // 可以构造复杂的条件: 并且and、或者or、否negate
        String email = "mengday@gmal.com";
        Predicate<String> predicate = (str) -> str.length() > 20;
    
        // 测试 emial.length > 0 的boolean
        boolean result = predicate.test(email);     // false
    
        // 测试 !(emial.length > 0) 的boolean
        result = predicate.negate().test(email);    // true
    
        Predicate<String> orPredicate = (str) -> str.contains("@");
        // 测试 emial.length > 0 or emial.contains("@")
        result = predicate.or(orPredicate).test(email);     // true
    }

    我的微信公众号:

    展开全文
  • 宝马汽车属于高档类汽车,其总线网络集成非常独特,它总线控制系统很特色,各类总线通信功能并不复杂但很强大,宝马轿车总线网络系统主要有以下两种。 1、以E38/E39/E46/E53等底盘车型为代表总线网络...
  • 6、80C51单片机要用传送指令访问片内程序存储器,它指令操作码助记符是以下( )。 A、MOV B、MOVX C、MOVC D、MUL 7、假定设置堆栈指针SP值为37H,在进行子程序调用时把断点地址进栈保护后,SP值为( )。 ...
  • 1. 关于LoadTimeWeaving1.1 LTW与不同的切面织入时机AOP——面向切面编程,通过为目标类织入切面的方式,实现对目标类功能的增强。按切面被织如到目标类中的时间划分,主要有以下几种:1.运行期织入这是最常见的,比如在...
  • 本公众号持续分享DLP相关最新技术及应用,敬请关注!6.3 DMD高速图像曝光实验6.3.1 DMD曝光成像实验结果分析上...DMD属于高精密器件,实际用于光刻曝光时需要均匀光源照明以获得更 好曝光效果,以下DMD实际...
  • DICOMcloud服务器可以通过当前实现的功能(qido-rs,wado-uri,wado-rs和stow-rs)与任何DICOMweb客户端接口。 官方文档和示例可以在这里找到: 在线版本: 在线版本托管在Azure中: : DICOMweb客户端演示在...
  • 通过接口输入模拟电路描述听起来是构成功能一种通用方法。但是,在你收起烙铁之前,应该更多地了解功能块在实际应用中性能究竟多好。  大多数行业都其哲学上激烈争论,如果仅从纯粹娱乐价值出发,...
  • 实现可扩展软件系统是我一直目标和想法。...知道了实现插件系统有以下的核心流程: 1. 定义插件接口,并在各个功能组件中实现这些接口  2. 在主程序中,通过遍历所需目录下dll文件,查询实现该接口的type...
  • 装饰者模式(Decorator Pattern)是指在不改变原有对象基础上,将功能附加到对象上,提供了比继承更弹性方案(扩展原有对象的功能),属于结构型模式。装饰者模式适用于以下场景: 扩展一个类的功能或给一个...
  • 通过接口输入模拟电路描述听起来是构成功能一种通用方法。但是,在你收起烙铁之前,应该更多地了解功能块在实际应用中性能究竟多好。  大多数行业都其哲学上激烈争论,如果仅从纯粹娱乐价值出发,...
  • 主板与CPU搭配

    2014-01-17 20:22:42
    此外,还内建了千兆网络连接和硬件防火墙功能,支持多种功能的SATA RAID模式,USB2.0接口数提升到了10个。nForce4 SLI则在Ultra的基础上多提供了两个PCI-EX16接口,通过特殊的转换来实现双显卡协同工作的SLI模式,...
  • 后台管理员权限管理实现

    千次阅读 2019-10-01 14:29:31
    需求:在一个前后端分离项目里,实现对于“系统管理员”类用户权限管理功能。 每个管理员都可以属于一个或者多个角色; 每个角色权限进行一个或者多个操作。 设计: 权限控制分成两层,分别是接口...
  • 一:简介JDK升级目的有以下几个:增加新的功能、修复bug、性能优化、简化代码等几个方面,Lambda表达式就是属于简化代码,用于简化匿名实现类,提供一种更加简洁写法。Lambda表达式在Swift语言中称之为代码块,...
  • 移动通信系统中基站主要负责与无线有关各种功能,为MS(移动台)提供接入系统UM接口,直接和MS通过无线相连接,系统中基站发生故障对整个移动网影响是很大。引起基站故障原因很多,但大多可归为以下四类...
  • C#基础(四)

    2020-03-12 10:34:38
    接口和类一样都属于引用类型,它可以用来描述属于类或结构一组相关功能,即定义了一种协议或者规范和标准,接口里面只允许未定义方法,它里面东西没有任何实际意义。它可以约束类行为,例如一个类实现了...
  • PAGE / NUMPAGES 以下关于多媒体技术的描述中错误的是多媒体技术就是能用来观看的数字电影技术 以下硬件设备中不是多媒体硬件系统必须...并具有音视频处理功能的计算机文档收集自网络仅用于个人学习 以下接口中一般不能
  • 命令(Command)模式:又称Action模式或者Transaction模式。它属于对象行为模式。命令模式把一个请求或者操作封装到一个...命令模式是有以下角色: 抽象命令(Command)角色:声明执行操作的接口。 具体命令(Conc
  • 计算机网路复习题1

    千次阅读 2020-04-16 23:15:06
    1. 下列选项中,不属于物理层接口规范定义范畴是。 A. 接口形状B. 引脚功能C. 物理地址D. 信号电平 【答案】C 【解析】 物理层包含以下四种接口特性: (1)机械特性:指明接口所用接线器形状和尺寸、引脚数目...
  • SAN与NAS虽然在功能很多相同之处,但它们还是很大区别以下我们讨论两者之间相同之处。   1.SAN和NAS共同特征:  (1)都用于扩展存储容量和性能,都可以随这大容量存储增长而逐步扩展,具有较好...
  • 事实上,目前网上现存的类似功能的程序也就能计算简单数据类型的基本四则运算,间或能够实现少许函数功能,功能极度简单。这里我们期望实现一个像MATLAB等软件那样的具有相当强大功能的计算工具! 1.3 MATLAB等软件...
  • 1创建git node 高并发,不会有回调地狱 服务端处理跨域问题,主要就是通过设置 Access-Control-Allow-Origion 使用jwt验证登录过程中,服务端生成token的方法是?...以下属于接口测试工具的有 postman ind...
  • ISP 功能的优点: ①在系统中编程不需要移出微控制器。 ②不需并行编程器仅需用P15,P16 和P17,这三个IO 仅仅是下载程序的时 候使用,并不影响程序的使用。 ③结合上位机软件免费就可实现PC 对其编程硬件电路连接...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 196
精华内容 78
关键字:

以下属于接口功能的有