Packages in scala are similar to java but a lot more flexible and at a higher level. By higher level I mean a developer can organize the packages in a program from his/her logical view and do not have to worry about the lower level folder structure in which JVM requires the packages to be organized.
Once again scala provides an abstraction and flexibility that would be nice to have in Java.
so let us say I want to define a package coms.abc.depts and com.abc.depts.employee.
Every java programmer knows how to do this in Java. Only by hte naming convention we indicate that these two packages in fact are related, but there is no other way to organize them like the scala code below.
package coms {
package abc {
package depts {
class Dept(val deptName: String, val deptId: Int) {
def findNumOfEmployees(): Int =
{
var nEmps = 0;
nEmps;
}
}
package employee {
class Employee(val ssn: Int, val name: String) {
}
}
}
}
}
This code of course will be organized into two different directories for java classess.
When we define a package, of course, we have to talk about how to import the package.Here again scala provides a way to import a package where it is required making the code much more easy to read and less cluttered at the top. every java programmer who has to use java's date and java.sql.Date can quickly appreciate it.
Let us see an example that shows the versatility of the import statements. The code also shows how the constants can be defined, imported and used. Most apps we have at least one list of constants, the public static finals. Scala implements pure oops, and therefore does not have any static declarations.
Here is how we will define constants in Scala.
package org.manu.blog.constants
object MyContext{
val appName = "Manu Blog"
val banner = "Welcome to Manu's Blog"
val mission ="Our mission is to explore the Human origins"
val end ="Mission accomplished"
}
Now to use it, this is how we will import the constants as well as the dept and employee we defined.
package org.manu.test
object Test11 {
def main(args: Array[String]) {
employees
def employees = {
import org.manu.blog.constants.MyContext._
println("welcome to " + appName + "\n" + mission)
import coms.abc.depts.Dept
val dep = new Dept("my Dept", 10)
import java.math.BigDecimal, BigDecimal._
println("Employees in my dept :" + dep.findNumOfEmployees);
println("Our CEO currently draws a salary of "+ ZERO)
println(end)
}
}
}
The points worth noting are:
1. Once we import a package/class, now we can use its contents thereafter.
That is how we are using the appName and end strings.
2. The scala style packages we defined for dept and employee have the same nomenclature as java, i.e. coms.abc.dept
3. The _ which works like * in Java for imports, is applicable also to a Object. This is what the declaration is : import org.manu.blog.constants.MyContext._
This declaration essentially means that we can now use all the members object MyContext directly with their name. i.e. We can do not have to access end as MyContext.end any more.
4. Java's static can also be imported in scala. That is how we are using ZERO of BigDecimal in the statement. The statement import java.math.BigDecimal, BigDecimal._ is how it is done, simialr to the one in 3 above.
In a nutshell, I like the scope style declaration of the packages and find it much more intuitive for nested and closely related package declarations.
I think for the packages that are mostly used in a class, I will like to import those in java style, at the top of the class file. As we know there are many time packages that are used may be only once or twice in a class and in such situations I find the scala style import very useful and intuitive as well.
Access Modifiers
Private:
With packages, the other appropriate discussion is about the access modifiers.
The thing I like a lot is the Default is PUBLIC. How many times do we really declare a class that is NOT public. I think this is a great improvement.
So the default is public and private is java like private when declared inside a class. Now just like java static the private of a class is also available to its companion class which we will use to declare the static members of a class.
Now let us say we want ot hide the findNumbers of the department class and instead provide a static method to show the numbers. (not a great example but works for the concept).
Let us make the corresponding changes to the Dept class:
class Dept(val deptName: String, val deptId: Int) {
private def findNumOfEmployees(): Int =
{
var nEmps = 0;
nEmps;
}
def companyName(): String = {
Dept.company
}
object Dept {
val company = "ABC Company"
def showNumbers(): String = {
company + " : " + deptName + findNumOfEmployees
}
}
}
Points to note:
1. The private method findNumuOfEmployees can be used directly in the companion object.
2. The company declared in the companion object can be in turn used int the any class method of the class of the companion object.t
This is the way to call these from any other object:
import coms.abc.depts._
val dep = new Dept("Motor Vehicle ", 10)
println( "show Numbers: " + dep.Dept.showNumbers() );
Private and Protected Scopes
Private can be further qualified with a package, let us says we have a method in Employee that returns if an employee is a contractor, the Dept class might have a method to count all its contractors. We therefore want this method exposed to the Dept package classes but not any other classes.
To achieve this we will put a qualifier on this method as follows.
package employee {
class Employee(val ssn: String, val name: String) {
private[depts] def isContractor() : Boolean = { true}
}
}
Now we can use this method only inside the depts classes as below.
def findContractors(){
import coms.abc.depts.employee._
var emp = new Employee("55", "Unknown")
emp.isContractor;
}
However we cannot use it any other package. Similarly we can use protected with a qualifier.
The java visibility and scala visibility works as follows
Once again scala provides an abstraction and flexibility that would be nice to have in Java.
so let us say I want to define a package coms.abc.depts and com.abc.depts.employee.
Every java programmer knows how to do this in Java. Only by hte naming convention we indicate that these two packages in fact are related, but there is no other way to organize them like the scala code below.
package coms {
package abc {
package depts {
class Dept(val deptName: String, val deptId: Int) {
def findNumOfEmployees(): Int =
{
var nEmps = 0;
nEmps;
}
}
package employee {
class Employee(val ssn: Int, val name: String) {
}
}
}
}
}
This code of course will be organized into two different directories for java classess.
When we define a package, of course, we have to talk about how to import the package.Here again scala provides a way to import a package where it is required making the code much more easy to read and less cluttered at the top. every java programmer who has to use java's date and java.sql.Date can quickly appreciate it.
Let us see an example that shows the versatility of the import statements. The code also shows how the constants can be defined, imported and used. Most apps we have at least one list of constants, the public static finals. Scala implements pure oops, and therefore does not have any static declarations.
Here is how we will define constants in Scala.
package org.manu.blog.constants
object MyContext{
val appName = "Manu Blog"
val banner = "Welcome to Manu's Blog"
val mission ="Our mission is to explore the Human origins"
val end ="Mission accomplished"
}
Now to use it, this is how we will import the constants as well as the dept and employee we defined.
package org.manu.test
object Test11 {
def main(args: Array[String]) {
employees
def employees = {
import org.manu.blog.constants.MyContext._
println("welcome to " + appName + "\n" + mission)
import coms.abc.depts.Dept
val dep = new Dept("my Dept", 10)
import java.math.BigDecimal, BigDecimal._
println("Employees in my dept :" + dep.findNumOfEmployees);
println("Our CEO currently draws a salary of "+ ZERO)
println(end)
}
}
}
The points worth noting are:
1. Once we import a package/class, now we can use its contents thereafter.
That is how we are using the appName and end strings.
2. The scala style packages we defined for dept and employee have the same nomenclature as java, i.e. coms.abc.dept
3. The _ which works like * in Java for imports, is applicable also to a Object. This is what the declaration is : import org.manu.blog.constants.MyContext._
This declaration essentially means that we can now use all the members object MyContext directly with their name. i.e. We can do not have to access end as MyContext.end any more.
4. Java's static can also be imported in scala. That is how we are using ZERO of BigDecimal in the statement. The statement import java.math.BigDecimal, BigDecimal._ is how it is done, simialr to the one in 3 above.
In a nutshell, I like the scope style declaration of the packages and find it much more intuitive for nested and closely related package declarations.
I think for the packages that are mostly used in a class, I will like to import those in java style, at the top of the class file. As we know there are many time packages that are used may be only once or twice in a class and in such situations I find the scala style import very useful and intuitive as well.
Access Modifiers
Private:
With packages, the other appropriate discussion is about the access modifiers.
The thing I like a lot is the Default is PUBLIC. How many times do we really declare a class that is NOT public. I think this is a great improvement.
So the default is public and private is java like private when declared inside a class. Now just like java static the private of a class is also available to its companion class which we will use to declare the static members of a class.
Now let us say we want ot hide the findNumbers of the department class and instead provide a static method to show the numbers. (not a great example but works for the concept).
Let us make the corresponding changes to the Dept class:
class Dept(val deptName: String, val deptId: Int) {
private def findNumOfEmployees(): Int =
{
var nEmps = 0;
nEmps;
}
def companyName(): String = {
Dept.company
}
object Dept {
val company = "ABC Company"
def showNumbers(): String = {
company + " : " + deptName + findNumOfEmployees
}
}
}
Points to note:
1. The private method findNumuOfEmployees can be used directly in the companion object.
2. The company declared in the companion object can be in turn used int the any class method of the class of the companion object.t
This is the way to call these from any other object:
import coms.abc.depts._
val dep = new Dept("Motor Vehicle ", 10)
println( "show Numbers: " + dep.Dept.showNumbers() );
Private and Protected Scopes
Private can be further qualified with a package, let us says we have a method in Employee that returns if an employee is a contractor, the Dept class might have a method to count all its contractors. We therefore want this method exposed to the Dept package classes but not any other classes.
To achieve this we will put a qualifier on this method as follows.
package employee {
class Employee(val ssn: String, val name: String) {
private[depts] def isContractor() : Boolean = { true}
}
}
Now we can use this method only inside the depts classes as below.
def findContractors(){
import coms.abc.depts.employee._
var emp = new Employee("55", "Unknown")
emp.isContractor;
}
However we cannot use it any other package. Similarly we can use protected with a qualifier.
The java visibility and scala visibility works as follows
no modifer | public access, any class in any package can access |
private[depts] | access within enclosing /outer package depts (all classes) |
private[employee] | only inside the package employee, the default access of java |
private[Employee] | same as private in Java |