赞
踩
【实现关系】是一种类与接口的关系,表示类是接口所有特征和行为的实现。
特征:空白三角形箭头+虚线 箭头指向接口
【代码体现】:纯虚函数
对于C++,其接口类一般具有以下特征:
Testable() = delete; Testable(const Testable&) = delete;
class Testable
{
public:
static const int START = 1; // #1
static const int STOP = 2;
virtual void test() = 0; // #2: 接口方法
virtual ~Testable() {}; // #3: 从C++11开始可以: virtual ~Testable() = default;
}
【组合关系】:是整体与部分的关系,但部分不能离开整体而单独存在。如公司和部门是整体和部分的关系,没有公司就不存在部门。
组合关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。
各种关系的强弱顺序:
泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
下面这张UML图,比较形象地展示了各种类图关系:
权限按照以下两点递减:
public继承方式
基类中所有 public 成员在派生类中为 public 属性;
基类中所有 protected 成员在派生类中为 protected 属性;
基类中所有 private 成员在派生类中不能使用。
protected继承方式
基类中的所有 public 成员在派生类中为 protected 属性;
基类中的所有 protected 成员在派生类中为 protected 属性;
基类中的所有 private 成员在派生类中不能使用。
private继承方式
基类中的所有 public 成员在派生类中均为 private 属性;
基类中的所有 protected 成员在派生类中均为 private 属性;
基类中的所有 private 成员在派生类中不能使用。
继承方式/基类成员 | public成员 | protected成员 | private成员 |
---|---|---|---|
public继承 | public | protected | 不可见 |
protected继承 | protected | protected | 不可见 |
private继承 | private | private | 不可见 |
应当为客户端提供尽可能小的单独的接口,而不是提供大的总的接口。
又叫最少知识原则,一个软件实体应当尽可能少的与其他实体发生相互作用。
面向扩展开放,面向修改关闭。
尽量使用合成/聚合达到复用,尽量少用继承。原则: 一个类中有另一个类的对象。
类的静态成员与类本身直接相关,而不是与类的各个对象保持关联。
我们不能在类的内部初始化静态数据成员,必须在类的外部初始化。
字面值常量类型constexpr除外
/*类静态成员、静态成员函数例子如下*/ #include <iostream> #include <cstdio> #include <cstring> using namespace std; class Guest{ private: static int m_num; static int m_count; static double m_totalFee; string name; int num; double fee; public: Guest(string name, double fee):name(name),fee(fee) { m_num++; num = m_num; m_count++; m_totalFee+=fee; } ~Guest() { m_count--; } void show() const{ printf("num:%d,name:%s,fee:%.2lf\n",num,name.c_str(),fee); } static int GetCount() { return m_count; } static double GetTotalIncome(){ return m_totalFee; } }; int Guest::m_num = 0; int Guest::m_count = 0; double Guest::m_totalFee = 0; int main(int argc, char *argv[]) { Guest g1("lihua",11.99), g2("zhangsan",12.99), g3("xiaomei",13.99); g1.show(); g2.show(); g3.show(); printf("count:%d,totalFee:%.2f\n",Guest::GetCount(),Guest::GetTotalIncome()); return 0; }
#include <iostream.h> class animal { public: animal(int height, int weight) //有且仅有 有参参数,必须显性调用 { cout<<"animal construct"<<endl; } … }; class fish:public animal { public: fish():animal(400,300) { cout<<"fish construct"<<endl; } … }; void main() { fish fh; }
Shape *a = new Circle();
delete a;
new Circle()时,将会调用Circle(子类)的构造函数,delete a时,由于指针a是基类,将只会调用父类的析构函数,所以我们必须实现多态(用虚函数),使得对象为Circle时,delete会调用子类的析构函数。方法是将析构函数声明为虚函数
//Product.h #ifndef _PRODUCT_H_ #define _PRODUCT_H_ class Product { public: virtual ~Product() = 0; //多态时,调用子类的析构函数 protected: Product(); //不可被外部调用,抽象基类不可以被实例化 private: }; class ConcreteProduct:public Product { public: ~ConcreteProduct(); ConcreteProduct(); protected: private: }; #endif
//Product.cpp #include "Product.h" #include <iostream> Product::Product() { std::cout<<"Product()...."<<std::endl; } Product::~Product() { std::cout<<"~Product()...."<<std::endl; } ConcreteProduct::ConcreteProduct() { std::cout<<"ConcreteProduct()...."<<std::endl; } ConcreteProduct::~ConcreteProduct() { std::cout<<"~ConcreteProduct()...."<<std::endl; }
//Factory.h #ifndef _FACTORY_H_ #define _FACTORY_H_ class Product; //factory抽象基类 class Factory { public: virtual ~Factory() = 0; //析构函數 virtual Product* CreateProduct() = 0; protected: Factory(); //构造函数,外部不可以调用,子类可以调用 private: }; //factory实例 class ConcreteFactory:public Factory { public: ~ConcreteFactory(); ConcreteFactory(); Product* CreateProduct(); protected: private: }; #endif
//Factory.cpp #include "Product.h" #include "Factory.h" #include <iostream> Factory::Factory() { std::cout<<"Factory()...."<<std::endl; } Factory::~Factory() { std::cout<<"~Factory()...."<<std::endl; } ConcreteFactory::ConcreteFactory() { std::cout<<"ConcreteFactory()......"<<std::endl; } ConcreteFactory::~ConcreteFactory() { std::cout<<"~ConcreteFactory()......"<<std::endl; } Product* ConcreteFactory::CreateProduct() { return new ConcreteProduct(); }
//main.cpp
#include "Factory.h"
#include "Product.h"
#include <iostream>
#include <cstdio>
int main(int argc, char* argv[])
{
Factory *fac = new ConcreteFactory();
Product* p = fac->CreateProduct();
delete p;
delete fac;
return 0;
}
#makefile
CC = g++ -g
BaseIncludePath = ../include/
SRCS = main.cpp Product.cpp Factory.cpp
OBJS = $(addsuffix .o,$(basename ${SRCS}))
main.exe: $(OBJS)
$(CC) $(OBJS) -o main.exe
%.o: %.cpp
$(CC) -c $< -o $@ -I$(BaseIncludePath)
clean:
del $(OBJS) main.exe
抽象工厂模式和工厂方法模式一样,都符合开闭原则。但是不同的是,在抽象工厂模式中,增加一个产品族很容易,而增加一个产品等级结构却很难,工厂模式则反之。
也就是说,在抽象工厂模式中,增加一个具体的工厂很容易,但是你想在工厂中多生产一种产品,就需要修改很多个类,会违背开闭原则,这种情况下应该使用工厂模式。
简单来说:工厂模式新增产品类型容易,抽象工厂模式新增工厂类型容易
表头 | 表头 |
---|---|
单元格 | 单元格 |
单元格 | 单元格 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。