现在的位置: 首页 > Web开发 > .Net > 正文

〔C# Note〕面向对象篇

2016年05月27日 .Net ⁄ 共 6500字 ⁄ 字号 暂无评论

面向对象编程的三大特点:封装,继承,多态。

一、封装
封装就是把数据组合在一起,形成一个对象。将类封装了以后,对外提供可访问的属性和方法,外部对象通过这些属性和方法访问此对象的信息。
类是支持对象封装的工具,对象则是封装的基本单元。

封装的好处:
1、良好的封装能够减少耦合。
2、类内部的实现可以自由地更改。
3、类具有清晰的对外接口。

封装性主要由访问修饰符来控制。
在这里有五个访问修饰符,public,private,protected,internal,protected internal。

public是“公共”的意思,若被这个访问修饰符所修饰,那么它会被任何地方访问到。

private是“私有”的意思,被这个访问修饰符所修饰的只能在它所在的类中被访问。

protected是“保护”的意思,被这个访问修饰符修饰的只能在它所在的类及其子类中被访问。

internal是“内部”的意思,被这个访问修饰符修饰的只能在它所在的项目内部被访问。其他项目无法访问。

protected internal是“内部受保护”的意思,被这个访问修饰符修饰的只能在项目内该元素所在类及其子类中被访问。

私有等级:private>protected internal>protected>internal>public
访问修饰符

枚举类型(enum)的默认修饰符为public,不可被其他访问修饰符修饰。

类中的字段,属性,方法等成员的默认修饰符为private可被其他任意修饰符修饰。

类(class)的默认修饰符为internal,可被其他任意修饰符修饰。

接口(interface)的默认修饰符为public,不可被其他修饰符修饰。

{关于接口}

//private interface Interface1错误在命名空间中定义的元素无法显式地声明为 private、protected 或 protected internal
//internal interface Interface1 Internal虽然可以修饰接口,但是不建议去用internal。因为我们的接口是要对外通信的,使用public以便于其他项目能够重复利用此接口的代码
public interface Internal1
{
//接口可以是方法、属性和事件,但是不能有任何成员变量,也不能在接口中实现接口成员。接口不能被实例化。接口的成员默认都是公共的,因此不允许成员加修饰符。
//void Interface() { }错误“面向对象篇.Internal1.Interface()”: 接口成员不能有定义
void Interface();
}

结构体(struct)的默认修饰符为private可被public,internal,private修饰。

