Scala Function Variance and Overriding

后端 未结 4 552
野性不改
野性不改 2021-02-04 18:09

I\'m having a little problem understanding variance of methods when overloading.

While this perfectly works due to covariance in the return type

class Bl         


        
4条回答
  •  野性不改
    2021-02-04 19:04

    There are two things going on here:

    1. A function and a method are not the same thing
    2. Methods are not polymorphic in their parameters' types

    Your tester method is a method, not a Function1. It can be lifted into a function using the underscore syntax:

    val f = (new FooTest[String]).tester _ // Fasel => Bla
    

    This function will be contra-variant in its input type. (It's worth saying, however, that functions cannot be parameterized and also worth saying that I had to have an instance of Foo or FooTest in order to get a function object for the tester method. This of course follows from the first observation!)

    A function is an object, it cannot be overridden as that makes no sense. Methods can be overridden. However, as I say above, the overriding is not polymorphic in the method's parameter types. So for example:

    class A {
      def foo(a : Any) = println("A: " + a)
    }
    
    class B extends A {
      override def foo(s : String) = println("B " + s) //will not compile!
    }
    

    The two methods in my example above are two separate methods: dynamic dispatch works only on the method target (i.e. the object on which it is being called).

    In the above, example, if you remove the override declaration, the code will compile. If you run the following:

    (new B).foo(1)   //prints A 1
    (new B).foo("s") //prints B s
    

    This is because, although both methods are called foo, they are completely different methods (i.e. I have overloaded foo, not overridden it). It's best understood as being that a method's arguments' (incl their types) form part of that method's unique name. One method overrides another only if they have exactly the same name.


    Essentially you have confused what are two separate and un-related things in your question, which I will put down for clarity:

    • The variance annotations on Function1 define what it means for one function to be a subtype of another (and hence assignable to a reference of a given type).
    • Methods can be overridden on subclasses and the language specification outlines rules for when such overriding takes place.

提交回复
热议问题