曾与多个 O.O.语言,我学到了一些东西,有助于用 C++ 编程。 这适用于您的问题。
这是一个冗长而无聊的问题,但是,它可能值得花时间。
具体类,首先
我通常从具体的类开始,当几个类共享共同的特性,如方法或字段时,我会设计一个共同的超类。许多开发人员(使用任何语言)似乎直接跳到做超类,然后是子具体类。
O.O.的设计程序,无论是否抽象,似乎都是首先设计的超类。但是,在现实世界中,大多数类一开始都是具体的,而超类是后来出现的。即使在设计上,U.M.L.或代码超类首先出现。
所以这个例子,包括数据和方法:
// ....
#include <iostream>
class Employee {
public:
Employee(); // constructor;
void SayHello();
void Work();
};
class Student {
public:
Student(); // constructor;
void SayHello();
void Study();
};
// ....
变成这样:
// ....
#include <iostream>
class Person {
public:
Person(); // constructor;
virtual void SayHello() = 0;
};
class Employee {
public:
Employee(); // constructor;
virtual void SayHello();
void Work();
};
class Student {
public:
Student(); // constructor;
virtual void SayHello();
void Study();
};
// ....
这些前面的例子只显示了方法,而不是数据,但同样的原则也适用。
避免私有字段或方法
我通常会做的事情是避免“私人”部分。如果我需要隐藏,我会使用“protected”来代替。
所以,这个:
// ....
#include <iostream>
#include <cstring>
class Person {
private:
char[512] Name;
public:
Person(); // constructor;
virtual void SayHello() = 0;
};
// ....
变成这样:
// ....
#include <iostream>
#include <cstring>
class Person {
protected:
char[512] Name;
public:
Person(); // constructor;
char[512] Name;
virtual void SayHello() = 0;
};
// ....
如果您正在使用一个类,无论是否抽象,您可能会认为,您或其他开发人员可以编写子类并访问父类字段或方法。
使用属性(使用访问器方法)代替普通数据字段
真正困扰我的一点是,“C++”和“Java”中缺少“真实属性”。
从对象访问、修改、控制或更新数据的一种方法,它的直通属性,即使用称为访问器的方法访问的字段。
属性可以在 C++ 中实现,使用模板,或者只是手动编码方法。
所以这个,直接非隔离字段示例:
// ....
#include <iostream>
#include <cstring>
class Person {
public:
Person(); // constructor;
char[512] Name;
virtual void SayHello() = 0;
};
int main (...) {
Person thisPerson = new Person();
strcpy(thisPerson.Name, "John Doe");
cout << thisPerson.Name << "\n";
delete thisPerson;
}
// ....
变成,这个孤立的属性例子:
// ....
#include <iostream>
#include <cstring>
class Person {
protected:
// isolated data field
char[512] Name;
public:
Person(); // constructor;
virtual void SayHello() = 0;
// public data field accesor reader method or "getter"
const char* getName();
// public data field accesor writer method or "setter"
void setName(const char* AName);
};
const char Person::getName() {
char char* Result = this.FName;
return Result;
}
void setName(const char* AName) {
bool IsValid = false;
// do some validation before actually modifing field
// ...
if (IsValid)
{
strcpy(this.FName, AName);
}
}
int main (...) {
Person thisPerson = new Person();
// should be read as "thisPerson.Name = "John Doe";"
thisPerson.setName("John Doe");
// should be read as "cout << thisPerson.Name;"
cout << thisPerson.getName() << "\n";
delete thisPerson;
}
// ....
许多 C++ 开发人员不喜欢“属性”,因为缺乏控制。我认为您应该习惯于访问数据作为您的问题,但作为任何功能,都应该“正确使用”。
属性访问方法应该是虚拟的
在某些语言中,可以实现属性的概念,直接访问对象的数据字段,通过方法读取和写入,或混合两种方法。为了使事情更复杂,方法可以是“虚拟的”或“非虚拟的”。
当我使用属性时,我总是使用虚拟方法来访问它们。速度和记忆力会受到惩罚,但是,这是值得的。具有虚拟覆盖方法的属性允许控制和访问对象的数据。
总结
您的问题涉及如何实现数据、如何隔离数据、如何访问类中的数据以及如何在子类中实现这些功能。
我在 Stackoverflow 中阅读过类似的问题,但我得出的结论是,有几个问题与 C++ 中“真实属性”的缺失有关。
您可能希望通过使用“属性”来管理您的数据访问和隔离。
并且,可能想尝试学习其他 O.O.,其中实现了“属性”的概念,例如:VB (.NET)、C#、Delphi、D 或 Vala。
稍后,如果需要,请尝试在您的 C++ 程序中实现这个概念。我在 C++ 中的类具有普通数据字段、被视为“属性”的字段,就像 Java 对访问器方法所做的那样,或者在需要时混合两者。
这并不意味着你要重写你正在工作的应用程序,或者尝试探索哪种编程语言更好,只是从其他编程语言中学习一些可能对你的工作有帮助的东西。