制作物体时的向上倾斜

时间:2011-03-29 08:50:03

标签: java upcasting

假设您有一个Shape基类和各种派生类型:Circle等。

通过写这个:

,在制作新物品时是否有任何理由在那里进行向上翻转
Shape s = new Circle();

而不是:

Circle s = new Circle();

并且这两个语句中的每一个所做的s对象是否以任何方式彼此不同?

7 个答案:

答案 0 :(得分:3)

就JVM而言,这两个语句将产生相同的对象。显示您只计划将对象用于基类或接口并不罕见。例如。这很常见:

List<String> list = new ArrayList<String>();

虽然通常不是一个好主意,但如果您确定它是一个Shape,则可以将Circle投回Shape s,例如使用Circle c,您可以将其带回if (s instanceof Circle) { Circle c = (Circle) s; // handle Circle case }

{{1}}

答案 1 :(得分:3)

你可以说你的第一个例子(即Shape s = new Circle();)可以具有与“编码到界面”相同的优点,即使Shape可能是抽象的甚至是具体的基类。因此,例如,如果您只使用Shape上定义的方法而不是Circle特有的方法,那么您可以很容易地将您正在使用的实现更改为Square,例如只需更改一行代码,即{{1 }}

两个示例中的对象都是相同的,第一个选项可以被认为更好的原因更多的是样式事物。对接口进行编码可以使代码库更容易扩展和修改。

答案 2 :(得分:1)

实例化的对象完全相同。

向上转播的后果是:

  1. 存储时的泛化:不同专用类型的所有对象可以作为相同的接口进行威胁,并且可以一起存储到数据结构中。 (如@ WhiteFang34指出:List&lt; Shape&gt;)
  2. 访问对象时的泛化方法:客户端类可以在不知道实际类型的情况下调用Shape的方法(通常可以使用工厂创建返回公共接口Shape的对象,因此客户端类不知道实际类型的对象,但只暴露了Shape的接口方法)

答案 3 :(得分:1)

在回答你的问题时,这两个对象完全相同。两个引用都可以指向同一个对象:

Circle c = new Circle();
Shape s = c;

编码到接口允许您更改实现类,而对代码的影响最小。说你有这个:

Set<String> names = new HashSet<String>();         // using Set reference not HashSet
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

现在您的需求发生了变化,您希望按字母顺序打印名称,即使用HashSet而不是TreeSet。因为您已编码到接口而未使用任何特定于HashSet类的方法,所以您只需更改一行:

Set<String> names = new TreeSet<String>();   // the only line of code that changes
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

接口还允许您使用依赖注入。它允许您使用在编写代码时可能不存在的类。

http://en.wikipedia.org/wiki/Dependency_injection

答案 4 :(得分:0)

不,对象本身并没有什么不同。只有编译器认为他所看到的是不同的(例如,哪些方法可用)。

进行此类演员的一个原因是表达您希望如何对待对象(以便您可以轻松地插入不同的派生类)。

答案 5 :(得分:0)

我同意@WhiteFang34所说的话。

Coding to interfaces? 这可能会对你有所帮助。

答案 6 :(得分:-2)

Circle s = new Circle();
这里的对象是指圆圈

Shape s = new Circle(); 这里反对它引用接口

两者都是一样的。