为什么定义具有超类型的变量是一个好习惯?

时间:2015-08-19 09:05:54

标签: java generics polymorphism

“Java编程简介”,说:

  

要启用通用编程,   定义具有超类型的变量是一种很好的做法,它可以接受任何子类型的值。

代码示例:

 Object myObject = new Circle();

... // Some lines of code

System.out.println("The circle diameter is " +
((Circle)myObject) .getDiameter());

... // Some lines of code

为什么不首先将myObject定义为Circle类型?

3 个答案:

答案 0 :(得分:2)

让我们用类Fruit

制作一个简单的例子
public class Fruit {
   public void eat() {
       //some code
   }
}

另外两个班级

public class Banana extends Fruit{

}
//
public class Apple extends Fruit{

}

现在让我们创建一个人

public class Person {
    public void eat(Fruit f) {
        f.eat();
    } 
}

让我们现在使用

public static void main(String[] args) {
    Person p = new Person();
    // We are creating a random Fruit, and pass it to the person to eat.
    // We can´t be more specific here and don´t need to be more specific
    Fruit f = getRandomFruit();
    p.eat(f);
}

public static Fruit getRandomFruit() {
    if(new Random().nextInt(2) == 0) {
        return new Banana();
    } else {
        return new Apple();
    }
}

答案 1 :(得分:1)

我认为在这种情况下,这个例子弊大于利。要执行任何CircleShape相关操作,您需要投射当前对象。除了增加潜在开销之外,这可能会导致诸如不兼容类型之类的问题。

通常建议进行泛型编程,因为它允许您的代码灵活。 与您发布的示例不同,建议仅在完成时才建议。将所有内容创建为对象几乎总是弊大于利

List为例,如果您在哪里找到一个返回ArrayList<String>的方法:public ArrayList<String> foo(),那么,您将被绑定到该特定类型。如果您想要一个链表,您可能需要编写某种转换器,从LinkedList<String>创建一个ArrayList<String>

另一方面,如果您使用通用界面,您的方法将变为如此:public List<String> foo()。这将允许曾经消费foo的人能够创建任何一个实现List接口的数据结构,而无需通过箍。

编辑:根据你的评论,大部分时间它没有帮助。正如我在答案中提到的那样,弊大于利。使用对象的一个​​实例是ObjectInputStream提供的readObject()方法。当您正在阅读ObjectInputStream不知道的自定义对象时,将使用此方法。因为在Java中,所有内容都扩展了Object类,所以此方法会生成一个对象。即便如此,我所看到的这种方法的每个插图最终都会将其转化为其他内容。

答案 2 :(得分:1)

如果你稍微修改一下这个例子,从Circle而不是从Square派生RectAngleShapeShape,这将是有道理的。 getArea()可以使用Shape circle = new Circle(); Shape rectangle = new Rectagle(); 等方法以及高度和宽度等属性,这些属性可以被派生类覆盖。

methods

在现实生活中的示例中,最好为派生类使用Base泛型类型,以便实现可以在运行时更改。

如果您正在寻找对象创建,请使用简单的Factory

如果您希望在运行时更改对象的行为,请使用Strategy_pattern

如果您正在制定多种功能策略,则可以通过将基础更改为新的派生策略来动态替换策略。

看看下面的例子:

Design Patterns: Factory vs Factory method vs Abstract Factory

Real World Example of the Strategy Pattern