继承:
这个世界到处是继承的例子比如动物是一个最基础的对象,人、猪、猫猫、狗狗都从动物继承了基本的属性和方法。继承就是一个层次结构,先抽象出一个基本的东西,然后具体的对象从这个基本的东西来继承,继承后再写他特有的,这样就可以做到复用了。
隐藏:
如果基类和继承类里有一样的方法,在子类里调用的时候会怎么样,到底使用的是哪个呢?看,现在执行到了子类的drawme方法了,这样就是子类把父类的那个方法给隐藏了,如果你要专门隐藏的话,最好在方法上加一个关键字 new,这样就不会有警告了,专门隐藏就是说子类的实现和父类中的完全不同,但我还想使用这样的名字的时候就要用到这种了。
覆盖:
比如基类中已经有了一个方法了,但个方法和我想要的不同,我想重新写一个有自己特点的,这里就有一个覆盖的概念,子类的方法覆盖父类的方法后,调用时也会执行子类的方法。virtual,override就是覆盖。
多态:
一个对象根据运行期执行了那个对象,从而调用该对象的方法的能力就是多态。刚才例子中的 shape的一个实例 指向了 矩形对象,也就是说,在运行期运行的时候shape实际上代表的是一个矩形,而不是一个图形对象,说简单点 就是我们把一个子类的对象赋给父类对象后,多态就出现了。
我写了一个方法,参数是基类,那你调用的时候可以根据情况传入不同的子类,这样写的代码就非常灵活,不需要写多个类似的代码了,这样做的好处是我的代码可以写一次就行了,如果加了薪的子类的话,我只需要加一个类而已,那个方法是不用变的。
抽象类:
以前我们学的类都是具体的类,里边的属性,方法都有具体的实现,但有时候基类里的某些方法是没有意义的 ,只能定义一个方法,没有具体的实现,这样的类就是一个抽象类。
形状里有个drawme的方法,对于形状来说,他肯定不知道把自己画成什么样子,只有具体的图形才知道,所以我们把这个方法定义成抽象的。抽象类是无法进行new的,它不是具体的,抽象类只能被继承,不能直接创建对象。
/// <summary>
/// 表示一个形状的类,这个作为基类 abstract 表示这个对象是抽象的
/// </summary>
public abstract class Shape
{
//表示面积,一个新的关键字 virtual 虚方法
protected int area;
public virtual int GetArea()
{
System.Console.WriteLine("Area is :" + area.ToString());
return area;
}
//这里定义一个抽象的方法,里面没有任何实现,具体的实现在它的子类里来处理
public abstract void DrawMe();
}
接口:
刚才我们定义了一个抽象类,抽象类里有一个方法,这个方法对这个类来说实现没有意义,只有子类里才有意义,但为了统一继承体系中的方法,需要在基类里定义一个方法,然后由子类来实现,这样看起来所有继承体系中的类都有一样的方法,也就是说同一个类,对外提供的方法是一样的,但可以有自己特有的实现。
现在我们把抽象类更进一步,这个类里中任何方法都是抽象的,没有一个实现,这样就变成了一个接口。接口你可以理解成一个合同,比如你和某人签了一个合同,合同里规定了你要做什么什么,但具体怎么做有执行的人去实现 。
一个类可以继承另外一个类,也可以继承一个抽象,也可以继承一个接口,C#里只能从一个类继承,不能同时继承多个类,但可以继承多个接口,就像一个类同时和很多接口签了合同一样。
面向对象有个很重要的原则就是面向接口编程,这是什么意思呢,就是说我们先定义一个接口,在程序里用的时候都是接口,不用关心他具体的实现,如果说,现在有个一个新的实现的话,我们的程序不需要修改,只加一个实现该接口的类就Ok了 ,可维护行很好。
/// <summary>
/// 定义一个接口 ,注意命名规范,接口以I开头
/// 这个接口中定义了两个没有实现的方法,由继承它的类来实现
/// </summary>
interface IShape
{
void DrawMe();
int Geteara();
}
static void Main(string[] args)
{
//通过 一个接口类型的对象指向了实现该接口的具体类,这也是多态,和昨天的概念是一样的
IShape circle = new Circle();
circle.DrawMe();
//这里使用 接口类型的对象来访问 Circel自己的方法时是找不到
//要想访问的话,需要先把接口类型转换成具体的类型
Circle a = circle as Circle;
//这里一般要加判断,避免类型转换失败
if (a != null)
{
a.Test();
}