Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler not look in the enclosing class for a method?

Have a look at the following Scala example:

class A {
  def foo(x: Int): Int = x

  private class B {
    def foo(): Int = foo(3)
  }
}

The compiler produces an error message when trying to compile this:

A.scala:5: error: too many arguments for method foo: ()Int
                def foo(): Int = foo(3)
                                    ^

For some reason the compiler doesn't look in the enclosing class A to find the method to call. It only looks in class B, finds the foo method there that takes no parameters that doesn't fit and then gives up. If I rename the methods, then it works without a problem:

class A {
  def bar(x: Int): Int = x

  private class B {
    def foo(): Int = bar(3)
  }
}

In this case, the compiler does look in class A and finds the bar method there.

Why does the first example not work; is this according to Scala's specifications, or is this a compiler bug? If this is according to the rules, then why are the rules like this?

By the way, another way to get around the problem is by using a self type annotation:

class A {
  self =>

  def foo(x: Int): Int = x

  private class B {
    def foo(): Int = self.foo(3)
  }
}
like image 944
Jesper Avatar asked Mar 09 '11 15:03

Jesper


People also ask

What is a enclosing class in Java?

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.

Can an inner class method have access to the fields of the enclosing class?

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

Are declared inside a class but outside a method?

A class that is declared inside a class but outside a method is known as member inner class.

Can we create a class inside a class in Java?

In Java, it is possible to define a class within another class, such classes are known as nested classes. They enable you to logically group classes that are only used in one place, thus this increases the use of encapsulation, and creates more readable and maintainable code.


1 Answers

Technically the class B is a block. You could reduce the problem to the following:

def foo(x: Int): Int = x;
{    
   def foo(): Int = foo(3)
}

That would cause the exact same problem. It is compliant to the specs, because all names introduced in a block shadow anything that has the same name (ignoring the signature, see chapter 2 of the spec). Overloading is only possible on class level. (chapter 6.26.3 in the spec)

like image 139
Martin Ring Avatar answered Sep 23 '22 13:09

Martin Ring