三大特性
- 封装:对具有相同属性的事物进行统一描述
- 继承:一个类获取另外一个类的属性的方式
- 多态:一个类实例的相同方法在不同情形有不同表现形式,说白了就是父类指针指向子类对象
七项原则:目的就是实现 高内聚、低耦合
- 单一职责原则(Single Responsibility Principle,SRP):类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个
- 开闭原则(Open-Closed Principle,OCP):增加功能是通过增加代码,而不是修改代码
class Calculater
{
public:
int calculate(int a,int b,char c)
{
if(c=='+')
{
return a+b;
}
if(c=='-')
{
return a-b;
}
if(c=='*')
{
return a*b;
}
if(c=='/')
{
return a/b;
}
}
如果我再想加入 % 功能,则需要修改 calculate 方法, 得修改源代码
};
class Calculater
{
public:
virtual int calculate()=0;
}
class Plus:public Calculater
{
virtual int calculate(int a,int b)
{
return a+b;
}
}
class Subtrct:public Calculater
{
virtual int calculate(int a,int b)
{
return a-b;
}
}
class Multiply:public Calculater
{
virtual int calculate(int a,int b)
{
return a*b;
}
}
class Devide:public Calculater
{
virtual int calculate(int a,int b)
{
return a/b;
}
}
这时候如果想添加功能就直接 再继承一个抽象类,不用修改其他代码
-
里氏代换原则(Liskov Substitution Principle,LSP):任何抽象类出现的地方都可以用他的实现类进行替换,实际就是虚拟机制(多态),语言级别实现面向对象功能
-
依赖倒转原则(Dependence Inversion Principle,DIP):依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程
-
接口隔离原则(Interface Segregation Principle,ISP):一个方法对外只提供一个功能
-
合成复用原则(Composite Reuse Principle,CRP):如果使用继承,会导致父类的任何变换都可能影响到子类的行为。如果使用对象组合(将另一个对象当做成员),就降低了这种依赖关系。对于继承和组合,优先使用组合
错误的做法
class Car
{
public:
virtual void setcar() = 0;
};
class tuolaji : public Car
{
public:
virtual void setcar()
{
cout << "拖拉机";
}
};
class Person : public tuolaji //继承,这样就能使用其中方法
{
public:
void Party()
{
cout << "julain开着";
setcar();
cout << "去开Party"<<endl;
}
};
int main()
{
Person p;
p.Party();
return 0;
}
正确的做法
class Car
{
public:
virtual void setcar() = 0;
};
class tuolaji : public Car
{
public:
virtual void setcar()
{
cout << "拖拉机";
}
};
class Person
{
public:
void Set(Car *c)
{
car = c;
}
void Party()
{
cout << "julian开着";
car->setcar();
cout << "去Party" << endl;
}
string name;
Car* car; // 作为成员:类的组合 ,而不是继承
};
int main()
{
Person p;
BMW * bmw = new BMW;
p.Set(bmw);
p.Party();
return 0;
}
- 笛米特原则 (Law of Demeter Principle,LoD):一个对象应当对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统的可维护性
情况1:调用者直接对每个类进行操作,需要了解每个类的细节
情况2:调用者通过中介对类ABC进行操作,并不去了解类ABC的细节,只操作中介提供的接口