public class ClassFather
{
private struct Date { public int day; public int month; public int year;};//结构成员默认为private,在声明结构体的时候对结构体内部元素前加上访问修饰符
//这是一个私有的字段,表明字段可以被private修饰
private int fieldPrivate;
//这是一个公有的属性,表示属性可以被public修饰
public int FieldPrivate
{
//这是属性的get方法,即取值方法,将私有字段fieldPrivate的值取出来。
get
{
return fieldPrivate;
}
//这是属性的set方法,即赋值方法,将属性的值赋值给私有字段。
set
{
fieldPrivate = value;
}
}
//这是一个公有的字段,表示字段可以被public修饰
public int fieldPublic;
//这是一个公有自动属性
public int FieldPublic { get; set; }
//这是一个内部字段
internal int fieldInternal;
//这是一个受保护字段
protected int fieldProtected;
//这是一个内部受保护字段
protected internal int fieldProtectedInternal;
//这是一个私有的自动属性
private int FieldPrivate_ { get; set; }
private void methodPrivate()
{
Console.WriteLine("这是一个私有方法");
}
public void methodPublic()
{


Date d;//与类一样,但可以不用new关键字
d.month = d.year = d.day = 0;
Console.WriteLine("这是一个公有方法");
}
protected void methodProtected()
{
Console.WriteLine("这是一个受保护方法");
}
internal void methodInternal()
{
Console.WriteLine("这是一个内部方法");
}
protected internal void methodProtectedInternal()
{
Console.WriteLine("这是一个内部受保护方法");
}
public ClassFather(int field1,int field2,int field3,int field4,int field5)//通过构造函数将值传递给字段
{
this.fieldPrivate = field1;
this.fieldPublic = field2;
this.fieldProtected = field3;
this.fieldInternal = field4;
this.fieldProtectedInternal = field5; //使用this 关键字可以调用此类中的成员变量
}


//其他的修饰符不做举例说明,大家可以自己尝试。
}
class Program
{
static void Main(string[] args)
{
//实例化ClassFather对象
ClassFather cf = new ClassFather();
//cf.fieldPrivate = 0;错误“面向对象篇.ClassFather.fieldPrivate”不可访问,因为它受保护级别限制 该字段只能在生命所在类中被访问并赋值
cf.fieldPublic = 0;//这个字段是public修饰的,所以在任何地方都是可以访问并赋值的。
cf.fieldInternal = 0;//这个字段是internal修饰的,所以是可以访问并赋值的。
//cf.fieldProtected = 0;错误“面向对象篇.ClassFather.fieldProtected”不可访问,因为它受保护级别限制 该字段是被protected修饰的,所以只能在该类及其子类中被访问并赋值的
//cf.fieldProtectedInternal=0;错误“面向对象篇.ClassFather.fieldProtectedInternal”不可访问,因为它受保护级别限制 该字段是被protected internal修饰的,所以只能在该类及其同一项目内的子类中被访问并赋值的
/************* 方法与字段同理 ***************/
//cf.methodPrivate();错误“面向对象篇.ClassFather.methodPrivate”不可访问,因为它受保护级别限制
cf.methodPublic();//这个方法是被public修饰的,所以在任何地方都是可以访问并调用的。
//cf.methodProtected();错误“面向对象篇.ClassFather.methodProtected”不可访问,因为它受保护级别限制
cf.methodInternal();//这个方法是被Internal修饰的,只要是在这个项目内就可以被访问并调用
//cf.methodProtectedInternal();错误“面向对象篇.ClassFather.methodProtectedInternal”不可访问,因为它受保护级别限制
}
}

输出结果为:
这是一个公有方法
这是一个内部方法

合理利用访问修饰符可以使项目中的数据得到有效的保护。使代码尽可能模块化,以便维护与调试。

二、继承
继承指的是一个类可以用继承于一个类的方式得到那个类里除了构造函数与析构函数之外的所有成员。被继承的那一个类称为基类(或父类),继承的那一个类称为派生类(或子类)。

继承的本质是代码重用。子类在继承父类既有的属性和方法的基础上,又有自己的特性。

继承常用与提炼出相同的特性,放于父类,起到减少代码重复的作用。

如果子类继承与父类。第一、子类拥有父类非private的属性和功能;第二、子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能;第三,子类还可以以自己的方式实现父类的功能(方法重写)。

子类可以从父类中继承的成员有方法、域、属性、事件、索引指示器,但对于构造方法不能被继承,只能被调用。对于调用父类的成员,可以使用base关键字。

如果不使用继承,如果要修改功能,那么就必须在所有的重复的方法中修改,代码越多,出错的可能就越大,而继承的优点是,继承使得所有子类公共的部分都放在了父类,使得代码得到了共享,这就避免了重复,另外,继承可使得修改或扩展继承而来的实现都较为容易。

继承也是有缺点的,如父类变,子类不得不变。继承是一种类与类之间强耦合关系。

class ClassSon:ClassFather //继承ClassFather类
{
public ClassSon(int field1, int field2, int field3, int field4, int field5)
: base(field1, field2, field3, field4, field5)
{
//使用base 关键字为父类的成员变量赋值
}
}

三、多态
多态是指同一个消息或操作作用于不同的对象可以有不同的解释,产生不同的执行结果。
在面向对象编程中多态性有两种:静态多态和动态多态。

