Scala/Packages
A package is an organization unit that can contain entities such as classes, objects and other packages. Entities that are contained in a given package belong to that package's namespace.
Note that the following examples may not work in the Scala REPL.
Packages
editA package can be declared at the start of a source file:
package geometry
class Rectangle
In the first line, the keyword "package" followed by the name "geometry" declares a package named "geometry". All following entities belong to that package. In the third line, a class named "Rectangle" is defined, and since it is declared in the package "geometry", its full identifier is "geometry.Rectangle".
Multiple nested packages can be declared by inserting "." between each package:
package org.transport.vehicles
class Car
In the first line, the nested packages "org", "transport" and "vehicles" are declared. "org" is the outermost package, "transport" is the middlemost package, and "vehicles" is the innermost package. In the third line, a class named "Car" is defined, and its full identifier is "org.transport.vehicles.Car".
A similar method is to chain the packages:
package org
package transport
package vehicles
class Car
This declares 3 nested packages and a class named "Car", with the full identifier "org.transport.vehicles.Car".
Packages can also be declared elsewhere in the source by following the package name with a pair of curly brackets:
package org.transport
package vehicles {
class Car
}
package fuel {
class Gasoline
}
The first line defines the nested packages "org.transport". Lines 3 to 5 defines a package belonging to "org.transport" named "vehicles", which contains the class "Car". Lines 7 to 9 defines a package belonging to "org.transport" named "fuel", which contains the class "Gasoline". Class "Car" has the full identifier "org.transport.vehicles.Car", and class Gasoline has the full identifier "org.transport.fuel.Gasoline".
An entity in one namespace cannot in general refer directly to an entity in another namespace without using the full identifier:
package somePack1 {
class SomeClass
}
package somePack2 {
class AnotherClass {
val a = new somePack1.SomeClass
//ERROR: Does not compile!
//val b = new SomeClass
}
}
In certain cases, entities in different namespaces can refer to each other without using the full identifier. One case is when referring to entities in packages that are higher up in the hierarchy. The rule is that all the declared packages for an entity that is in the final part of each nested declaration can be referred directly.
package p1.p2.p3
class A
package p4 {
class B
}
package p4 {
package p5 {
class C
}
package p5.p6 {
class D {
val a = new A
val b = new B
val c = new p5.C
//ERROR: Does not compile!
//val c2 = new C
}
}
}
In the above, several layers of packages are declared. The lowest package, "p6", contains a class named "D". For class "D", its package declarations can be summarized as "p1.p2.p3", "p4" and "p5.p6". Since packages "p3", "p4" and "p6" are at the end of each package declaration for "D", all their members can be referred directly in "D". Conversely, entities in "p1", "p2", and "p5" cannot be referred directly. This helps give fine-grained control over which entities can or can not be directly referred to. The default approach is to declare the packages in one declaration, meaning that only entities in the current package can be directly referred to.
Lower nested packages shadow higher packages. This means that in some cases, it may become difficult to refer to a specific entity. The special package "_root_" can be used in those cases. All top-level packages are considered members of "_root_":
package tools {
class Console
}
package carpentry {
package tools {
class Hammer
package testing {
class A {
val console = new _root_.tools.Console
//ERROR: Does not compile!
//val console2 = new tools.Console
}
}
}
}
In the above, from the point of view of class "A", the package "tools" refers to the "carpentry.tools" package, since it shadows the "tools" package. In order to refer to the outermost "tools" package, the package "_root_" is used.
It should be noted that entities in different packages can often be referred to more easily through the use of importation, which is described in Scala/Import.