面向对象编程(Object Oriented Programming,OOP)。
面向对象的三大特性
特性 |
优势 |
封装 |
保证对象自身数据的完整性、安全性 |
继承 |
建立类之间的关系,实现代码复用,方便系统的扩展 |
多态 |
相同的方法调用可实现不同的实现方式 |
一、封装
封装是面向对象的重要内容,是面向对象的三大特性之一。它用于隐藏内部实现,对外只暴露对象的基本操作,而不会让其他对象影响类的内部实现。在类中,构建封装字段,我们可以创建属性,将属性和字段封装在一起。保证了对象自身数据的完整性、安全性。
封装为我们带来如下好处:
- 避免使用非法数据赋值。
- 保证数据的完整性。
- 避免类内部发生修改时,导致整个程序的修改。
类的成员:字段、属性、方法
在C#中,我们通常不会直接访问类中的字段,而是通过get和set访问器来访问,这种实现方式我们称为属性。
如:
class Student
{
//字段
private stirng name;
private int age;
//封装好的属性
public string Name
{
get{ return name; }
set{ name=value;}
}
public int Age
{
get{ return age; }
set{
//属性是聪明的字段
if( value>0 && value<100 )
{
age=value;
}
else
{
age=18;
}
}
}
//方法
访问修饰符 返回类型 方法名(参数)
{
//方法体
}
}
二、继承
在C#中,一个类可以继承另一个类。如Student和Teacher类都继承Person类:
public class Student : Person { }
public class Teacher : Person { }
继承必须符合is a 的关系,被继承的类称为父类或基类,继承其他的类称为子类或派生类。
继承机制很好地解决了代码复用的问题,方便系统的扩展。
子类继承父类的成员,并且可以拥有自己特有的成员。
C#中,this关键字代表当前实例,通过它可以访问类本身的成员。base关键字代表父类,可以用于访问父类的成员。例如:在子类中,调用父类的属性、方法、构造方法。
继承具有传递性,如果class A : B ;class B : C,则A也可以访问C的成员。
C#中的继承具有单根性,一个类不能够同时继承自多个父类。
继承模拟了现实世界的关系,继承实现了代码的重用,继承使得程序结构清晰,子类和父类的层次结构清晰,最终的目的是使子类只关注子类的相关行为和状态,无须关注父类的行为与状态。
三、多态
多态是指两个或多个属于不同类的对象,对于同一个消息(方法调用)作出不同响应的行为方式。
使用抽象方法和虚方法都可以实现多态性。
使用抽象类和抽象方法实现多态
(1)抽象方法是一个没有实现的方法,通常在定义方法时增加关键字abstract 可以声明抽象方法。
访问修饰符 abstract 返回类型 方法();
(2)含有抽象方法的类必须是抽象类。但抽象类中可以有非抽象方法,且非抽象方法可以有方法体。同样,我们用abstract 关键字来定义一个抽象类。
访问修饰符 abstract class 类名 { }
常见错误:
1.对于抽象类有一个限制:它不能被实例化。
由于无法创建抽象类的实例对象,所以只能通过它的子类来实现该类的方法,除非它的子类也是一个抽象类。
2.抽象类不能是密封或者静态的:如果给抽象类增加密封类的访问修饰符sealed或者static,系统会提示错误,其实很容易理解,抽象类如果不被子类继承并实现它的抽象方法,便没有实际意义。
重写抽象方法:
抽象方法必须在其子类中实现,除非它的子类也是抽象类。在子类中的实现一个抽象方法的方式是使用override关键字来重写抽象方法。
访问修饰符 override 返回类型 方法(参数)
{
//方法体
}
使用虚方法实现多态
C#中用virtual 关键字修饰的方法称为虚方法。虚方法必须有具体的实现,在父类中提供默认实现,也可以被子类重写。
使用虚方法实现多态:
在父类中定义虚方法,然后在子类中可以重写虚方法,也实现了面向对象的多态。
虚方法是用virtual 关键字修饰的。
访问修饰符 virtual 返回类型 方法(参数)
{
//方法体
}
子类中重写父类的虚方法时,采用override关键字
访问修饰符 override 返回类型 方法(参数)
{
//方法体
}
总而言之,虚方法除了提供默认的实现之外,还可以重写自定义的实现方式,大大增加了程序的灵活性。
虚方法与抽象方法的区别
虚方法 |
抽象方法 |
用virtual修饰 | 用abstract修饰 |
必须有方法体,哪怕是一个分号 | 不允许有方法体 |
可以被子类override重写 | 必须被子类override重写 |
除了密封类外都可以写 | 只能在抽象类中 |
接口
接口:接口是某类行为或功能的抽象,是一种规范或者标准,或者说是一种契约。
C#中,一个类只能继承一个类,但能实现多个接口。
C#中,使用interface关键字来定义接口。
public interface IName { }
.NET中的接口的使用要注意以下几点:
(1)接口中可以包含属性、方法、索引器等(不包含字段),但是都不能够实现,接口中的方法和属性。
接口中的方法:
public interface ISampleInterface
{
void ShowName();
}
接口中的属性:
public interface ISampleInterface
{
string Name
{
get;
set;
}
}
(2)定义一个接口的名称通常都是以“I”开头。
(3)我们习惯说法是实现了一个接口,继承了一个类。
(4)实现一个接口的语法与继承类似:class Student : IComparable。
(5)如果类已继承了一个父类,则以“,”分隔父类和接口。
class Student : Person,IComparable
接口的典型应用:
(1)接口作为参数的意义:
接口作为参数传递时,实际上要传递的就是实现这个接口的对象。
(2)接口作为返回值的意义:
接口作为返回值实际上就是返回一个实现接口的对象。
接口小结:
(1)接口是继承单根性的扩张。
(2)接口是一种规范和标准。
(3)接口屏蔽了实现的细节。
(4)接口的使用方便团队协作开发。