回答这个问题:How to GUI - Using paintcomponent() to initialize a GUI and then to add GUI based on mouse我已说过:
您没有正确覆盖
paintComponent()
。这是受保护的 方法,不公开。如果在此方法上添加@Override
注释 然后编译器会抱怨。
但@peeskillet明智地指出了这一点:
编译器不会抱怨
public
或protected
paintComponent
。您可以使用更高的可见性覆盖,但不能覆盖 低一个。public
高于protected
所以没有问题。
这当然是对的。但现在出现了这样一个问题:良好的实践覆盖是否具有更高的可见度?
链接到JComponent.paintComponent() javadoc。
Netbeans的形象完全没有抱怨:
答案 0 :(得分:4)
来自Java教程,Controlling Access to Members of a Class:
如果其他程序员使用您的课程,您需要确保错误 从滥用不可能发生。访问级别可以帮助您实现此目的。
- 使用对特定成员有意义的最严格的访问级别。除非你有充分理由不使用私人,否则请使用私人。
- 避免除常量之外的公共字段。 (本教程中的许多示例都使用公共字段。这可能有助于说明一些内容 简明扼要,但不建议用于生产代码。)公开 字段往往会将您链接到特定的实现并限制您的 更改代码的灵活性。
此建议旨在reduce coupling:
要实现最佳封装(信息隐藏),您应该这样做 始终声明具有最低可见性的方法。在小 程序确实没有问题,但在大型程序中存在这个问题 过度耦合非常严重。耦合发生在一个部分 取决于另一个的具体实施。耦合越多 因为太多而变得更加昂贵 代码取决于具体的实现。这导致软件腐烂 - a 程序变得越来越不可用,因为它不容易 升级。
因此,提高知名度实际上不是一个好主意。这样的代码可能会在未来的开发和维护中遇到麻烦。
答案 1 :(得分:4)
执行此操作的一个原因是,如果您有一个方法需要覆盖项目中的其他位置,并且当前范围不允许您这样做。通常在使用默认值而不是受保护时。
通过在项目的其他位置使用修改范围在正确的包中创建新的子类,然后可以在代码中创建一个您需要它的匿名类,因为您现在可以覆盖麻烦的方法而不必执行反射(这使得代码非常难以理解)。
这也是图书馆课程永远不会成为最终版本的原因,因为那时你不能做这样的事情。
编辑:我被要求详细说明为什么这与依赖注入有关。我只能根据自己的经验说话,首先是Guice,现在是Dagger。
Dagger使用构造函数注入,这基本上意味着一个类将所有依赖项作为构造函数的参数提供(并且仅在那里),并且将它们绑定在一起的粘合代码列在Dagger @Module中。在这个模块中,通常使用日志语句或提供自定义toString()方法返回库类的子类进行扩充非常方便。为了实际 DO 这没有反射技巧,clasess不能是最终的,你需要能够覆盖方法并直接使用超类中的字段。因此,最终的类和两种类型都不需要至少protected
而不是private
!
(我强烈建议使用Dagger,因为它会在java编译器中移动依赖项解析,为IDE提供帮助您在编译时解决问题所需的信息,而不是依赖于野外运行时的魔法。我是仍然对Java生态系统中的洞察力感到惊讶,Dagger设计师甚至不得不获得这个想法,然后意识到它)
答案 2 :(得分:1)
如果您需要从它所在的类/子类外部访问该方法,那么解决方案是使用public参数覆盖可见性。最佳做法是尽可能降低您的变量和方法。
答案 3 :(得分:1)
您可以提高方法的可见性,使其变得更加可见但不太可见,因此可以覆盖paintComponent并将其声明为public
方法。话虽如此,我还要补充一点,你不应该这样做。覆盖方法时,您应该保持可见性不变,除非您有充分的理由使其更加可见。
答案 4 :(得分:1)
从OOP的角度来看,它没有任何问题。通过扩展课程,您可以执行以下操作:
当你覆盖一个方法并改变它的可见性时,你正在做两件事:你 - 显然 - 改变了功能,但也扩展了界面。从类'客户端的角度来看,您实际上是在类'接口中创建一个新方法。这个新方法巧合地与超类中的某个内部方法具有相同的名称,但客户端并不关心(或者甚至不知道这一点)。那你为什么不呢?
另一方面,有一个问题“为什么你需要这样做?”。超类的作者可能对这种方法的可见性有一些想法,发现它的功能并不适用于外部世界。 我并不是说这样做是错误的,但你必须质疑你提高可见度的动机,因为它可能暗示你的或者超类的代码可能是糟糕的设计。
Btw:正如所指出的那样here禁止使用这种语言功能甚至可能是有害的。答案 5 :(得分:0)
如果您希望外部代码能够调用它们,那么重写的方法就像所有其他方法一样,只应声明public
(除非您没有选择,因为重写的方法被声明为public)。在您的情况下,重写的方法paintComponent
只应由Swing调用,因此保持protected
是最佳选择。
答案 6 :(得分:0)
要添加弗朗索瓦所说的话,这里的OOP原则是“Open Close Principle”,它表示你应该能够扩展,但不能修改对象。通过覆盖它来“提升”方法的可见性只是弗朗索瓦指出的扩展。
答案 7 :(得分:0)
有许多论据可以改变可见性。但只要考虑一下你将改变该类的接口(在API意义上)这一事实。阅读evolving APIs并将该信息与您的问题相关联。
因此,在我的书中,良好的做法是不改变可见性 - 如果可能的话。否则你必须仔细考虑后果 - 如果只是从长远来看。