5

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

在制作新对象时,是否有任何理由在此处向上转换,通过编写以下代码:

Shape s = new Circle();

而不是这个:

Circle s = new Circle();

这两个陈述中的每一个所产生的s对象是否彼此不同?

4

7 回答 7

3

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

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

于 2011-03-29T08:58:40.367 回答
3

就 JVM 而言,这两个语句将产生相同的对象。表明您只打算将对象用于基类或接口的情况并不少见。例如,这是常见的:

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

虽然通常不是一个好主意,但如果您确定它是一个,您可以将其转换为 a,例如,Shape您可以将它带回 a :CircleShape sCircle c

if (s instanceof Circle) {
    Circle c = (Circle) s;
    // handle Circle case
}
于 2011-03-29T08:53:43.473 回答
2

实例化的对象完全相同。

向上转型的后果是:

  1. 存储中的泛化:所有不同专业类型的对象都可以被威胁为相同的接口,并且可以一起存储到数据结构中。(就像@WhiteFang34 指出的那样:List < Shape>)
  2. 访问对象方法的泛化:客户端类可以在不知道真实类型的情况下调用Shape的方法(通常您可以使用工厂创建返回公共接口Shape的对象,因此客户端类不知道对象的真实类型但仅Shape 的接口方法被暴露)
于 2011-03-29T09:07:28.333 回答
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

于 2011-03-29T09:30:43.940 回答
0

我同意@WhiteFang34 所说的。

看到这个Coding to interfaces 了吗? 这可能会帮助你。

于 2011-03-29T08:58:13.273 回答
0

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

进行这样的强制转换的一个原因是表达您喜欢如何对待对象(以便您可以轻松地插入不同的派生类)。

于 2011-03-29T08:56:20.527 回答
-2

圆 s = 新圆();
这里的对象是指类 Cricle

形状 s = new Circle(); 这里的对象是指接口

两者都是一样的。

于 2011-03-29T08:56:50.240 回答