`

同名不同义——函数重载和构造函数

阅读更多

 

众所周知,三层的D层主要是对数据的处理,而一般我们三层习惯引入sqlhelper来处理D层的传入的参数,而具体处理就是传入或者不传入一个参数,返回一个bool值或者是一个数据集,所以,如果我们一一写出来就是这中情形:首先是一个带参数返回值为bool的函数,在写一个不带参数返回值为bool的函数,还有一个不带参数返回值为datatable的函数,最后是一个带参数返回值为datatable的函数,如果这四个参数如果设置不同的名字,这种在D层调用处理的时候还需要考虑需要调用那个函数,需要传入什么样的返回值才能符合要求,这是很麻烦的,这里我们就需要用到函数重载:

重载:

函数重载:在同一作用域内函数名相同而参数列表不同定义的来实现功能相同或相似的多个函数,即通过函数参数列表而唯一标识并区分函数的一种特殊的函数。

说明:

l  同一作用域内。

l  参数列表不同是指:参数类型、个数和顺序至少有一个不同。

l  不能通过函数返回类型来说明函数重载。

l  并不是只要功能相似或相同就一定要使用函数重载。如果不同的函数名所提供的信息可使程序更易于理解的话,则再用重载函数就没有什么好处了。如:←、→、↑、↓

重载决议:采用匹配算法根据函数中的实参来判定所有同名函数中哪个函数的形参与其相匹配。进行匹配检测的顺序与函数声明的顺序无关。

为了明确地确定调用哪个重载函数,编译器必须进行重载决议。编译器执行重载决议时,在同一个时间内根据某个参数来寻找“最佳匹配”的函数。

根据某个特定的参数,只要找到一个匹配的函数,搜索过程就会结束。

 

重载决议规则:为了确定调用多个同名函数中的某个函数,针对每个参数编译器都必须按顺序执行5类匹配过程。无论在哪类匹配过程,只要发现一个匹配,就停止对该参数的匹配搜索并开始对下一个参数做类似工作。

5类匹配过程:

完全匹配,包括添加限定符const和数组到指针的转换。

提升:char->int、usigned char->int、signed char->int、enum->int、short->int、usigned short->int、wchar->int、bool->int、float->double等。

标准转换:整型转换、浮点转换、浮点整型转换、指针转换、指针成员转换、基类转换。

用户自定义的转换:构造函数、运算符转换函数。

省略号转换序列:它由形参都是由省略号组成的任何函数组成。可以与任何实参匹配。

 

下面我们就写一下新闻发布系统的对SQLHelper的重载

 SQLhelper的抽象:

 

[html] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Data.SqlClient;  
  6. using System.Data;  
  7. using System.Configuration;  
  8. using System.Data.SqlTypes;  
  9. namespace DAL  
  10. {  
  11.     public class SQLHelper  
  12.     {  
  13.         private SqlConnection conn = null;  
  14.         private SqlCommand cmd = null;  
  15.         private SqlDataReader sdr = null;  
  16.         /// <summary>  
  17.         /// 设定连接数据库参数  
  18.         /// </summary>  
  19.         public SQLHelper()  
  20.         {  
  21.             string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString ;  
  22.             conn = new SqlConnection(connStr);  
  23.         }  
  24.         /// <summary>  
  25.         ///打开数据库  
  26.         /// </summary>  
  27.         /// <returns></returns>  
  28.         private SqlConnection Getconn()  
  29.         {  
  30.             if (conn.State == ConnectionState.Closed)  
  31.             {  
  32.                 conn.Open();  
  33.             }  
  34.             return conn;  
  35.         }  
  36.         /// <summary>  
  37.         /// 执行不带参数的增删改SQL语句或存储过程  
  38.         /// </summary>  
  39.         /// <param name="cmdText">增删改SQL语句或存储过程</param>  
  40.         /// <param name="ct">命令类型</param>  
  41.         /// <returns></returns>  
  42.         public int ExecuteNonQuery(string cmdText, CommandType ct)  
  43.         {  
  44.           int res;  
  45.           try  
  46.                 {  
  47.                 SqlCommand  cmd = new SqlCommand(cmdText, Getconn());  
  48.                     cmd.CommandType = ct;  
  49.                     res = cmd.ExecuteNonQuery();  
  50.                 }  
  51.          catch (Exception ex)  
  52.                 {  
  53.                     throw ex;  
  54.                 }  
  55.           return res;  
  56.         }  
  57.   
  58.         /// <summary>  
  59.         /// 执行带参数的增删改SQL语句或存储过程  
  60.         /// </summary>  
  61.         /// <param name="cmdText">增删改SQL语句或存储过程</param>  
  62.         /// <param name="paras"></param>  
  63.         /// <param name="ct">命令类型</param>  
  64.         /// <returns></returns>  
  65.         public int ExecuteNonQuery(string cmdText, SqlParameter[] paras,CommandType ct)  
  66.         {  
  67.             int res;  
  68.           try  
  69.             {  
  70.                 using (cmd = new SqlCommand(cmdText, Getconn()))  
  71.                 {  
  72.                     cmd.CommandType = ct;  
  73.                     cmd.Parameters.AddRange(paras);  
  74.                 }  
  75.                 res = cmd.ExecuteNonQuery();  
  76.             }  
  77.   
  78.             catch (Exception ex)  
  79.             {  
  80.                 throw ex;  
  81.             }  
  82.             return res;  
  83.         }  
  84.   
  85.   
  86.       /// <summary>  
  87.       /// 传入不带参数的SQL语句或存储过程  
  88.       /// </summary>  
  89.         /// <param name="cmdText">SQL语句或存储过程</param>  
  90.       /// <param name="ct">命令类型</param>  
  91.       /// <returns></returns>  
  92.         public DataTable ExecuteQuery(string cmdText, CommandType ct)  
  93.         {  
  94.   
  95.             DataTable dt = new DataTable();  
  96.             SqlCommand cmd = new SqlCommand(cmdText, Getconn());  
  97.             cmd.CommandType = ct;  
  98.             using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))  
  99.             {  
  100.                 dt.Load(sdr);  
  101.             }  
  102.             return dt;  
  103.   
  104.         }  
  105.   
  106.     /// <summary>  
  107.     /// 传入带参数的SQL语句或存储过程  
  108.     /// </summary>  
  109.         /// <param name="cmdText">SQL语句或存储过程</param>  
  110.     /// <param name="paras">参数数组</param>  
  111.     /// <param name="ct">命令类型</param>  
  112.     /// <returns></returns>  
  113.         public DataTable ExecuteQuery(string cmdText, SqlParameter[] paras,CommandType ct)  
  114.         {  
  115.             DataTable dt = new DataTable();  
  116.             cmd = new SqlCommand(cmdText, Getconn());  
  117.             cmd.CommandType = ct;  
  118.             cmd.Parameters.AddRange(paras);  
  119.             using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))  
  120.             {  
  121.                 dt.Load(sdr);  
  122.             }  
  123.             return dt;  
  124.         }  
  125.     }  
  126. }  

 

在外面平时运用中,有一种特殊的函数重载,就是构造函数。

构造函数

构造函数是一种特殊的方法 主要用来在创建对象时初始化对象 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 特别的一个类可以有多个构造函数 可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。

1.构造函数的命名必须和类名完全相同

 2.构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。而其他方法都有返回值,即使是void返回值。尽管方法体本身不会自动返回什么,但仍然可以让它返回一些东西,而这些东西可能是不安全的。  

3.构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的。   

4.当定义一个类的时候,通常情况下都会显示该类的构造函数,并在函数中指定初始化的工作也可省略,不过Java编译器会提供一个默认的构造函数.此默认构造函数是不带参数的。而一般的方法不存在这一特点。  

5当一个类只定义了私有的构造函数,将无法通过new关键字来创建其对象,当一个类没有定义任何构造函数,C#编译器会为其自动生成一个默认的无参的构造函数。

在牛腩新闻发布系统中,有这样一个问题,是如果我们在新闻列表中添加新闻时,新闻的ID是自动生成的,也就是说,我们的NEW类中无需传入ID这个参数,而在修改新闻列表的时候,又必须知道ID才能进行修改,也就是说,我们需要传入一个包含ID 的new类,在我没有接触到构造函数是这样做的:new类中包含ID这个参数,当时给他任意赋值(因为不能为空),在D层应用的时候不使用这个参数,当然,这里最大的缺点传入多于参数,使得代码累赘容易出错。下面是使用构造函数的代码:

这里定义了三个构造函数:

[html] view plaincopy
  1. public News()  
  2.        { }  
  3.        public News(string title, string content, string caid)  
  4.        {  
  5.            this.title = title;  
  6.            this.content = content;  
  7.            this.caid = caid;  
  8.        }  
  9.        public News(string id,string title, string content, string caid)  
  10.        {  
  11.            this.id = id;  
  12.            this.title = title;  
  13.            this.content = content;  
  14.            this.caid = caid;  
  15.        }  


这样,很函数重载一样,在调用的时候不需要考虑是不是需要传入ID,并且,在写代码的时候不会感觉到别扭。

更多信息请查看 java进阶网 http://www.javady.com

分享到:
评论

相关推荐

    构造函数重载

    2. **构造函数的重载**:重载意味着在同一个作用域内,可以有多个同名但参数列表不同的函数。在构造函数的情况下,这意味着一个类可以有多个构造函数,每个构造函数接受不同数量或类型的参数。这允许用户根据需要...

    C++高级参考手册,讲解C++ 语法,函数重载,构造函数等

    5. **函数重载**:函数重载允许在同一作用域内定义多个同名函数,但每个函数的参数列表不同。这是C++的多态性的一种体现,可以提供更加灵活的编程方式,让函数调用更具可读性。 6. **缺省参数**:C++允许函数参数...

    运算符重载和函数重载

    在C++中,可以通过重载构造函数来提供多种初始化方式。此外,拷贝构造函数是一种特殊的构造函数,用于从已存在的对象初始化新对象。 **构造函数重载** ```cpp TString() { StrVar = NULL; } TString(const TString...

    构造函数与析构函数

    构造函数是一个与类同名的方法,可以没有参数,有一个参数或多个参数,但是构造函数没有返回值。如果构造函数没有参数,该函数被称为类的默认构造函数。 (1) 一个类可以包含多个构造函数,各个构造函数之间通过...

    实验六函数重载与运算符重载

    编写Rectangle类,重载构造函数 **背景介绍**: - **Rectangle类**:表示一个矩形,拥有长和宽两个私有成员变量`iteLength`和`itsWidth`。 - **构造函数重载**:提供默认构造函数以及带参数的构造函数。 **代码...

    实验二:友元和函数重载

    函数重载允许在同一作用域内定义多个同名函数,但要求这些函数的参数列表不同(参数个数、类型或顺序不同)。这样做可以为相同的操作提供不同的接口,提高代码的可读性和可维护性。 1. **参数数量不同**:两个或多...

    友元函数的函数重载程序

    函数重载是指在同一作用域中可以有多个同名的函数,但这些函数的参数列表必须不同(即参数的数量、类型或顺序)。这样可以让程序更加简洁且易于理解。在这个例子中,`operator+` 和 `operator-` 都是重载了C++中的...

    章构造函数和析构函数PPT学习教案.pptx

    10. 函数重载允许在同一作用域内定义多个同名但参数列表不同的函数;构造函数重载是指在一个类中定义多个构造函数,每个有不同的参数列表,用于不同的初始化需求。 析构函数和构造函数一起确保了对象生命周期内的...

    构造函数与静态块的执行顺序

    构造函数可以被重载,即在同一个类中可以有多个具有不同参数列表的构造函数。 静态块(`static`)是在类定义中包含的一段特殊的代码块,它在类加载时执行,而不是在对象创建时执行。静态块常用于初始化静态变量或...

    函数参数缺省与重载,命名和缺省规则

    函数重载允许在同一个作用域内定义多个同名函数,但这些函数的参数列表必须有所不同,通常体现在参数数量或参数类型上。这种特性使得我们可以为相似的功能提供多种调用方式,而无需为每个变体创建单独的函数名。在...

    构造函数的继承问题 笔记

    3. **构造函数重载与父类构造函数的选择**:如果父类中有多个构造函数,子类可以通过`super()`后跟相应的参数列表来选择调用哪一个父类构造函数。 例如: ```java class Base { public Base() { System.out....

    面试必备的构造函数的重点

    构造函数可以被重载,即在同一类中可以定义多个同名但参数列表不同的构造函数,这称为构造函数的重载。 `malloc()`和`new`都是用来分配内存的,但它们之间存在显著差异。`malloc()`是一个C语言中的函数,它分配固定...

    解析C++中构造函数的默认参数和构造函数的重载

    重载意味着在同一个类中可以有多个同名但参数列表不同的构造函数。这是C++允许的,因为它可以根据传入的参数数量和类型来决定调用哪个构造函数。在上面的代码中,`Box` 类有两个构造函数: 1. 一个无参数的构造函数...

    c++面向对象实验 函数重载

    【函数重载】是C++面向对象编程中的一个重要特性,允许在同一作用域内定义多个同名函数,但每个函数的参数列表必须不同,这通常通过不同的参数类型、数量或顺序来实现。在实验中,这一特性被用于实现不同类型的变量...

    函数重载的重要性不言而明.docx

    在C++编程语言中,函数重载是一项关键特性,它允许在同一个作用域内定义多个同名函数,但每个函数的参数列表不同。这主要解决了命名冲突问题,提高了代码的可读性和可维护性。函数重载的关键在于,编译器能够通过...

    第十章运算符重载复习题.doc

    运算符重载是重新定义已有的运算符,使其适用于用户定义的数据类型,而函数重载是定义多个同名函数,但参数列表不同。 十二、面向对象编程的应用 运算符重载和函数重载都是面向对象编程的重要特性,通过它们可以...

    C#多态性实例,向基类构造函数传递参数.rar

    综上所述,这个"C#多态性实例,向基类构造函数传递参数"的示例展示了如何在C#中利用多态性、继承和构造函数来创建灵活、可扩展的代码结构。通过理解和应用这些概念,开发者可以编写出更高效、更具维护性的软件系统。

    C程序设计电子多态性和虚函数学习教案.pptx

    重载构造函数可以提供多种初始化对象的方式,比如传递不同的参数或执行不同的初始化逻辑。在实际编程中,这是创建具有不同初始化需求的对象时非常有用的。 在派生类中重载基类的成员函数,可以实现覆盖或扩展基类的...

    C++中构造函数重载

    总之,构造函数重载允许根据不同的初始化需求创建类的对象,而函数重载则使得我们可以根据上下文选择合适的函数执行,两者都是C++中提高代码灵活性和可读性的重要手段。了解并熟练运用这些概念,对于编写高效且易于...

    Java 重载、重写、构造函数的实例详解

    Java中的重载(Overloading)、重写(Overriding)和构造函数是面向对象编程中的核心概念,它们在实现代码的灵活性和可扩展性方面起着至关重要的作用。 首先,让我们了解一下重载。重载指的是在同一个类中,可以有多个...

Global site tag (gtag.js) - Google Analytics