.NET基础拾遗系列第一篇



 



.NET基础拾遗系列第一篇:.NET的几个基本概念(上) 
开篇小引                                                                                      
     虽然做.NET后台开发很久了,但是我是今年1月底的时候经朋友介绍才发现博客园的,然后每天都像登录腾讯一样,登上博客园,发现这里的人真多,看到了很多高手,像下面提到的和加为关注的,都是我理想要完成的写作,你还不是程序员了,连博客园都没有账户,我来的太晚了!!!
     看过了anytao的《你必须知道的.net》,看过了伍迷的《大话设计模式》,内心就不安了,之所以觉得他们都是牛人,不错,因为他们都是mvp,都是高手,他们对了.net平台的基础内功都是很深厚,不过鄙人不才,看的书不多,精读的也不多,所以只能写这些基础—《.NET基础拾遗系列》来发闷下,解析内心的夙愿。这些基础概念以及知识点可能就是新手曾经碰到过的,亦或者是投简历面试亲临过的,在这里我将用文字和代码来一起拾遗,希望大家多多给力!如果你是高手不值得看下,或者是久经沙场的大牛,那就请你飘过就可以了,类菌体会记住你的...呵呵…
 
基本概念列表开始                                                                            
       面向对象思想
       类和对象的区别
       private,protected,internal,public修饰符
       属性与get,set
       静态的类和成员函数都是静态的
       构造函数也有用
       重载和重写也参与
       接口来了,抽象也来了
       最后说说工厂
       关键字this和base得作用
       索引器和迭代器
 
 
第一篇由于要说的概念比较多,另外加上代码例子,所以我把基本概念分开来说,第一篇(上)就说说下面几个 
 
面向对象思想
类和对象的区别
private,protected,internal,public修饰符
属性与get,set访问器静态的类和成员函数都是静态的
  
(一)面向对象思想                                                                     
  
    其实学过一点C++的人都知道,面向对象就是程序并发的一种机制,他有几个重要的特征,分别是:封装,继承,多态要实现以面向对象编写程序,那你要记得把复杂的项目抽象分成几个对象的模型,然后就可以开始写类的结构,声明变量以及实现成员类型(包括接口和结构体),最后通过类的实例处理完成一定的问题的解决。相对于面向过程,面向对象注重人的思维,可以实现程序快速开发,当你把程序分成多个模块时,更加体现了分工负责的思想,有更低的耦合度,类是面向对象的重要概念,而对象的作用也不能忽视,打个比方,动物是个大说法,可以有鸟类,而鸟类又有分有燕子,布谷鸟,乌鸦等等,燕子,布谷鸟,乌鸦是从鸟类中派生出来的,他们具有鸟类特有飞的特征,但另外他们也具有自己特有的特点,如图:

  
  
  类和对象图示



下面代码显示这个思想
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace oop
{
class Program
{
staticvoid Main(string[] args)
{
Console.WriteLine(
"---------------请输入猫头鹰对象的体重和身高(以回车隔开)------------------");
string w = Console.ReadLine();
string l = Console.ReadLine();
Owl a_Owl
=new Owl(w,l);
Console.WriteLine(
"猫头鹰对象创建成功!!");
Console.WriteLine(
"猫头鹰的体重是"+a_Owl.weight +"kg");
Console.WriteLine(
"猫头鹰的身高是"+a_Owl.length +"cm");
Console.WriteLine(
"猫头鹰的特征是"+ Owl.message);
Console.WriteLine(
"猫头鹰的生存在"+ Owl.habitat);
Console.WriteLine(
"猫头鹰跟猫很像吗?"+ Owl.cat());
Console.WriteLine(
"---------------程序结束!!------------------");
Console.ReadLine();

}

}
class Mammal //动物全称
{
protectedstaticbool Feeding =true;//有哺乳的特点
}
class Bird:Mammal//鸟类
{
protectedstaticbool catlike =true;//类似猫
protectedstaticbool Fly=true;//可以飞行
}
class Owl : Bird
{
//有自己的特征
internalstaticstring message="猫头鹰吃老鼠";
internalstaticstring habitat ="丛林高树上";
internalstring weight; //体重
internalstring length; //身高
internal Owl(string w, string l)//构造函数直接赋值
{
this.weight = w;
this.length = l;
}
internalstaticbool cat()//通过静态方法获取继承的信息
{
return Owl.catlike;
}

}
}
 