多态表示不同的对象可以执行相同的动作,但要通过他们自己的实现代码来执行。
1、子类以父类的身份出现。
2、子类在工作时以自己的方式(代码)来实现。
3、子类以父类的身份出现时,子类特有的属性和方法不可以使用。
当在同一个类中直接调用一个对象的方法时,根据传递的参数个数、参数类型和返回值类型等信息决定实现何种操作,就是静态多态。
当在一个有着继承关系的类层次结构中间接调用一个对象的方法时,调用经过基类的操作,就是动态多态。

静态多态的实现——重载
重载是指允许多个同名函数,而这些函数的参数不同,或许参数个数不同,或许参数类型不同,或许两者都不同。

class Program
{
static void overload()//静态方法函数名前用static标志
{
Console.WriteLine("这是一个重载方法,返回值为空,参数为空");
}
static int overload(int value)//以int 为例,其他类型与int相同
{
Console.WriteLine("这是一个重载方法,返回值为int,参数为int "+ value );
return value;
}
static int overload(int value1.int value2)
{
Console.WriteLine("这是一个重载方法,返回值为int,参数为int,int " + value1 + value2 );
return value1;
}
static void Main(string[] args)
{
overload();
int value1 = overload(2);
int value2 = overload(3,4); //静态多态 函数重载调用
}
}

输出结果:
这是一个重载方法,返回值为空,参数为空
这是一个重载方法,返回值为int,参数为int 2
这是一个重载方法,返回值为int,参数为int,int 34

动态多态的两种实现方法:抽象类和虚方法
抽象类:使用abstract关键字来定义抽象类。在抽象类中使用abstract关键字声明一个抽象方法(但不定义)。在抽象类子类当中,必须使用override关键字重写这个抽象方法,在方法中定义自己需要的功能。抽象类不能实例化。如果类中包含抽象方法,那么类就必须定义为抽象类。

虚方法:在父类当中使用virtual关键字来定义一个虚拟方法(可以定义功能)。在子类当中去过需要改变父类虚拟方法功能,可以使用override关键字去重写父类的方法。除了字段不能为虚拟的之外,其他的属性、事件、索引器都可以使虚拟的

abstract class polymorphismFather //一个类中出现抽象方法,就必须把类声明为抽象类
{
public virtual void PolymorphismVirtual()
{
Console.WriteLine("这是一个父类虚方法");
}
public abstract void PolymorphismAbstsact();//抽象方法只声明不定义
}

class polymorphismA:polymorphismFather //继承抽象类polymorphisFather
{
public override void polymorphismVirtual()
{
Console.WriteLine("这是第一个子类重写虚方法");
}
public override void polymorphismAbstract()
{
Console.WriteLine("这是第一个子类重写抽象方法");
}
}

class polymorphismB:polymorphismFather
{
public override void polymorphismVirtual()
{
Console.WriteLine("这是第二个子类重写虚方法");
}
public override void polymorphismAbstract()
{
Console.WriteLine("这是第二个子类重写抽象方法");
}
}

class Program
{
static void Main(string[] args)
{
polymorphismFather pfA = new polymorphismA(); //将父类用里氏转换法转成子类对象
//调用方法时,先检查子类又没有对应的方法,没有再向父类检查,如此类推。
pfA.polymorphismVirtual();//调用子类polymorphismA 的重写虚方法
pfA.polymorphismAbstract(); //调用子类polymorphismA 的重写抽象方法

polymorphismFather pfB = new polymorphismB();
pfB.polymorphismVirtual();
pfB.polymorphismAbstract();
}
}

输出结果为:
这是第一个子类重写虚方法
这是第一个子类重写抽象方法
这是第二个子类重写虚方法
这是第二个子类重写抽象方法

面向对象思想:世间万物皆对象

参考资料:
博客园–《面向对象基础》-逆心
http://www.cnblogs.com/kissdodog/archive/2013/03/24/2979650.html

《C#程序设计》-杨律青 上海交通大学出版社

我是大一新生,最近在学习C#程序设计。这是根据自己的感悟总结的,如果有不足的地方欢迎大家在下方指出来帮我改正。自己第一次写博客,希望能得到大家的鼓励。

自己的第一幅插画