[C#学习笔记]面向对象
编写程序只不过是对象堆砌而成的,这些对象可以是独立的,也可以是从另外一个对下岗继承过来,对
成都创新互联长期为1000多家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为昌江黎族企业提供专业的成都网站建设、网站建设,昌江黎族网站改版等技术服务。拥有十载丰富建站经验和众多成功案例,为您定制开发。
象之间可以传递消息,并通过消息来改变自身的状态.
类是对象的模板.即类是对一组由相同数据和相同操作的对象的定义,一个类所包含的方法和数据描述
一组对象的共同属性和行为.类是在对象之上的抽象,对象则是类的具体化. 类可以有其子类,也可有
其他类,形成类层次结构.
类是对具有相同属性和行为的一组形似的对象的抽象.
面向对象的基本特征: 封装,继承,多态
Object是所有的类的基类.
定义类与创建类的对象
class Myclass{
//类的主题
}
★★★★类的修饰符
在定义类是,可以在类的前面添加访问修饰符,类的修饰符用于控制被访问的范围.默认情况下,类的修
饰符为private
new仅允许在嵌套类定义时使用,以表明类中隐藏了由基类中继承而来的与基类中同名的成员
public类可以在任何地方访问
protected只能从所在类和所在类的派生出来的子类进行访问,不能实例化,只能继承.
★★★★创建类的对象
MyClass myclass = new MyClass();
结构的定义:
结构与类相似,主要区别在于:类是存储在堆上的引用类型,而结构式存储在堆栈上的值类型,以及访问
方式和一些特征(例如:结构不支持继承);
定义结构:
在语法上,定义结构和定义类非常相似,主要区别是定义结构使用struct关键字代替class关键字.对于
类和结构,都是用new关键字生声明实例
struct FirstStruct{ //声明结构
//代码
}
FirstStruct first = new FirstStruct(); //实例化结构
类的数据成员:
构造函数,析构函数,常数,字段,方法,属性,索引器,运算符,事件,委托,类,接口,结构.
方法:
public string FangFa(){
return "返回值";
}
public void FangFa(){
Message.Show("无返回值");
}
★★★★ref关键字
可以通过引用为方法传递参数,不过若通过引用为方法传递参数,需要使用ref关键字.
string sex ="www";
Person p = new Person();
string name = p.GetName(ref sex); //这里将会把sex值改为女
Console.WriteLine("");
class Person {
public void GetName(ref string sex)
{
sex="女";
}
}
★★★★out关键字
out关键字和ref关键字很相似,out关键字也会导致参数通过引用来传递.与ref关键字不同之处在于
ref要求变量必须在传递之前进行初始化.如果使用out关键字,方法定义和调用方法都必须显示使用
out关键字.尽管作为out参数传递的变量不必再传递之前进行初始化,但必须在方法中为out参数赋值.
在方法中传递参数时使用out关键字,便是这个变量要回传值.最简单的运用时除法,例如你需要一个除
法方法,同时得到余数和商.但是普通的方法只能返回一个值,这个时候就可以使用out参数,把另一个
值返回.
int i = 15;
int j = 6;
int yushu;
Person p = new Person();
Consol.WriteLine();
class Person{
public int GetShangYuShu(int i,int j, out int yushu){
yushu = i%j;
return i/j;
}
}
★★★★重载
在C#中,类成员都有一个唯一的签名,而方法的签名由名称\参数个数和参数数据类型组成.只要签名不
同,就可以在一种类型内定义具有相同名称的多种方法.当定义两种或多种具有相同名称的方法时,就
称重载.
通俗的讲: 方法重载就是方法名相同,参数个数或参数类型不同.
string name ="小米";
int age = 21;
Peson p = new Person();
p.GetName();
p.GetName(name,age);
class Person{
public void GetName(){//重载方法1
//代码
}
public void GetName(string name){ //重载方法2
//代码
}
public void GetName(string name,int age){ //重载方法3
//代码
}
}
★★★★静态方法
定义静态方法和定义非静态方法相似,只是在定义静态方法时,需要在返回类型前加static关键字.静
态放在程序启动时系统会在内存里为静态方法创建一个实例,不需要再手动去实例静态方法.通过类名
可以直接调用静态方法,还有就是静态方法会在内存中占一定的内存空间.
在类中一旦定义了静态方法,name在类中就可以直接通过类名调用静态方法,并不需要通过实例化对象
访问静态方法.
注意:系统一旦为静态方法分配了内存空间,静态方法就会一直占用.所以在系统内存比较小时,尽量少
用静态方法.
public static string GetName(){
return"www";
}
扩展方法使你能够向现有类型"添加",而无需创建新的派生类型\重新编译或以其他方式修改原始类型
.扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.因此,通过扩咱方法
,就可以在不修改一个类型的前提下对一个类型进行功能上的扩充.
★★★★扩展方法
扩展方法使你能够向现有类型"添加"方法,而无需创建新的派生类型,重新编译或以其他方式修改原始类型.扩展方法时一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.它定义在静态类中,但可以在其他类的对象上像调用实例方法那样进行调用.因此,通过扩展方法,就可以在不修改一个类的前提下对一个类进行功能扩充.
扩展方法和一般的静态方法的定义类似,唯一区别是在第一个参数的前面加上关键字this作为修饰符,同时第一个参数也决定了扩展方法可以扩展的类型.
public static class AddClass{
public static string GetLower(this string str)
{
return str.ToLower();
}
public static string GetName(this Student stu)
{
return "扩展方法";
}
public static string GetCanShu(this Student stu,string str) //带参数的扩展方法
{
return str; //返回参数str
}
}
public class Student{
//这里没有代码
}
//----------调用代码
string URL = "HTTP://WWW.XXX.COM"; //要转化为小写字母的字符串
URL.GetLower(); //结果: http://www.xxx.com
Student s = new Student(); //实例化Student类
s.GetNme(); //结果: 扩展方法
string str = "扩展方法参数" //结果:扩展方法参数
//------------扩展方法的特点
1.扩展方法是给现有类型添加一个方法.
2.扩展方法是通过制定关键字this修饰第一个参数
3.扩展方法必须声明在静态类中.
4.扩展方法要通用对象来调用.
5.扩展方法可以带参数.
★★★★属性
在C#编写的程序中,属性提供灵活的几只读取或编写私有字段的值.使用属性可以像使用公共数据成员一样使用属性,单实际上它们是称作"访问器"的特殊方法.这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性.
对于类的实例化对象,属性显示为字段.对于类的构造来说,属性是一个或两个代码块:表示一个get访问器和set访问器.当读取属性时,执行get访问器的代码块;当向属性分配一个新值时,执行set访问器的代码块.value关键字用于定义set索引器分配的值.
语法格式
public string PropertyName
{
get{
return "返回私有变量的值或返回其他一些有意义的值";
}
set{
//为属性相关的私有变量赋值
}
}
例子:
public class Student{
string _name; //声明私有字段
public string Name{
get{
return _name
}
set{
_name = value;
}
}
}
Student stu = new Student();
stu.name = "属性";
//------set索引器可以进行判断,改写代码如下
set{
if(value=="属性"){
_name = "你是输入的是属性,符合要求"
}else{
_name = "你输入的非法";
}
}
以上看出在使用set索引器为属性赋值时,可以对赋值的数据进行判断,提高安全性.
★★★★自动属性
当属性访问器中不需要其他逻辑时,自动实现的属性可以使属性声明变得更加简洁.
一旦在类中声明了自动属性,那么编译器将创建一个私有的匿名后备字段,但是这个私有字段只能通过属性的get和set访问器进行访问.
自动属性必须同时声明get和set访问器.若要穿件只读自动属性,必须在set访问器前加private关键字.
声明:
public class Student
{
public int Age{
set;
get;
}
}
Student stu = new Student();
stu.Age = 15;
//感觉自动属性没什么用!
★★★★构造函数
构造函数具有与类相同的名称,他通常初始化新对象的数据成员.在类中不带参数的构造函数为类的默认构造函数,除非类是static(即静态类)的,否则C#编译器将为无构造函数的类提供一个公共的默认构造函数,一便该类可以实例化.无论何时,只要使用new关键字实例化对象,不提供参数就会调用默认构造函数.
注意: 如果构造函数设置了私有构造函数(使用private关键字),那么该类不能被实例化.
如果声明的构造函数带有参数,那么我们在实例化时也必须提供相应的参数,否则会出错.但是同时有声明了不带参数的构造函数,就调用该构造函数,也就是说的重载.
构造函数的特征:
1.类的构造函数函数名与类名相同
2.构造函数没有返回值
3.一般情况构造函数为public
★★★★对象初始化器
对象初始化器(Object Initializers)和集合初始化器(Collection Initializers)就是简化代码,让本来几行才能写完的代码一行写完.
作用:可以在创建对象时向对象的任何可访问的字段或属性赋值.
例子:
class Student{
public string name;
public string sex{get; set;} //自动属性
}
Student stu = new Student{name = "名字",Sex = "男"}; //使用{}以;结束
Student stu = new Student{Sex = "男"}; //也可以只为其中一个字段赋值
★★★★析构函数
在C#中很少使用析构函数,但是,当应用程序疯长窗口,文件,网络连接等这类非托管资源时,应当使用析构函数释放这些资源.
1.不能再结构中定义析构函数,只能对类使用析构函数
2.一个类只能有一个析构函数
3.无法继承或重载析构函数
4.无法调用析构函数,他们被自动调用
5.析构函数没有修饰符,也没有参数
例子:
public class Student{
~Student(){
//和类名相同,前面加~符合
}
}
★★★★readonly关键字
readonly修饰符只能用于字段(不能用于局部变量),只能在构造函数和声明中赋值.
例:
public class RendKey{
public readonly string Name;//声明没有赋值,只能在构造函数中进行赋值
public readonly string Age = 15; //声明时赋值(正规书写格式首字符大写)
}
与const修饰符的区别
1.readonly修饰的字段即使在声明时赋值了也可以在构造函数中对其进行更改. const修饰符声明时必须赋值,以后任何情况下都不允许更改.readonly修饰符即可以是实例字段也可以是静态字段.
2.将readonly应用于一个数组,不会冻结数组的内容.它只会冻结数组中的元素数量,因为现在无法将只读字段重新赋值为一个新的实例,数组中的元素仍然是可写的.
★★★★类的继承
类了除了继承于类还可以继承于接口,C#中类只能继承一个类,多重继承使用继承多个接口来实现.
子类从父类中继承了所有非私有数据和行为(属性,方法),可以说子类是对父类的扩展,但是构造函数和析构函数是不会被继承的.
语法格式:
public class BaseClass{
//父类
}
public class MyClass : BaseClass{
//子类
}
★★★★虚方法
在一个基类中,使用virtual修饰符修饰方法,属性,索引器或事件声明,那么他们就可以在派生类中被重写.使用
virtual关键字在基类中修饰的方法,就是平常所说的虚方法.在派生类中使用override关键字重写虚方法.
注意:成员字段和静态方法都不能声明为virtual,因为这个概念只对类中实例成员有意义.
class Person {
public virtual void Work(){
Console.WriteLine("这是一个虚方法");
}
}
class Student : Person{
public override void Work(){
Console.WriteLine("通过override关键字重写Work虚方法");
}
}
Student stu = new Stutent(); //实例化Student类
stu.Work();
★★★★调用方法的基类版本
在派生类中,可以使用base关键字访问基类成员,base关键字指定创建派生类实例时应用调用的基类构造函数,但
是不能在静态方法中使用base关键字.
1.关键字用于从派生类中访问基类的成员:
2.调用基类上已被其他方法重写的方法。
3.指定创建派生类实例时应调用的基类构造函数。
4.基类访问只能在构造函数、实例方法或实例属性访问器中进行。
★★★★隐藏方法
在派生类中,使用new关键字可以显示隐藏从基类继承的成员.若要隐藏继承的成员,请使用相同名称在派生类中
声明该成员,并用new修饰符修饰它,该成员就是独立于基类的方法.
例子:
class Person{
public string name = "小王";
public string sex ="男";
public void WriteInfo()
{
Console.WriteLine("人员信息:姓名{0},性别:{1}",name,sex);
}
}
class Student : Person
{
new public void WriteInfo(){
Consol.WriteLine("学生信息:姓名{0},性别:{1}",name,sex);
}
}
Student s = new Student();
s.WriteInfo();//这里调用子类的WriteInfo()方法
★★★★C#中重写父类方法的几种情况
关键字:virtual、abstract、override、new。
1. virtual:标识可能但不是必须被子类重写的方法,父类必须给出默认实现,子类可以重写(使用
override,new,或无特殊标识的普通方法),也可以不重写该方法。
2. abstract:标识必须被子类重写的方法,父类并不给出实现,子类必须用override关键字重写该方法。
3. override:标识重写父类的方法,父类方法必须是用abstract,virtual,override之一声明,运行时将根
据 实例的类型而不是引用的类型调用对象的方法。
4. new:标识重写父类的方法,父类方法可以用virtual、override、new之一声明,也可以是没有特殊标识的
普 通方法,运行时会根据引用的类型选择调用父类还是子类的方法,重写父类方法时,使用new关键字与使
用没 有特殊标识的普通方法是等效的,但是后者会给出一个编译警告。
★★★★抽象类和抽象方法
抽象类是一种特殊的类,他可以拥有数据成员,可以是其他类的子类.但是和具体类(非抽象类)不同,抽象类的某
些行为故意留给其子类来定义.
在C#中使用abstract关键字声明抽象类.abstract关键字可以和方法,属性,索引器及事件一起使用.标记为抽象
或包含在抽象类中的成员必须通过从抽象类的子类中在实现.
注意:抽象类不能够实例化,需要通过子类重写抽象类中的成员方法,然后实例化子类来实现.
抽象方法也是由关键字abstract声明,抽象方法需要使用;号结束,这和常规定义的方法块不同.抽象方法只能在
抽象类中声明.
例子:
class Person{
public abstract void Work(); //定义了一个抽象类
}
class Student{
public override void Work(){//使用override关键字重写抽象类
Console.WriteLine("重写抽象方法");
}
}
Student s = new Student();
s.Work();
★★★★密封类和密封方法
在应用程序中,有时候开发人员编写的类,并不希望被继承或没有必要被继承,为此C#提出了密封类的概念,密封
类在声明中使用sealed关键字.这样就可以防止类别其他类继承.
密封类可以组织其他开放人员在无意中继承,而且密封类可以起到运行时优化效果.
如果视图将一个密封类作为其他类的基类,C#将提示出错.密封类不能同时又是抽象类,因为抽象类是需要被继承
的,可以说sealed关键字不能喝abstract关键字一起使用.
密封类不可能有派生类,如果密封类实例中存在虚成员函数,该成员方法可以转化为非xude ,方法关键字将不再
生效.
class Person{
public virtual void Work(){
Console.WriteLine("声明封闭类时需要继承一个父类,不能直接声明");
}
}
sealed class Student : Person //使用sealed关键字声明封闭类
{
public sealed override void Work(){
Console.WriteLine("使用sealed关键重写父类的方法");
}
}
Student s = new Student();
s.Work();
★★★★部分类
★★★★接口
在应用程序中,接口就是一种规范,接口封装了可以被多个类继承的一些公共部分.但是接口不能包含字段.声明
接口使用interface关键字,接口中的成员默认是public,所以在声明成名方法时不需要加public关键字.接口中
的成员必须是非静态的.
例子:
interface Person{
//string name; 如果包含字段,程序将会报错.
void Work();
}
class Student : Person{
public void Work(){
Console.WriteLine("这个类继承与接口类Person");
}
}
Student s = new Student();
s.Work();
当前标题:[C#学习笔记]面向对象
链接分享:http://myzitong.com/article/jijjjs.html