我最近读过,我应该在编程时使用通用类而不是特定的类。 我无法弄清楚为什么建议它。
示例:假设我们有一个继承自JPanel的类MyPanel。 MyPanel是一个名为getLastChild的非继承方法。
而不是:
MyPanel panel = new MyPanel():
Component last = panel.getLastChild();
建议这样做:
JPanel panel = new MyPanel();
Component last = ((MyPanel)panel).getLastChild();
我不明白为什么我应该选择第二个。
答案 0 :(得分:4)
你是对的,这个例子确实毫无意义。
一般的经验法则是你应该使用仍然具有适当功能的最通用的类。通过这种方式,您可以自由地更改您正在使用的具体类,并让程序的其余部分继续工作。例如,考虑JDK' Collections.sort(List)
。相同的方法调用可以与ArrayList
,LinkedList
或任何其他List
一起使用 - 它不关心如何实现该列表的具体细节,只是关于以下事实:它是一个清单。
然而,你的例子却不同。如果您需要致电MyPanel.getLastChild()
,那么您肯定关心的是MyPanel
- 您无法使用任何其他JPanel
。由于您已经拥有此依赖关系,因此将变量声明为JPanel
并向下转换它只是为了调用getLastChild()
毫无意义。
答案 1 :(得分:0)
一个很好的例子是:
List<Integer> list = new ArrayList<Integer>;
而不是
ArrayList<Integer> list = new ArrayList<Integer>;
tl; dr 它为您提供了更大的灵活性,并免费推广您的代码。
每当您想传递list
时,您都会使用List
代替ArrayList
。例如,您有一个方法:
public void doSomething(List<Integer> list)
如果您意识到例如LinkedList
是更好的选择,那么您可以轻松更改您的实施。
答案 2 :(得分:-1)
第二个带来更大的灵活性。如果您将panel声明为MyPanel类型,那么它只能是MyPanel(或从MyPanel继承的类),而如果您将panel声明为JPanel类型,它可以是通用JPanel或JPanel的任何子类(包括MyPanel)。这使您的代码更加便携,更容易编辑。您的组件现在可能只是一个MyPanel,但如果以后更改会怎样?
答案 3 :(得分:-1)
您现在可以开发使用JPanel
运行的实用程序方法。我们称之为foo(JPanel p)
。
现在,您可以将其与包含JPanel
的任何MyPanel
一起使用。但为什么?您可以将方法定义如下:foo(MyPanel p)
并将其与MyPanel
一起使用,直到您开发出名为OtherPanel
的第二个面板。您无法将此OtherPanel
发送给仅使用foo()
的{{1}}。
然而,MyPanel
的第一个(通用)版本可用于扩展foo()
并由您,我或任何其他程序员开发的任何其他类。
我希望这个简单的例子足以理解泛化的必要性。