程序创建了一个对象,并访问部分数据和方法,编译后结果显示如下: 
 
  
 
(二)类和对象的区别                                                                   

 

1.概念
     类(class)就是指一事物,对象(object)就是这一事物的实体,如:学生和大学生,学生是一个事物,大学生就是这个事物的实体。
     类是一种数据类型,特定的类型的变量与类的实例注意区别,在与很多数据有关的操作上,两者的体现是类似的,类有很多的不同类型的实体组成,包括字段,属性,方法,事件,索引器运算符,构造函数和析构函数等等,这些都是类的成员,每一个对象可以通过存储在字段中的值来表现某一定的信息,对象的取值组合表达对象现在的状态,对象都是有生命期的,程序在对象运行期间,对象就可以构造出来,此时,类中的方法就自动被调用(初始化,分配数据资源).
     类中可以定义相当的数据和方法,类通过构造函数生成对象,对象实现类的定义而且拥有具体的数据字段,类的定义必须在Class关键字之后的大括号内完成,而对象的创建是使用new关键符来操作(即使没有参数但是也要写一对空的圆括号来表现下这个是无参数的构造函数).
下面代码显示这个思想
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CObject
{
class Program
{
staticvoid Main(string[] args)
{

Console.WriteLine(
"请输入学生对象的类型(Schoolchild,M_Student,Undergraduate)");
string type = Console.ReadLine();
Console.WriteLine(
"请输入学生对象的体重");
string height = Console.ReadLine();
Console.WriteLine(
"请输入学生对象的类型代号(1代表Schoolchild,2代表M_Student,3代表Undergraduate)");
int num = Convert.ToInt32(Console.ReadLine());
switch (num)
{
case1:
Schoolchild sc
=new Schoolchild(type, height);
Console.WriteLine(
"你创建一位名字叫"+Schoolchild.name+"的人");
Console.WriteLine(
"他是一名"+sc.type);
Console.WriteLine(
"他的身高是"+sc.height+"cm");
Console.WriteLine(Schoolchild.Message);
break;
case2:
M_Student ms
=new M_Student(type, height);
Console.WriteLine(
"你创建一位名字叫"+ M_Student.name +"的人");
Console.WriteLine(
"他是一名"+ ms.type);
Console.WriteLine(
"他的身高是"+ ms.height +"cm");
Console.WriteLine(M_Student.Message);
break;
case3:
Undergraduate un
=new Undergraduate(type, height);
Console.WriteLine(
"你创建一位名字叫"+ Undergraduate.name +"的人");
Console.WriteLine(
"他是一名"+ un.type);
Console.WriteLine(
"他的身高是"+ un.height +"cm");
Console.WriteLine(Undergraduate.Message);
break;
default:
Console.WriteLine(
"对不起,你输入有误,请重新输入!!");
break;

}
Console.ReadLine();
}

}
class Schoolchild //小学生类
{
internalstaticstring name ="小明";
internalstaticstring Message ="小明在小学校园捡到一分钱";
internalstring type;//学生类型
internalstring height;//身高
internal Schoolchild(string type, string height)
{
this.type = type;
this.height = height;
}
}
class M_Student //中学生类
{
internalstaticstring name ="小红";
internalstaticstring Message ="小红在中学校园捡到一块钱";
internalstring type;//学生类型
internalstring height;//身高
internal M_Student(string type, string height)
{
this.type = type;
this.height = height;
}
}
class Undergraduate //大学生类
{
internalstaticstring name ="类菌体";
internalstaticstring Message ="类菌体在大学校园捡到一百块钱";
internalstring type;//学生类型
internalstring height;//身高
internal Undergraduate(string type, string height)
{
this.type = type;
this.height = height;
}
}
}



例子很简单,不过还算很能体现类和对象的关系,3个学生类的图示如下
解析:学生就是描述各不同层次学生对象的特征和状态,行为的模板,如大学生当中的一员就是学生当中的一个对象的实体 ,创建完对象就可以自动调用类中的方法完成所要的操作
 
