5 回答
TA贡献1790条经验 获得超9个赞
到目前为止,我真的不喜欢这些答案。他们正在把简单的事情变得复杂起来。
变量只是一个引用的持有者。
正如您从示例中看到的,变量的类型不必与其所保存的引用的确切类型相匹配。该变量只需等于或比其引用更通用(或者,如果您愿意,等于或不那么具体)。Car
比 更通用Ford
,因此该分配是可以的。
每个引用都可以由变量保存Object
,因为这是Java 中存在的最通用的类型。
Object foo = new Car(1, 6);Object bar = "hello world";
现在,使用这些变量的困难在于我们只能调用类中的方法Object
。通过将变量声明为Object
,当我尝试访问内容时,我只能使用方法,无论Object
其中实际存储了什么。
Object
(例如)有几个方法toString
,所以这可能没问题,但在大多数情况下分配给Object
并不是很有用。
因此,我们对变量越具体,我们可能访问的功能就越多。
当你说
Car car = new Ford("ford", 6);
当从此变量引用它时,我们可能无法访问一些福特特定的功能。我们总是可以稍后通过强制转换实例来解决这个问题,但除非绝对必要,否则应该避免这样做。
然而,我们越通用,我们的代码就越灵活。如果一个方法只以福特汽车作为参数,那是相当有限制的。如果可以取任何一辆车作为参数,那就更加灵活了。
一般来说,在为变量选择正确的类型时,您可以在心里尽可能地从最通用的类型开始,然后不断使其变得更加具体,直到它适合您的用例。
例如,如果您可以选择“prefer Iterable
over a” Collection
、“prefer Collection
over a” List
、“prefer List
over an” ArrayList
。
TA贡献1777条经验 获得超10个赞
Ford ford = new Ford("ford", 6); Car ford2 = new Ford("ford", 6);
两个对象变量都引用福特类对象。但对象变量的类型不同。就像福特是福特的类型,但福特2是汽车的类型。
它被称为概括对象创建。始终建议概括对象引用创建,因为您可以通过分配继承相同超类的不同类型的子类来更改对象引用类型。
除此之外,下面提到的差异也是一个有用的情况。
Car car = new Car("car", 4);
该汽车对象只能访问 Car 类方法。
Ford ford = new Ford("ford", 6);
该对象可以访问两个类的所有方法。但是假设你在两个类中都有如下所示的 1 个方法
public static void a(){ system.out.println("static method"); }
如果福特对象调用方法a()。它将运行子类中存在的方法。因为 Ford 变量是 Ford 子类的类型。
Car ford2 = new Ford("ford", 6);
该对象可以访问两个类的所有方法。但是假设你在两个类中都有如下所示的 1 个方法
public static void a(){ system.out.println("static method"); }
如果福特对象调用方法a()。它将运行超类中存在的方法。因为 ford2 变量是 Ford 超类的类型。
TA贡献1794条经验 获得超8个赞
我只是想问一下福特和福特2有什么区别吗?或者它们完全一样吗?
最好的答案是:这取决于。
这取决于您所说的“相同”到底是什么意思。
在Java中,new
需要操作符来创建一个新对象。因此,这两个赋值会将新创建的对象分配给变量ford
和ford2
。这些对象将具有不同的引用,因此在 JVM 中具有不同的标识。结果,以下内容将评估为false
:
boolean b = (ford == ford2);
然而,这两个对象可以说具有相同的属性,因为它们的实例字段包含相同的值。就目前而言,该表达式的计算结果也为false
:
boolean b = (ford.equals(ford2));
equals()
因为从Object
分配变量的两种类型(即Car
和)继承的默认方法Ford
执行与上一条语句中评估的相同的引用比较。如果类equals()
中的方法Ford
被重写以执行值比较(而不是默认的引用比较),如下所示:
@Override boolean equals(Object ob) { if (!(ob instanceof Ford)) return false; Ford f = (Ford) ob; return this.name.equals(f.name) && this.wheels == f.wheels; }
那么下面的表达式将计算为true
:
boolean b = ford.equals(ford2);
TL;DR:变量引用的对象ford
具有ford2
相同的类型(即它们都是Ford
s)、相同的属性,但不同的标识。如果如图所示为类定义了值比较Ford
,那么它们将具有相同的值,否则它们不会。
TA贡献1811条经验 获得超5个赞
从技术上讲,它们不一样 -==
会给出false
- 但它们保存相同的数据(不一样意味着修改一个不会影响另一个)并且它们是相同的类型。但是,您只能通过将ford2
其强制转换来调用仅在Ford
类中定义的方法(如果有的话)Ford
(在这种状态下,ford2
您只能调用Car
的方法)。
添加回答
举报