这样封闭包装起来是有好处的,其中最重要一条就是信息隐藏,可以隐藏实现细节,防止客户意外修改数据.
说到客户,我们有必要提一下程序开发人员的角色.首先就是创建者.或者称为:服务端.
另一个就是使用者,或称为:客户端.有时我们写出一个程序以供别人使用,我们就是创建者了,我们不希望使用者对我们所写的东西进行修改.那么封装就是非常重要的了.我们只留给使用者必须的接口,
隐藏其它一切实现细节.
我们时刻 要注意角色的区别.我们是创建者时,我们需要修改我们程序时,不要影响到客户端的使用体验,
这样做是为降低客户与服务的耦合,修改服务时不用修改客户,修改客户时也不会影响服务.
有时我们又是使用者,我们拿来别人开发好的模块,对其进行使用.有时可能我们不满意这个模块或者是类提供的功能.
有可能我们会对这个模块进行修改.但是要记住一条原则,那就是我们只能对原有的类进行扩展.千万不要去修改.这是许多设计原则所提到的事情.
一旦我们扩展了原有类,我们就继承了原有类的数据与行为.我们可以节省大量重构的时间.所以继承是我们代码复用的基础.
定义:继承是面向对象软件技术当中的一个概念,继承可以使得子类具有父类的属性和方法.
例:
class A{
public:
int a;
void setA(int a){
this->a = a;
}
};
class B : public A {
public:
int b;
};
上面的代码就是继承的基本形式.B类公有继承了A类.那么B类对象就拥有了A类的所有数据与函数.再加上自己的特有的属性int b.就目前代码来说,定义一个B val; val有两个成员,一个是int a; 一个是int b;因为它从A类那里继承过来一个成员.
class B : public A
在这里我们发现了权限关键字 public
如果没有继承.类的客户只有其对象的调用者和它的子类.
类中的权限说明就是针对调用者的说明.
但有了继承之后,子类也有客户
子类的客户包括. 子类的调用者 与 子类的子类
在C++中,继承按访问权限也分为三种,公有继承,保护继承与私有继承.
这个关键字描述了.子类在继承之后, 子类的客户,对父类成员 各种权限的,访问权限
用的最多的是 public 继承, 子类的子类访问父类时,父类的公有还是公有(可访问), 保护的还是保护, 私有的还是私有,
第二种是 protected 继承, 子类的子类访问父类时,父类的公有变成保护(可访问), 保护变私有(不可访问), 私有还是私有(不可访问)
还有就是 private 继承, 子类的子类访问父类时,父类的所有成员都变成私有的不可访问.
对于子类对象的调用者来说.它只可访问公有继承下的公有成员.其它的皆不可访问.
继承还可按继承的类多少分为单继承与多继承.子类只继承于一个类时,叫单继承,如果同时继承了两个或两个以上的类,叫多继承.
继承不仅可以继承数据,而且还可以继承行为.
现在在B类当中,虽然没有声明setA函数,但是它已经从父亲继承过来.我们可以直接对它进行使用,就像是自己的类本来就有的一样
B valb;
//我们可以这样对SetA进行使用.
valb.setA(8);
如果我们希望这个函数在子类有不一样的行为.我们可以在子类对这个函数"重写".
例如:
class B : public A {
public:
int b;
void setA(int a){
this->a = a + 8;
}
};
这样,当B类对象再运行这个函数的时候,执行的就是B类本身具有的行为.
valb.setA(8); //执行htis-> a = a + 8;
子类的同名的函数就把父类的函数 "覆盖" 了,在子类,父类的这个函数不再可见.
当然,还有很多聪明人想的更深远一些..(呵呵..)
既然子类与父类的函数同名..那能不能重载呢? (呵呵呵..)
虽然我个人极力反对这样的行为..但是它确实可以的.
C++有一个关键字叫using 可以对名字进行声明.
class B : public A {
public:
int b;
using A::setA ; //这样,在子类里就声明了父类的名字.
void setA(int a,int b){
this->a = a + 8 + b;
}
};
这样setA这个父类的名字.就在子类起了作用,就可以和子类的函数进行重载了.