问题:举例说明什么是抽象、对象、类、实例、消息、封装性、继承性和多态性。(最好是能举出一个系统性的例子能将以上概念都能涉及到)
抽象
现在有狗和猫两只生物,我们不考虑它们的不同之处,而概括出它们都拥有毛发长短,年龄的属性,且都拥有会叫的行为的共同特征。从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程就是抽象。
类
我们将它们这种具有相同特征的事物抽象为一个类,这里我们将它们抽象为Animal类,这个类具有的属性是length(长短),age(年龄),方法是bark()。
classAnimal{
private:
stringlength;
public:
Animal(stringstr) {
length= str;
}
virtual voidbark() {
cout<<"我会叫"<< endl;
}
};
继承性
如果我们想建立一个新的类Dog,它与Animal这个类的内容基本相同,在后者的基础上添加了age(年龄)的属性,并添加了返回年龄的方法,则:
class Dog :publicAnimal {
private:
intage;
public:
Dog(stringstr,inta ) :Animal(str) {
age= a;
}
intShowAge() {
returnage;
}
};
如果我们想建立一个新的类Cat,它与Animal这个类的内容基本相同,在后者的基础上添加了age(年龄)的属性,并添加了与其它对象比较年龄大小的方法的方法,则:
class Cat :publicAnimal {
private:
intage;
public:
Cat(stringstr,inta) :Animal(str) {
age= a;
}
void CompareAge(inta) {
if (age > a) cout
<< "我大"<< endl;
else if (age == a) cout
<< "我们一样大"<< endl;
else cout << "它大"<< endl;
}
};
这就是类的继承,Animal为基类,Dog与Cat为派生类,继承达到了重用代码功能和提高执行效率的效果。
对象与实例
现在我们在主函数中给这个Dog类创造一个对象,命名为dog,则这个对象会拥有Dog类的属性和方法。dog即为Dog类的一个实例,即以类为模板,构造出了一个现实的具体的例子。这里我们给该对象的赋初值。
Dog dog("长", 4);
封装性
但是,如果把对象的一些属性设为private型(私有型),则其他对象就无法看到该对象的私有的变量或函数,只能访问公共的服务,例:将
intShowAge()
returnage;
设为私有型,则cout<<dog.ShowAge();会出错,原因为Dog::ShowAge()不可访问,即把信息隐藏了,这就是类的封装的作用。
消息
消息是对象之间的相互请求,发消息的目的是请求某个实例对象执行类中定义的某个操作,体现在函数的调用。
同上,我们 Cat cat("短", 2);若cat想要比较自己与dog的年龄,则:
cat.CompareAge(dog.ShowAge());结果输出“它大“,则通过消息传递,cat调用了dog返回年龄值的函数,得知了dog的年龄,作为参数传入自己比较年龄的函数,得出了结果。
多态性
当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
Dog与Cat类继承了基类的这个方法:
virtual voidbark() {
cout<<"我会叫"<< endl;
}
我们在Dog类和Cat类中分别重写这个函数:
voidbark(){
cout<<"我会汪汪叫"<< endl;
}
voidbark(){
cout<<"我会喵喵叫"<< endl;
}
在主函数中:
Animal* animal;
Dogdog("长", 4);
Catcat("短", 2);
animal= &dog;
animal->bark();
animal= &cat;
animal->bark();
输出为:
我会汪汪叫
我会喵喵叫
这里animal的指针指向不同对象时,调用同一函数会产生不同的结果,原因就是多态性会根据调用函数的对象的类型来执行不同的函数,实现了接口重用。