为什么这么多的自由软件图书馆将他们的课程公开而不是最终的?
在你给我一个明显的答案之前,让我限定一下这个问题并说,并不是所有的类都是可子类的。
- 子类应该是经过深思熟虑的额外属性,而不是所有类的默认属性。
- 可以说,默认情况下,类应该是最终的,如果确实想要的话,则不是最终的。
我可以想到包私有类的许多优点。
- 如果该类并不真正适合我查看,而只是一个我应该考虑实现细节的帮助程序,那么将其设为非公开意味着当我在 ide 中按名称或接口的实现搜索类时,它不会出现。
- 这也意味着,如果除了导出的接口之外的所有内容都是公开的,那么在浏览库 jar 文件时检查 api 就会变得更加简单,因为噪音更少。我不再看到内部实现的东西。
- 无需担心包外的子类。
- 对于用户来说,实际的好处意味着他们需要的方法可能也将被分组在一个接口/类下,而不是分散在其他公共类中,这意味着更少的混乱,需要查看的地方更少,需要管理的句柄也更少。
那么为什么人们不利用这些设施呢?
Before you jump on me with an obvious answer, let me qualify the question and say, not all classes are sub classable.
- Sub classing should be a carefully thought out extra not a default property of all classes.
- It could be argued classes should be final by default and not final if one really wants that.
I can think of many advantages for package private classes.
- if the class is not really for my viewing and just a helper that i should consider a implementation detail, making it non public means it wont come up when i search for classes by name or implementations of an interface in my ide.
- it also means that if everything but the exported interfaces are public examining the api while browsing the library jar files becomes much simpler as there is less noise. I no longer see internal implementation stuff.
- there is no need to worry about sub classes outside your package.
- for the users the practical benefit means that methods they need are probably also going to be grouped together under one interface/class rather than being scattered around in other public classes which means less cluter and there are less places to look and less handles too manage.
So why dont people take advantage of these facilities ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
有些语言(例如 python)中的一切都是公开的,没有什么是最终的。这并不意味着他们生活在地狱中并且模块无法使用和维护。恰恰相反。
软件工程很棘手。很多时候,我们心里都在与稻草人作斗争。这很有趣,我们不顾实际利益而追逐理想——如果我们有时间的话。如果你是一个负责数百个课程的人,完美主义者会让你发疯。
There are languages e.g. python in which everything is public and nothing is final. That doesn't mean they are living in hell and modules are impossible to use and maintain. Quite the contrary.
Software engineering is tricky. Many times we are fighint strawmen in our minds. That can be fun, we chase the ideal regardless of practical benefits - if we have the time. If you are a single person that's responsible for hundreds of classes, being a perfectionist will drive you crazy.
基本上,情况会发生变化。
您认为现在不可子类化的内容,以后可能需要子类化。
当您发现实际上应该进行子类化时,会在以后的工程中考虑更多“蓬松”的设计选择(例如将类定为最终的)。
大多数API设计都会考虑可扩展性。
Basically, circumstances change.
What you think is not subclassable now, may be required for subclassing later.
A lot of more "fluffy"design choices (such as making a class final) are considered over engineering later when you find out that in fact you should be subclassing.
Most API designs take into account extendability.
就默认情况下类是否应该是最终的而言,这是一个备受争议的问题,并且没有真正的“正确”答案。 Java 选择了一种方式,C# 选择了另一种方式,不同的人认为不同的语言的做法是对的,也有错的。
就我个人而言,我喜欢默认情况下类可扩展的方式,如果人们想让它们成为最终的,那么他们就可以,只需一个关键字即可。但在我看来,允许子类化只会增加更多的灵活性,当然我不必扩展阳光下的每个非最终对象,但如果我想添加某种程度的特定行为,那么我可以选择这样做。是的,可以使用组合(在某些情况下确实应该使用),但这不会也不应该排除子类作为一种选择。在很多情况下,子类对象满足与父对象的 is-a 关系,在这种情况下,这是正确的方法。诚然,尽管这在过去被滥用了,甚至在 Java API 中也是如此(例如属性并不是真正的哈希表)。但是如果你试图改变语言以阻止人们变得愚蠢——那么,他们总会找到一个绕过它!
至于将类包设为私有,对我来说,如果包是分层的而不是扁平的,那么这个选项会更有用。是的,它们在描述上是分层的,但在 org.me 中声明为私有的包无法从 org.me.subpackage 访问,而我经常觉得有必要这样做。幸运的是,通过添加超级包,我们可能会看到这个选项得到更好的使用!
In terms of whether classes should be final or not by default, it's a heavily debated point for which there's not really a "right" answer. Java chose to do it one way, C# another, different people think different languages got it right and wrong.
Personally, I like the way classes are extendible by default, if people want to make them final then they can, it's only a keyword away. But allowing sub classing just adds more flexibility in my view, sure I don't have to extend every non-final object under the sun but if I want to add some degree of specific behaviour then that option's there for me to do so. Yes, composition could be used (and indeed should be used in some cases) but that doesn't and shouldn't rule out sub classing as an option. There's many cases when the sub-classed object fulfils the is-a relationship with the parent, and in that case it's the right way to go. Admittedly though this has been misused in the past, even in the Java API (properties for instance is not really a hashtable.) But if you're trying to change the language to stop people being stupid - well, they'll always find a way around it!
As for making classes package private, for me this option would be far more useful if packages were hierarchical rather than flat. Yes, they're hierarchical in description but something declared package private in org.me can't be accessed from org.me.subpackage, which I often feel the need to do. Fortunately with the addition of superpackages we might see this option being better used!
我的经验并不支持您所谓的不支持子类化的库的优势。
Java 没有委托,瘦子类通常用作适配器或方法拦截器。
在代码中执行此操作比使用反射代理执行此操作更具可读性。
事情发生了变化。可更改的软件更易于使用。有时这需要彻底的改进,比如 Java 8 的默认方法。这些巧妙地修复了接口被广泛使用后向接口添加方法的问题。
Your supposed advantages of libraries not supporting sub-classing is not backed by my experience.
Java doesn't have delegation, thin subclasses are often used as adapters or method interceptors.
It is more readable to do it in code than doing it by using a reflective proxy.
Things change. Software that can change is easier to work with. Sometimes this takes radical improvements like Java 8's default methods. These neatly fix adding methods to interfaces after the interfaces are widely used.
嗯,这只是因为思考什么不应该被扩展需要花费大量的脑力。
对于大多数中小型组件和框架来说,好的猜测是,弃用并保留滥用/过度使用的方法/类比考虑最可能的和一些不太可能的用例并且仍然偶尔关闭一些东西更容易,也更用户友好。需要一些肮脏的委托/装饰而不是简单的扩展。
在我的实践中,只有 Java 的 Spring 真正让我困扰的是这种预防性关闭(我认为在几次微发布之后,这会导致 API 变得更加清晰)。
我在这里引用了 R. Martin 关于此事的一段话:
http: //java.akraievoy.org/2009/03/openclose-principle-strategic-closure.html
Well, this is just because thinking what should NOT be EVER extended takes lots of brain effort.
For most of small and medium-sized components and frameworks good guess is that to deprecate and keep the abused/overused method/class is easier and more user-friendly than thinking of most probable and some quite improbable usecases and still occasionally closing something which then needs some dirty delegation/decoration instead of simple extension.
On my practice only Java's Spring really bothered me with this kind of preventive closure (which results in a lot clearer API after several micro releases I think).
I had a quote of R. Martin on this matter here:
http://java.akraievoy.org/2009/03/openclosed-principle-strategic-closure.html