编译结果:
 


 
(三) private,protected,internal,public修饰符                            
 
 
1.private
     该修饰符用于设置类或者类的成员的访问权限只可以在所属的类内部访问,它也叫私有修饰符,在分层架构的项目中要访问到私有类成员,可以使用get和set访问器读取,private最大的作用就是实现程序字段和方法的保护.
2.protected
     用于设置类或者类访问权限只可以为所属类和子类的内部,需要注意,跟private  对比是private可以访问所修饰的是类或者类成员的内部,而protected是在它的基础上还可以继承所属类的子类的成员访问.
3.internal
     用于设置类或者类成员的访问权限为同一程序集内部,它是c#默认的类访问权限,我上面举出的大量例子就是使用了该修饰符,实现提供类外部代码访问的功能.
4.public
     属于公共访问权限,对代码的访问没有任何的权限,不过在很多情况下我们要慎重使用该修饰符,搞不好话,会破坏类的封装特征,带来没有必要的代码安全祸害.
5.总结
     鉴于这几个修饰符跟类的封装特征很相关,所以记录下自己查资料和记笔记对封装的思考,正确使用这几个修饰符 参考:《你必须知道的.NET》
   (1)字段通常定义为private,属性通常实现为public,而方法在内部实现为private,对外部实现为public,从而保证对你内部数据的可靠性可读写控制,保护了数据的安全和可靠,提供与外部接口的有效交互,这是类得以有效封装的基础机制.
   (2)通常情况的理解我们就是上面(1)的规则,但是具体的操作还是要具体实质出发.
   (3)从内存和数据持久性角度可以知道,有一个我们必须知道的事实:封装属性提供了数据持久化的有效手段,因为,对象的属性和对象一样在内存期间是常驻的,只要对象不被垃圾处理,他的属性将一直存在,而且记录都是最新的一次更改后的数据.
 
(四属性与get,set访问器                                                             
 
 
问题:想想为什么c#不提倡字段的访问设置为public呢?
解答:因为那样子会使用户可以直接读写字段的值,带来潜在的危险,为避免又要保证与用户数据交互,所以使用属性 .
问题:类菌体能不能简单说明下属性和get,set的使用?
解答:非常可以,我们学习c#基础,除了知道为什么要用属性之外,还要知道他怎么用,怎么和get,set访问器在封装思想中一起使用,以及这使用过程有什么思想可保留,其实通过get和set访问器,可以很方便访问私有成员,其对外部曝露的就是熟悉或者索引器,在大多项目中属性比较常用,类的属性在使用当中和一般的类成员没有什么区别,不过他主要是通过内部实现的方法,即通过get和set访问器完成,当直接读取属性名称的时候,使用get访问器,执行"相关数据操作"的内容,相当于执行有返回值的数据类型的方法;当直接赋值给属性名称时,被赋值的新值将替掉隐参数values,执行相关的数据操作。
 
编写的格式:
访问修饰符  数据类型  属性名称
{
     get {[访问修饰符2] 相关的数据操作;}
     [访问修饰符3] set{和value关键字有关的操作}
}
 
代码例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CGs
{
class Program
{
staticvoid Main(string[] args)
{
Console.WriteLine(
"请输入用户名:");
LoginMsg dl
=new LoginMsg(); //创建对象dl
dl.Username = Console.ReadLine();
Console.WriteLine("Username的属性写入完成!");
Console.WriteLine(
"你输入的用户名为{0}(读取Username的属性值)",dl.Username);
Console.Write(
"请输入密码:");
dl.Password
= Console.ReadLine();
Console.WriteLine(
"Password的属性写入完成!");
Console.WriteLine(
"你输入的密码为{0}(读取Password的属性值)", dl.Password);
Console.ReadLine();
}
}
class LoginMsg
{
privatestring _username;
privatestring _password;
publicstring Username
{
get { return _username; }
set { _username = value; }
}
publicstring Password
{
get { return _password; }
set { _password = value; }
}

}
}
 
编译结果:
 
       
 
 
 五)静态的类和成员函数都是静态的                                               
 
 
     为什么标题说都是静态的呢?因为他们都是有static修饰符作用下的,由static所修饰的类或者成员都是静态类或者静态成员,其实我也比较喜欢使用静态类和静态方法了,记得好像是我08年用.NET开发的单层数据库网站就是创建一个公共的静态数据库操作类(Db_base.cs),给大伙看下这个静态的类和静态的成员函数,怀旧下单层封装思想,呵呵..
 
