Object与封装、继承和多态性
在面向对象编程思想中,无论是C++,Java还是C#等,封装、继承与多态性都有着无与伦比的地位,深入理解并掌握它们是必不可少的。而我将使用C#来浅谈继承与多态性。
1.封装:
封装就是把里面实现的细节包起来,这样很复杂的逻辑经过包装之后给别人使用就很方便,别人不需要了解里面是如何实现的,只要传入所需要的参数就可以得到想要的结果。封装很好理解,像我们常见的函数,就是一种封装。还有
类将一些函数一数据封装。类是比函数更高级的一种封装方法。
2.继承:
新类(即派生类)通过继承将获取基类的所有非私有数据和行为以及新类为自己定义的所有其他数据或行为。因此,新类具有两个有效类型:新类的类型和它继承的类的类型。
public class A{ public A() { }}public class B : A // B 直接继承自 A{ public B() { }}
从上面的代码与图形可与看出B直接继承自A,那么B就拥有了A的除了私有数据与行为外的所有部分,但在为B分配内存时,却包涵了A的部分,那么在B的内存中也包含A的私有数据和行为的部分,那么又为什么说B没有这部分呢?要解决
这个问题就要先理解类的结构:类自己的所有成员对自己都是可见(可访问)的,但类的实例只可以访问它的公有(public)成员,如下:
public class A{ private int temp; protected int temp2; public int temp3;}public class B : A{ public int temp4;}
此时,B的可见成员有 temp2,temp3,temp4 ,由于 temp 是 A 的私有成员,所以在继承时不包含它。但在 B 的内存里确实有一块是用来存放A的,而在存放 A 的部分里又有一部分存储 temp ,所以在B的存储空间里也存放着 temp 这个量。
只不过类 B无法直接访问temp,如果说B继承了A的temp,那么B就应该可以直接访问temp,但实际上并不能直接访问,所以说我们说:在继承时,子类确实包含了父类的所有部分,但子类自己所能访问的只有父类的非私有部分和自己新定义
的部分,即实际继承时,只从父类继承了其非私有部分。
3.多态性:
多态按字面的意思就是“多种状态”。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针(或引用)赋值给父类类型的指针(或引用)。
从上图看出,“汽车”,“小轿车”,“马车”等都继承自“车”,但他们除了公有的“车”这个属性外,都不相同。一组类,它们都继承自同一个类,但各自拥有的新的不同的属性,使得它们都不相同,呈现出多种状态的现象,就是所谓的多态。
4.object类:
在C#(与Java)中,所有的类都直接或间接的继承自 object 类,即 object 是所有类的基类。在我们定义类是,如果不显示指明基类,在编译时,编译器都会默认为继承自 object 类。为什么要这样做呢?当然是为了充分的体现
和利用面向对象思想的优点--即多态性的利用。
在学习C#时你也许会忽略一个重要的知识点: 向上转型和向下转型
class A{ pubic void A_Text() { Console.WriteLine("I'm A!"); }}class B{ public void B_Text() { Console.WriteLine("I'm B!"); }}void Sample(object obj){ if(obj is A) { A a=(A)obj; //向下转型 a.A_Text(); } else if(obj is B) { B b=(B)obj; //向下转型 b.B_Text(); }}A a=new A();B b=new B();Sample(a) //向上转型Sample(b) //向上转型
可以看出,通过向上与向下转型使得我们在遇到类似于上面(通过另一个函数来调用一个对象的成员)的情况时,不需要根据参数类型写多个重载函数,实现了代码的简化,可读性更强。还有接口的实现也是通过多态来实现的,可见,使用多态的好处有很多,
只不过要真正体会其好处和掌握多态,需要大量的实践!!!
object 类充分用到了前面讲的封装、继承与多态,并将它们的作用发挥到了极致,学会使用 object 是我们学习和使用C#不可或缺的部分。在这里只是简单提了一下 object ,如果真正的深入讲 object 类可能将是长篇大论,如果以后有时
间可能会专门研究一下 object 的成员与使用。