[英]Type Parameters in `abstract class`
Given: 鉴于:
scala> abstract class Foo[A] {
| def f: A
| }
defined class Foo
, and an implementation ,以及一个实现
scala> class FooImpl extends Foo[Any] {
| def f: Any = "foo"
| }
defined class FooImpl
and then an instantiation 然后实例化
scala> new FooImpl().f
res0: Any = foo
res0
has type Any
, as I'd expect since FooImpl
uses Any
as its type parameter to Foo
. 正如我所期望的那样, res0
具有Any
类型,因为FooImpl
使用Any
作为其Foo
类型参数。
And, given a second implementation: 并且,给出第二种实现:
scala> class FooImpl2 extends Foo[Any] {
| override def f= "foo"
| }
defined class FooImpl2
and an instantiation and call to f
: 以及实例化并调用f
:
scala> new FooImpl2().f
res1: String = foo
Why is res1
's type a String
? 为什么res1
的类型为String
?
Whereas, given: 鉴于:
scala> def g[A](x: A):A = x
g: [A](x: A)A
I can pass y
, an Int
: 我可以通过y
,一个Int
:
scala> val y: Int = 55
y: Int = 55
to g
到g
scala> g[AnyVal](y)
res3: AnyVal = 55
and get back an AnyVal
. 并返回AnyVal
。
Finally, 最后,
scala> g(55)
res5: Int = 55
returns an Int
, as expected. 按预期返回Int
。
However, I would've expected FooImpl2#f
to have returned an Any
given FooImpl2
's extends Foo[Any]
. 但是,我期望FooImpl2#f
返回Any
给定FooImpl2
的extends Foo[Any]
。
Why not? 为什么不?
When you override a member of an abstract class or trait, you are allowed to narrow its type to something more specific. 当您覆盖抽象类或特征的成员时,可以将其类型缩小为更具体的类型。 It doesn't appear that way here, because you're relying on type inference for override def f = "foo"
, but it's really override def f: String = "foo"
. 它不会出现这样在这里,因为你依靠的类型推断override def f = "foo"
,但它确实override def f: String = "foo"
。
This is legal: 这是合法的:
abstract class Foo[A] {
def f: A
}
class FooImpl2 extends Foo[Any] {
override def f: String = "foo"
}
String
still conforms to the type parameter A = Any
, but f
has been refined in FooImpl2
to String
. String
仍然符合类型参数A = Any
,但是f
在FooImpl2
已经细化为String
。
Here is an example without the type parameter: 这是一个没有类型参数的示例:
abstract class A { def f: Any }
class B extends A { override def f: String = "a" }
g[AnyVal](y)
is a just very different example. g[AnyVal](y)
是一个非常不同的示例。 Since you are manually supplying the type parameter of AnyVal
to g
, you are asking the compiler to make sure y
is AnyVal
, but it doesn't matter if it is some more specific type (a more specific type returned by method will always be up-cast to the return type). 由于您正在向g
手动提供AnyVal
的类型参数, AnyVal
您要求编译器确保y
为AnyVal
,但是它是否是更特定的类型并不重要(方法返回的更特定的类型将始终是up -cast到返回类型)。 In FooImpl2
you are simply changing the signature of f
. 在FooImpl2
您只需更改f
的签名。
When you override
a method, you can make it return more specific type. override
方法时,可以使其返回更特定的类型。 In this line 在这条线
override def f= "foo"
you didn't specify return type and it was inferred to be String
您未指定返回类型,因此推断为String
A subclass can narrow the return types of the methods that it overrides. 子类可以缩小其覆盖的方法的返回类型。
The return type of f
in Foo[Any]
is Any
. Foo[Any]
中f
的返回类型为Any
。 FooImpl2
is a subtype of Foo[Any]
and you didn't specify f
s return type so the compiler infers that it is String
, which is a subtype of Any
and thus satisfies all constraints. FooImpl2
是Foo[Any]
的子类型,您没有指定f
s返回类型,因此编译器推断它是String
,它是Any
的子类型,因此满足所有约束。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.