View Code
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Web;
using System.Data.OleDb;
using System.Data;

namespace Sophie
{
///<summary>
/// db 的摘要说明。
///</summary>
publicclass db
{
public db()
{
}
///<summary>
/// 创造一个数据库连接函数
/// ex:CreateConnetion()
///</summary>
///<returns>返回一个数据库连接对象</returns>

privatestatic OleDbConnection CreateConnection()
{
string databasestr = System.Configuration.ConfigurationSettings.AppSettings["connstr"];
string constr;
constr
="provider=Microsoft.Jet.OleDb.4.0;data source="
+ System.Web.HttpContext.Current.Server.MapPath(@databasestr);
OleDbConnection con
=new OleDbConnection(constr);
return con;
}

///</summary>
/// 构造一个通用的OleDbParameter
/// ex:PrepareCommand(new OleDbparameter("@me","你们好"),true,sqlstr,conn)
///<param name="conn">数据库连接对象</param>
///<param name="sqlstr">sql操作字符串</param>
///<param name="typed">是否使用OleDbParameters的参数数据</param>
///<param name="parm">OleDbParameters的参数娄组</param>
///<returns>返回一个数据库操作对象</returns>

privatestatic OleDbCommand PrepareCommand(OleDbConnection conn, string sqlstr, bool typed, OleDbParameter[] parm)
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
OleDbCommand com
=new OleDbCommand("", conn);

com.CommandText
= sqlstr;
if (typed)
{
foreach (OleDbParameter parmitem in parm)
{
com.Parameters.Add(parmitem);
}
}
return com;
}

///<summary>
/// 返回查询数据的第一行第一列
///</summary>
///<param name="conn">同上</param>
///<param name="sqlstr">同上</param>
///<param name="typed">同上</param>
///<param name="parm">同上</param>
///<returns>返回一个object对象</returns>
publicstaticobject ExecuteScalar(string sqlstr, OleDbParameter[] parm)
{

OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, true, parm);
object show = com.ExecuteScalar();

conn.Close();
com.Parameters.Clear();
return show;
}

publicstaticobject ExecuteScalar(string sqlstr)
{

OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, false, null);
object show = com.ExecuteScalar();

conn.Close();
com.Parameters.Clear();
return show;
}

///<summary>
///</summary>
///<param name="conn">同上</param>
///<param name="sqlstr">同上</param>
///<param name="typed">同上</param>
///<param name="parm">同上</param>
///<returns>返回受影响的行数</returns>
publicstaticint ExecuteNonQuery(string sqlstr, OleDbParameter[] parm)
{
OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, true, parm);
int show = com.ExecuteNonQuery();

conn.Close();
com.Parameters.Clear();
return show;
}

publicstaticint ExecuteNonQuery(string sqlstr)
{
OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, false, null);
int show = com.ExecuteNonQuery();

conn.Close();
com.Parameters.Clear();
return show;
}
///<summary>
/// 构造一个datareader的函数
///</summary>
///<param name="conn">同上</param>
///<param name="sqlstr">同上</param>
///<param name="typed">同上</param>
///<param name="parm">同上</param>
///<returns>返回一个向前读的流的对象OleDbDataReader</returns>
publicstatic OleDbDataReader ExecuteDataReader(string sqlstr, OleDbParameter[] parm)
{
OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, true, parm);
OleDbDataReader dr
= com.ExecuteReader(CommandBehavior.CloseConnection);
return dr;
}

publicstatic OleDbDataReader ExecuteDataReader(string sqlstr)
{
OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, false, null);
OleDbDataReader dr
= com.ExecuteReader(CommandBehavior.CloseConnection);
com.Parameters.Clear();
return dr;
}

