为什么继承每个 class,然后简单地使派生的单个对象 class 来执行 oop 中的所有操作是一种不好的做法?
why is it a bad practice to inherit every class, and then simply make a single object of derived class to do all operations in oop?
我是 c++ 的新手,我有一个简单的问题来实现一个面包店,有产品(例如糕点、甜甜圈)和烘焙机来处理这些产品(计算卡路里、烘焙温度等)。我只是做了两个 classes,写了所有的功能,然后继承它们做一个 class,并完成了我的工作,但我的导师对这种方式不满意。我想问问那里有什么问题吗?它如何影响代码的可重用性?这是我制作的函数原型。 P.s。我是 OOP 新手
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <map>
#include <time.h>
using namespace std;
int minimum(vector<int>);
struct Inventory
{
string Name;
map<string,float> inputfromfile;
};
class BakedItem
{
public:
BakedItem(){}
~BakedItem() {}
protected:
string Item;
float TemperatureForBakingItem;
vector <string> ShapesPossible;
vector <string> Ingredients;
void GetIngredients(string);
void ShapesPossibility(void);
void GetTemperature(string);
};
class Bakery:BakedItem
{
public:
Bakery(){}
~Bakery(){}
time_t * ViewManufactureDate(void);
float ViewPrice(void);
void GetInput(string);
void ViewShapesPossible(void);
protected:
time_t DateManufacture;
float PriceOfItem;
float Calories;
void GetManufactureDate(void);
void CalculateCalories(void);
void CalculatePrice(void);
void GetInventory(void);
};
因为它不仅忽略了不同 class 之间的关系,而且创建了不正确的关系。继承是一种 "is-a" 关系。当Cat
实现Animal
时,关系为"Cat is-an Animal".
您的 OOP 并非如此。 Bakery
应该 而不是 是 BakedItem
。相反,面包店有零个或多个烘焙食品。否则,Bakery
有一个可能的形状列表是什么意思?我们在谈论平面图吗?当你扩展 class 时,subclass 必须遵守 superclasses 的契约。
例如,BakedItem
class 的描述可能是:
This class represents a food item which has been heated in an oven at a specific temperature for a specific amount of time.
如果 Bakery
扩展 BakedItem
,是否意味着面包店本身已被放入某个巨大的建筑物大小的烤箱中?
...您可以看到遵循代码当前描述的逻辑关系如何很快变得荒谬。
记住,字段是"has-a"关系,继承代表"is-a"关系;使用这些可以准确地为您的对象建模,因为这样可以更清楚地了解每个 class 的用途以及每个方法如何工作以及如何与对象交互。
我是 c++ 的新手,我有一个简单的问题来实现一个面包店,有产品(例如糕点、甜甜圈)和烘焙机来处理这些产品(计算卡路里、烘焙温度等)。我只是做了两个 classes,写了所有的功能,然后继承它们做一个 class,并完成了我的工作,但我的导师对这种方式不满意。我想问问那里有什么问题吗?它如何影响代码的可重用性?这是我制作的函数原型。 P.s。我是 OOP 新手
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <map>
#include <time.h>
using namespace std;
int minimum(vector<int>);
struct Inventory
{
string Name;
map<string,float> inputfromfile;
};
class BakedItem
{
public:
BakedItem(){}
~BakedItem() {}
protected:
string Item;
float TemperatureForBakingItem;
vector <string> ShapesPossible;
vector <string> Ingredients;
void GetIngredients(string);
void ShapesPossibility(void);
void GetTemperature(string);
};
class Bakery:BakedItem
{
public:
Bakery(){}
~Bakery(){}
time_t * ViewManufactureDate(void);
float ViewPrice(void);
void GetInput(string);
void ViewShapesPossible(void);
protected:
time_t DateManufacture;
float PriceOfItem;
float Calories;
void GetManufactureDate(void);
void CalculateCalories(void);
void CalculatePrice(void);
void GetInventory(void);
};
因为它不仅忽略了不同 class 之间的关系,而且创建了不正确的关系。继承是一种 "is-a" 关系。当Cat
实现Animal
时,关系为"Cat is-an Animal".
您的 OOP 并非如此。 Bakery
应该 而不是 是 BakedItem
。相反,面包店有零个或多个烘焙食品。否则,Bakery
有一个可能的形状列表是什么意思?我们在谈论平面图吗?当你扩展 class 时,subclass 必须遵守 superclasses 的契约。
例如,BakedItem
class 的描述可能是:
This class represents a food item which has been heated in an oven at a specific temperature for a specific amount of time.
如果 Bakery
扩展 BakedItem
,是否意味着面包店本身已被放入某个巨大的建筑物大小的烤箱中?
...您可以看到遵循代码当前描述的逻辑关系如何很快变得荒谬。
记住,字段是"has-a"关系,继承代表"is-a"关系;使用这些可以准确地为您的对象建模,因为这样可以更清楚地了解每个 class 的用途以及每个方法如何工作以及如何与对象交互。