为何小心使用“受保护”

时间:2016-02-21 02:25:17

标签: java protected

CoreJavaⅠ,一书中,它说......

  应谨慎使用

protected个关键字。如果您设置一个具有protected字段的类,那么,如果您想要更改它,则必须通知所有使用此类的程序员。

我无法理解。如果Son extends FatherFather发生了变化,则Son未受影响。是不是?

2 个答案:

答案 0 :(得分:5)

示例:如果父亲有一个保险箱,并给他的儿子组合。儿子可以在没有通知父亲的情况下从保险箱拿钱,或者反过来。无论哪种方式,都无法保证从保险柜拿钱的儿子会将这些信息传达给父亲。

另一方面,如果儿子总是向父亲要钱,那么父亲就可以追踪支出并控制钱的花费。

这相当于封装。将字段保密并公开公共或受保护的方法始终是最佳做法。这样,负责人(声明字段的地方)可以隐藏字段修改方式的详细信息,但可以访问与方法调用者相关的信息。

这也掩盖了未来的变化。例如,假设您有一个名为total的字段。如果您直接访问该字段,则无法保证字段未被错误地修改并引入了错误。但是,如果您只通过方法()提供访问权限,则可以更改计算的执行方式,并且调用该方法的任何人都不会受到影响,并从更改中受益。

答案 1 :(得分:1)

  

我无法理解。如果void Mesh::LoadMeshFromFile(DXManager* dxPtr, LPCSTR fileName, int ID) { std::fstream f(fileName, std::ios_base::in); short vertexStride = sizeof(Vertex); //Gets the stride per vertex long fileLength = f.seekg(0, std::ios::end).tellg(); //Gets the byte count float vertexCount = (float)fileLength / (float)vertexStride; //Calculates the vertex count if (vertexCount == (int)vertexCount) //Ensures there are no incomplete vertices { if (vertexCount > 134217727 || vertexCount * vertexStride > 2147483647) { //Alloc will definitely fail. //Throw an error } else { char* vertices = new __nothrow char[(int)fileLength]; if (vertices == NULL) { //Allocation failed //Throw an error } else { //Read all vertices directly into the array and build the buffer f.seekg(0, std::ios::beg); f.read(vertices, fileLength); BuildBuffer(dxPtr, (Vertex*)vertices, vertexCount); } } } else { //1 or more incomplete vertices. } } Son extends Father发生了变化,则Father未受影响。是不是?

简短回答是:不,对于一般情况!

假设您拥有在源代码的第1版中描述的两个类:

版本1

Son

现在让我们更改class Father { protected int asdf; } class Son extends Father { int qwer = 2 * asdf; }

的受保护字段asdf

版本2

Father

现在你必须改变class Father { protected int fdsa; } class Son extends Father { int qwer = 2 * asdf; } // compile error ,所以它肯定会影响子类。

让我们考虑一下图书馆,我们假设你使用了很多。让我们假设您从核心库类派生了20个类。随着库的下一次更新,您的20个课程也可能需要更改。这是因为受保护的破坏了封装。

进一步阅读

有几个很好的资源描述了关于这个问题的所有漂亮细节,在程序员SE网络上可以找到一个很好的总结here。我现在试着进一步总结它。

使用Son往往;

  1. 导致YAGNI问题。
  2. 导致LSP问题。
  3. 违反OCP
  4. 设计继承优于组合的地方。
  5. 导致更多违反SRP
  6. 罗伯特·C·马丁(别名鲍勃叔叔)的另一个好参考是Clean Code