///<summary>
/// 构造一个dataview的函数
///</summary>
///<param name="sqlstr">同上</param>
///<param name="typed">同上</param>
///<param name="parm">同上</param>
///<returns>返回一个dataview的对象</returns>
publicstatic DataView ExecuteDataview(string sqlstr, OleDbParameter[] parm)
{

OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, true, parm);
OleDbDataAdapter pter
=new OleDbDataAdapter(com);
DataSet ds
=new DataSet();
pter.Fill(ds,
"datasource");
DataView dataShow
= ds.Tables["datasource"].DefaultView;
conn.Close();
com.Parameters.Clear();
return dataShow;

}

publicstatic DataView ExecuteDataview(string sqlstr)
{

OleDbConnection conn
= CreateConnection();
OleDbCommand com
= PrepareCommand(conn, sqlstr, false, null);
OleDbDataAdapter pter
=new OleDbDataAdapter(com);
DataSet ds
=new DataSet();
pter.Fill(ds,
"datasource");
DataView dataShow
= ds.Tables["datasource"].DefaultView;
conn.Close();
com.Parameters.Clear();
return dataShow;

}
}

}
 
     在这个类当中都采用了静态成员方法,此时我就没有必要创建实例实现,直接为静态类成员,静态成员在访问的时候直接引用类名而不用对象名,此时你要注意,像this关键字就不可以访问静态成员,此时的成员可以作多个对象访问共享的数据,当类中没有和对象实例相关得成员,只有静态成员时,可以声明该类为静态类,静态类不可以用new创建对象,自然而然不可以编写构造函数
 静态类的声明如下代码:
访问修饰符   static  class  类名称
{
      静态类成员1;
      静态类成员2;
      静态类成员3;
}
 
最后注意:类中的常数声明和类型声明都默认为静态,即这个类默认为static无法被所属类对象访问的.
 
代码例子:
 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CStatic
{
class Program
{
staticvoid Main(string[] args)
{
Console.WriteLine(
"------类访问静态方法-------");
Console.WriteLine(
"今天的新闻的主角是:");
MyStatic.ShowName();
Console.WriteLine(
"------对象访问非静态方法-------");
MyStatic ms
=new MyStatic();
Console.WriteLine(
"因为他"+ms.Msg);
Console.ReadLine();
}
}
class MyStatic
{
publicstaticstring Name="类菌体"; //静态字段
publicstring Msg="在06年的时候考上北京航天航空大学,祝贺他!";//非静态字段
publicstaticvoid ShowName()//静态的成员
{
Console.WriteLine(Name);
}
publicvoid ShowMsg()//非静态的成员
{
Console.WriteLine(Msg);
}
}
}
 
编译结果:
 

附加内容:从软件工程理论看待                                                         
 
附加内容:从软件工程理论看待目前使用最广泛的软件工程方法学:传统方法(结构化方法),面向对象方法
区别下这两个方法:
结构化方法,也称为生命周期方法学或结构化范型。将软件生命周期的全过程依次划分为若干个阶段,采用结构化技术来完成每个阶段的任务。  特点:  (1) 强调自顶向下顺序地完成软件开发的各阶段任务; (2) 结构化方法要么面向行为,要么面向数据,缺乏使两者有机结合的机制。
面向对象方法,是将数据和对数据的操作紧密地结合起来的方法。 软件开发过程是多次反复迭代的演化过程。 面向对象方法在概念和表示方法上的一致性,保证了各项开发活动之间的平滑过渡。 对于大型、复杂及交互性比较强的系统,使用面向对象方法更有优势。
所以,很有必要知道面向对象方法的真正思想!
 
结尾致谢:                                                                                  
感谢《大话设计模式》
感谢《你必须知道的.net》
谢谢大家给力!!!!
 
 

作者:类菌体
出处:http://www.cnblogs.com/bacteroid/archive/2011/04/11/2012739.html
关于作者:在校学生
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接
如有问题,可以通过2050372596 联系我,非常感谢。

posted @ 2011-04-11 17:43  类菌体  阅读(3197)  评论(32编辑  收藏  举报