一、继承
每个类都有自己的数据成员和函数,但有些类之间的数据成员和函数相同,直接指定新建的类继承了一个已有的类即可。
已有的类称为基类,新建的类称为派生类。
#include <iostream>
using namespace std;
//基类shape
class shape
{
public:
void setwidth(int w)//不用输出,void
{
width = w;
}
void setheight(int h)
{
height = h;
}
protected://受保护的成员
int width;
int height;
};
//基类paintcost
class paintcost
{
public:
int getcost(int area)//int,要输出
{
return area * 70;
}
};
//派生类rectangle
class rectangle : public shape, public paintcost //派生类rectangle
{
public:
int getarea()//类内定义函数getarea,int有输出
{
return (width*height);
}
};
int main(void)
{
rectangle rect; //声明rect,属于rectangle类
int area;//定义area
rect.setwidth(5);
rect.setheight(7);
area = rect.getarea();
//输出对象的面积
cout << "total area:" << rect.getarea() << endl;
//输出花费
cout << "total paint cost " << rect.getcost(area) << endl;
return 0;
}
二、函数重载与运算符重载
函数重载:同名函数,但形式参数(参数个数、类型、顺序)必须不同,不能仅通过返回类型的不同重载函数。
#include <iostream>
using namespace std;
class printdata
{
public:
void print(int i)
{
cout << "整数为:" << i << endl;
}
void print(double f)
{
cout << "浮点数为:" << f << endl;
}
void print(string b)
{
cout << "字符串为:" << b << endl;
}
};
int main()
{
printdata pd;
pd.print(5);
pd.print(500.263);
pd.print("Hello C++");
return 0;
}
运载符重载:带有特殊名称的函数,函数名由关键字operator和其后要重载的运算符符号构成。
出现原因:C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。
Box operator+(const Box&, const Box&);
声明加法运算符用于把两个Box对象相加。
一元运算符重载:只对一个操作数进行操作
#include <iostream>
using namespace std;
class distance
{
private:
int feet;//0到无穷
int inches;//0到12
public:
//所需构造函数
distance()
{
feet = 0;
inches = 0;
}
distance(int f, int i)
{
feet = f;
inches = i;
}
//显示距离的方法
void displaydistance()
{
cout << "F:" << feet << "I:" << inches << endl;
}
//重载运算符(-)
distance operator-()
{
feet = -feet;//一元运算符通常出现在它们所操作的对象的左边
inches = -inches;
return distance(feet, inches);
}
};
int main()
{
distance d1(11, 10), d2(-5, 11);
-d1;//取相反数
d1.displaydistance();//距离d1
-d2;
d2.displaydistance();
return 0;
}
二元运算符需要两个参数,平常使用的加运算符( + )、减运算符( - )、乘运算符( * )和除运算符( / )都属于二元运算符
#include <iostream>
using namespace std;
class Box
{
double length;//定义长宽高
double breadth;
double height;
public:
double getvolume(void)//定义函数,有返回
{
return length*breadth*height;
}
void setlength(double len)//没有输出
{
length = len;
}
void setbreadth(double bre)
{
breadth = bre;
}
void setheight(double hei)
{
height = hei;
}
//重载+运算符,把两个对象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
};
int main()
{
Box Box1;//声明Box1,类型为Box
Box Box2;
Box Box3;
double volume = 0.0;//体积
//Box1详述
Box1.setlength(6.0);
Box1.setbreadth(7.0);
Box1.setheight(5.0);
volume = Box1.getvolume();//Box1体积
cout << "Volume of Box1" << volume << endl;
//Box2详述
Box2.setlength(12.0);
Box2.setbreadth(11.0);
Box2.setheight(5.0);
volume = Box2.getvolume();//Box2体积
cout << "Volume of Box2" << volume << endl;
//把两个对象相加
Box3 = Box1 + Box2;
volume = Box3.getvolume();//Box2体积
cout << "Volume of Box3" << volume << endl;
return 0;
}
关系运算符重载
( < 、 > 、 <= 、 >= 、 == 等等)
//重载小于运算符
bool operator <(const distance& d)
{
if (feet < d.feet)
{
return ture;
}
if (feet == d, feet&&inches < d.inches)
{
return ture;
}
return false;
}
三、多态
什么是多态:
通过继承同一个基类,产生不同的派生类,一个接口多种方法。
问题:运行使用同一个成员名来调用类对象的成员函数,会调用哪个对象的成员函数呢?
多态作用:将基类指针或基类引用指向派生类对象。调用成员函数时,根据调用函数对象的类型执行不同的函数。
多态分类:
1静态分类:编译时的多态,通过函数重载或者运算符重载实现
2动态多态:运行时的多态,通过虚函数与基类指针共同作用实现。
虚函数 是在基类中使用关键字virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
#include <iostream>
using namespace std;
//基类
class shape
{
protected:
int width, height;
public:
shape(int a = 0, int b = 0)
{
width = a;
height = b;
}
virtual int area()//虚函数virtual 编译器看的是指针的内容,而不是它的类型
{
cout << "parent class area:" << endl;
return 0;
}
};
//派生类1,继承rectangle
class rectangle : public shape
{
public:
rectangle(int a = 0, int b = 0) :shape(a, b){}
int area()
{
cout << "Rectangel class area:" << endl;
return (width*height);
}
};
//派生类2,继承triangle
class triangle :public shape
{
triangle(int a = 0, int b = 0) :shape(a, b){}
int area()
{
cout << "triangle class area:" << endl;
return (width*height/2);
}
};
int main()
{
shape *shape;
rectangle rec(10, 7);
triangle tri(10, 5);
shape = &rec;//存储矩形地址
shape->area();//调用矩形的求面积函数 area
shape = &tri;//存储三角形地址
shape->area();//调用三角形的求面积函数 area
return 0;
}
形成多态必须具备三个条件:
1、必须存在继承关系;
2、继承关系必须有同名虚函数(其中虚函数是在基类中使用关键字Virtual声明的函数,在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数);
3、存在基类类型的指针或者引用,通过该指针或引用调用虚函数;
四、数据抽象
数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节。
#include <iostream>
using namespace std;
class adder
{
public:
//构造函数
adder(int i = 0)
{
total = i;
}
//对外的接口
void addnum(int number)
{
total += number;
}
//对外的接口
int gettotal()
{
return total;
}
private:
int total;
};
int main()
{
adder a; 声明a, 类型为adder
a.addnum(10);
a.addnum(20);
cout << "total" << a.gettotal() << endl;
return 0;
}