C#中的封装、继承和多态
2015-01-11 20:38
190 查看
我们都知道,封装、继承和多态是面向对象的三大特性。但是对他们的理解还不是很深刻,这篇博客就主要讲解一下C#中的封装、继承和多态。
一、封装。
封装的概念,想必我们大家都已经了解了。比如,电视机和遥控器,我们无需知道他们的内部构造,只需要让他们交互即可。这就体现了封装的思想。
封装是面向对象的第一步。封装就是将数据或者函数等集合在一个个单元中,这些单元,我们称之为类。通俗来说,我们把程序分为很多块,块与块之间可能会有交互。所以,我们把一个块分为:可变部分和不可变部分。当一些信息变动时,我们只需要对可变部分进行修改即可。
那么封装是怎么实现的呢?
(1)传统读、写方法。举个简单的例子。
客户端的代码:
大家可以看到,上面name用的Private,我们不能直接访问Person的name,只可以通过读写这两个方法来访问。这样我们就可以保护私有数据不被窃取和破坏。
(2)使用属性实现封装。举个例子。
我们可以看到Person的name属性有两种方法set和get。此外我们可以设置只读属性和只写属性。这里就不一一介绍了。
二、继承。
继承,在面向对象和UML中,我们想必已经对继承的概念聊熟于心了。比如动物和人,就是一个类之上再建立一个类,这个类具有一定的特殊性。子类可以拥有父类的方法和属性,可以重写,也可以有新的方法和属性。我们再来看一下在C#中,我们是如何实现继承的呢?
我们都知道,一个“:”就表示了一个类与另一个类的继承关系。那么具体怎么来调用呢?
(1)关键字base。
从派生类中访问基类成员方法,我们可以通过使用base关键字调用基类的构造函数。
比如:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> public class Person
{
public string _name;
public Person(string name)//<span style="color:#ff0000;">Person中的构造函数</span>
{
this._name = name;
Console.WriteLine(_name);
}
}
public class student : Person
{
private uint _id;
public student (string name,uint id):base(name)//<span style="color:#ff0000;">base关键字调用Person类构造函数</span>
{
this ._id =id;
Console.WriteLine(_id);
}
}</span> 客户端代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> student objstudent = new student("xyz", 001);//构造student
</span>
(2)关键字new。例如:
<span style="font-family:KaiTi_GB2312;font-size:18px;">public class Base//基类
{
public static int val = 456;
}
public class Derived : Base//派生类
{
new public static int val = 123;//<span style="color:#ff0000;">new隐藏继承成员</span>
public static void main()
{
Console.WriteLine(val);
}
}</span> 客户端代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> Console.WriteLine(Derived.val);
</span> 输出结果为派生类中的val。
(3)关键字virtual和override
<span style="font-family:KaiTi_GB2312;font-size:18px;">class Person
{
public virtual void name()
{
Console.WriteLine("此方法显示姓名");
}
}
class student : Person
{
public override void name()
{
base.name();
Console.WriteLine("此方法显示学生姓名");
}
}</span>
上述代码中,virtual关键字的作用是标记name方法运行时才可以执行,而override关键字意在覆盖基类中的name方法。
三、多态。
我们首先要明确没有继承,就没有多态。不同对象收到相同信息产生的行为不叫做多态。子类重写父类的操作就可以实现多态。多态实现的方式有两种:覆写(实现运行时的多态)和重载(实现编译时的多态)。
(1)重载。类中定义方法的不同版本。通俗来说就是同一个方法名字,不同的实现结果。
要求:方法名相同,参数列表不同,返回值类型可以不同。
比如:
上面这段代码就实现了对caculate的重载。具有重载的三个特点:方法名相同(同为caculate);参数列表不同(一个参数类型为int,一个为double);返回值类型可以不同(返回值类型一个为int,一个为double)。
(2)覆写。子类中为满足自己需要来重新定义父类某个方法的不同实现。通过override关键字来实现。
要求:方法名称相同,参数列表相同,返回值类型相同。
比如:
<span style="font-family:KaiTi_GB2312;font-size:18px;">public class Test
{
public virtual int calculate(int x, int y)
{
return x + y;
}
}
public class Test2 : Test
{
public override int calculate(int x, int y)
{
return x * y;
}
}
</span> 这段代码就实现了对calculate的覆写。满足方法名、参数列表、返回值类型相同的特点。
最后比较一下重载和覆写:
对于这三大特性的理解还很浅,还需在以后的学习中加深啊!
一、封装。
封装的概念,想必我们大家都已经了解了。比如,电视机和遥控器,我们无需知道他们的内部构造,只需要让他们交互即可。这就体现了封装的思想。
封装是面向对象的第一步。封装就是将数据或者函数等集合在一个个单元中,这些单元,我们称之为类。通俗来说,我们把程序分为很多块,块与块之间可能会有交互。所以,我们把一个块分为:可变部分和不可变部分。当一些信息变动时,我们只需要对可变部分进行修改即可。
那么封装是怎么实现的呢?
(1)传统读、写方法。举个简单的例子。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>public class Person { private string name; public string Gettname()//读方法 { return name; } public void Setname(string aaa)//写方法 { name =aaa; } }</strong></span>
客户端的代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong> Person a = new Person (); a.Setname ("wmm"); Console.WriteLine(a.Gettname ()); </strong></span>
大家可以看到,上面name用的Private,我们不能直接访问Person的name,只可以通过读写这两个方法来访问。这样我们就可以保护私有数据不被窃取和破坏。
(2)使用属性实现封装。举个例子。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>public class Person { private string name; private string Name { get { return name; } set { name = value; } } } </strong></span>客户端的代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong> Person d = new Person(); d.name = "wmm"; Console.WriteLine(d.name); </strong></span>
我们可以看到Person的name属性有两种方法set和get。此外我们可以设置只读属性和只写属性。这里就不一一介绍了。
二、继承。
继承,在面向对象和UML中,我们想必已经对继承的概念聊熟于心了。比如动物和人,就是一个类之上再建立一个类,这个类具有一定的特殊性。子类可以拥有父类的方法和属性,可以重写,也可以有新的方法和属性。我们再来看一下在C#中,我们是如何实现继承的呢?
我们都知道,一个“:”就表示了一个类与另一个类的继承关系。那么具体怎么来调用呢?
(1)关键字base。
从派生类中访问基类成员方法,我们可以通过使用base关键字调用基类的构造函数。
比如:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> public class Person
{
public string _name;
public Person(string name)//<span style="color:#ff0000;">Person中的构造函数</span>
{
this._name = name;
Console.WriteLine(_name);
}
}
public class student : Person
{
private uint _id;
public student (string name,uint id):base(name)//<span style="color:#ff0000;">base关键字调用Person类构造函数</span>
{
this ._id =id;
Console.WriteLine(_id);
}
}</span> 客户端代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> student objstudent = new student("xyz", 001);//构造student
</span>
(2)关键字new。例如:
<span style="font-family:KaiTi_GB2312;font-size:18px;">public class Base//基类
{
public static int val = 456;
}
public class Derived : Base//派生类
{
new public static int val = 123;//<span style="color:#ff0000;">new隐藏继承成员</span>
public static void main()
{
Console.WriteLine(val);
}
}</span> 客户端代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> Console.WriteLine(Derived.val);
</span> 输出结果为派生类中的val。
(3)关键字virtual和override
<span style="font-family:KaiTi_GB2312;font-size:18px;">class Person
{
public virtual void name()
{
Console.WriteLine("此方法显示姓名");
}
}
class student : Person
{
public override void name()
{
base.name();
Console.WriteLine("此方法显示学生姓名");
}
}</span>
上述代码中,virtual关键字的作用是标记name方法运行时才可以执行,而override关键字意在覆盖基类中的name方法。
三、多态。
我们首先要明确没有继承,就没有多态。不同对象收到相同信息产生的行为不叫做多态。子类重写父类的操作就可以实现多态。多态实现的方式有两种:覆写(实现运行时的多态)和重载(实现编译时的多态)。
(1)重载。类中定义方法的不同版本。通俗来说就是同一个方法名字,不同的实现结果。
要求:方法名相同,参数列表不同,返回值类型可以不同。
比如:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>public class test { public int calculate(int x, int y) { return x + y; } public double calculate(double x, double y) { return x + y; } }</strong></span>
上面这段代码就实现了对caculate的重载。具有重载的三个特点:方法名相同(同为caculate);参数列表不同(一个参数类型为int,一个为double);返回值类型可以不同(返回值类型一个为int,一个为double)。
(2)覆写。子类中为满足自己需要来重新定义父类某个方法的不同实现。通过override关键字来实现。
要求:方法名称相同,参数列表相同,返回值类型相同。
比如:
<span style="font-family:KaiTi_GB2312;font-size:18px;">public class Test
{
public virtual int calculate(int x, int y)
{
return x + y;
}
}
public class Test2 : Test
{
public override int calculate(int x, int y)
{
return x * y;
}
}
</span> 这段代码就实现了对calculate的覆写。满足方法名、参数列表、返回值类型相同的特点。
最后比较一下重载和覆写:
重载 | 覆写 | |
方法名 | 相同 | 相同 |
参数列表 | 相同 | 不同 |
返回值 | 相同 | 可以不同 |
位置 | 继承关系中存在 | 同一类中存在 |
相关文章推荐
- 用一个简单示例来说明C#中的继承、封装和多态
- C#总结(三)—三大特性(封装、继承、多态)
- 学习C# 继承 封装 多态
- C# 面向对象三大特性:封装、继承、多态
- C#三大特性之 封装、继承、多态
- 关于C#面向对象三个特征:继承,封装,多态的说明
- c# 封装,继承,多态
- C# 面向对象:封装、继承、多态
- 3、C#面向对象:封装、继承、多态、String、集合、文件(下)
- C# 面向对象三大特性:封装、继承、多态
- 用一个简单示例来说明C#中的继承、封装和多态
- C# 学习历程——类的封装,继承与多态
- 《程序员的第一年》---复习一下C#的【封装 多态 继承 -----简单计算器源码实例】
- C# 面向对象三大特性:封装、继承、多态
- 关于C#面向对象三个特征:继承,封装,多态的说明
- C#中的继承封装和多态知识点总结
- C#的封装、继承和多态
- C#基础知识复习1代码规范-执行流程(c#)-面向对象-引用命名空间-封装-继承-访问修饰符-虚方法-静态成员-多态-抽象类等
- C# 面向对象特性 封装 继承 多态
- C# OOP模型(传说中的继承封装多态)