#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
//纯虚函数的概念:
//纯虚函数是一个在基类(父类)中声明的虚函数,在父类中没有任何定义,要求所有的派生类(子类)都定义自己的版本
//纯虚函数为子类提供了一个公共界面(即接口)
//抽象类的概念:
//用于一个或多个纯虚函数的基类(父类)称为抽象类
//抽象类和普通类的区别:
//抽象类不可以创建对象,普通类可以创建对象性
//这个类即为抽象类
class Shape//父类则为抽象层
{
public:
//表示形状类声明一个getArea()方法,它是一个纯虚函数,并没有函数的实现
virtual double getArea() = 0;//这即为纯虚函数,子类中必须重写这个方法,我们通常称这种纯虚函数为接口
virtual ~Shape()
{
cout << "~shape......" << endl;
}
};
//如果一个子类继承抽象类,需要重写抽象类里的纯虚函数,如果不重写的话,这个子类仍为抽象类
//注意:父类中有多个纯虚函数,子类如果想可以实例化,必须把所有的纯虚函数都重写才可以
class Square :public Shape
{
public:
Square(int a)
{
this->a = a;
}
virtual double getArea()
{
return a * a;
}
//当父类的析构函数为虚析构函数时,子类的析构函数即使没有显式的写出来,也会被写到虚函数表中,因此当new的时候,只需要在父类中把析构函数写成虚析构函数就可以了,此时子类的析构函数编译器会自动帮我们加入虚函数表中
~Square()
{
cout << "~square......" << endl;
}
private:
int a;
};
class Circular :public Shape//这几个子类则为实现层
{
public:
Circular(int r)
{
this->r = r;
}
virtual double getArea()
{
return 3.14 * r * r;
}
private:
int r;
};
class InterFace1
{
public:
virtual void func1(int a) = 0;
virtual void func2() = 0;//纯虚函数也可以发生重载???
virtual ~InterFace1()
{
}
};
class InterFace2
{
public:
virtual void func1(int a) = 0;
virtual void func3() = 0;
virtual ~InterFace2()
{
}
};
class Test :public InterFace1, public InterFace2
{
public:
//纯虚函数多继承时,子类实现纯虚函数,这个纯虚函数在两个父类中都有声明,则两个父类的指针都可以调用子类的具体函数,发生多态
void func1(int a)
{
}
//子类中实现的纯虚函数在多继承父类中只在一个父类中声明,那么只有这个父类的指针可以通过多态调用到这个实现的函数
void func2()
{
}
//不同父类指针通过多态调用子类实现的不同纯虚函数,不会发生任何歧义,各调各的
void func3()
{
}
};
int main()//main函数体内为高层业务逻辑层
{
//这种模式为设计模式中的依赖倒转原则
//抽象类的优点:
//减少main函数与其他子类的耦合度,只与父类相关联,
//子类之间互不影响,子类只与父类有关系
//当在堆空间创建对象时,如果使用父类指针,则需要把父类的析构函数写成虚析构函数,这样delete
Shape *p1 = new Square(10);
p1->getArea();//发生了多态
Shape *p2 = new Circular(20);
p2->getArea();//发生了多态
delete p1;//也发生了多态
delete p2;//也发生了多态
InterFace1 *i1 = new Test();
i1->func1(10);
InterFace2 *i2 = new Test();
i2->func1(100);
i1->func2();
i2->func3();
}
#include <iostream>
using namespace std;
//纯虚函数的概念:
//纯虚函数是一个在基类(父类)中声明的虚函数,在父类中没有任何定义,要求所有的派生类(子类)都定义自己的版本
//纯虚函数为子类提供了一个公共界面(即接口)
//抽象类的概念:
//用于一个或多个纯虚函数的基类(父类)称为抽象类
//抽象类和普通类的区别:
//抽象类不可以创建对象,普通类可以创建对象性
//这个类即为抽象类
class Shape//父类则为抽象层
{
public:
//表示形状类声明一个getArea()方法,它是一个纯虚函数,并没有函数的实现
virtual double getArea() = 0;//这即为纯虚函数,子类中必须重写这个方法,我们通常称这种纯虚函数为接口
virtual ~Shape()
{
cout << "~shape......" << endl;
}
};
//如果一个子类继承抽象类,需要重写抽象类里的纯虚函数,如果不重写的话,这个子类仍为抽象类
//注意:父类中有多个纯虚函数,子类如果想可以实例化,必须把所有的纯虚函数都重写才可以
class Square :public Shape
{
public:
Square(int a)
{
this->a = a;
}
virtual double getArea()
{
return a * a;
}
//当父类的析构函数为虚析构函数时,子类的析构函数即使没有显式的写出来,也会被写到虚函数表中,因此当new的时候,只需要在父类中把析构函数写成虚析构函数就可以了,此时子类的析构函数编译器会自动帮我们加入虚函数表中
~Square()
{
cout << "~square......" << endl;
}
private:
int a;
};
class Circular :public Shape//这几个子类则为实现层
{
public:
Circular(int r)
{
this->r = r;
}
virtual double getArea()
{
return 3.14 * r * r;
}
private:
int r;
};
class InterFace1
{
public:
virtual void func1(int a) = 0;
virtual void func2() = 0;//纯虚函数也可以发生重载???
virtual ~InterFace1()
{
}
};
class InterFace2
{
public:
virtual void func1(int a) = 0;
virtual void func3() = 0;
virtual ~InterFace2()
{
}
};
class Test :public InterFace1, public InterFace2
{
public:
//纯虚函数多继承时,子类实现纯虚函数,这个纯虚函数在两个父类中都有声明,则两个父类的指针都可以调用子类的具体函数,发生多态
void func1(int a)
{
}
//子类中实现的纯虚函数在多继承父类中只在一个父类中声明,那么只有这个父类的指针可以通过多态调用到这个实现的函数
void func2()
{
}
//不同父类指针通过多态调用子类实现的不同纯虚函数,不会发生任何歧义,各调各的
void func3()
{
}
};
int main()//main函数体内为高层业务逻辑层
{
//这种模式为设计模式中的依赖倒转原则
//抽象类的优点:
//减少main函数与其他子类的耦合度,只与父类相关联,
//子类之间互不影响,子类只与父类有关系
//当在堆空间创建对象时,如果使用父类指针,则需要把父类的析构函数写成虚析构函数,这样delete
Shape *p1 = new Square(10);
p1->getArea();//发生了多态
Shape *p2 = new Circular(20);
p2->getArea();//发生了多态
delete p1;//也发生了多态
delete p2;//也发生了多态
InterFace1 *i1 = new Test();
i1->func1(10);
InterFace2 *i2 = new Test();
i2->func1(100);
i1->func2();
i2->func3();
}