The BASE for JAVA LEARNING

by PRO FE S S OR


SECTION XI - PACKAGES and VISIBILITY MODIFIERS

Step 45: Packages (Directories) and importing them


Packages (directories) and importing them

Packages in JAVA refer to directories. They are like clusters where we can place our class files. When two or more JAVA files are in a directory (folder), we can say that those files are in the same package.

There are many JAVA packages in the language. When going to the JAVA documentation it can be found that classes are organized within packages. Classes fundamentals to the design of Java programming are contained in the java.lang package. This package does not need to be imported when using any of its classes. ('import' will be covered soon.)

Classes such as Object, String, System, Math are in the java.lang package. When working with JAVA, the programmer can create his or her own packages to place the classes being developed. It is a matter of creating a directory (folder) and place the JAVA file in it.

The package can also be created in a specific directory at compiling time, by using the -d option of the 'javac' instruction of the Command Prompt line.

Example: javac -d users Exercise.java That would placed the bytecode 'Exercise.class' on a directory named 'users'.

The package java.lang is the default package for JAVA. All classes that we generate in our working directory are considered to be in the same directory of java.lang. As stated before, there is no need to import that package. All classes within a directory together with the java.lang package are said to be "package" friendly, and that means that classes are visible within in the same package or directory.

The way directories/subdirectories are stated in UNIX is by using the forward slash, and in DOS is by using the backslash.

Example: TopLevel/users/agendas or TopLevel\users\agendas refers to a directory 'TopLevel' that has a sub-directory 'users', and under this, a sub-directory 'agendas'.

If we create a JAVA program that uses JAVA classes contained in a package, then we use dots to refer to that package instead of slashes.
TopLevel.users.agendas Files that are in packages are identified by the keyword 'package' followed by the package name. This has to be the first line of code in the program, before defining a 'class'.

If you are using a working directory and all your JAVA files are in the same directory you may not have to worry about packages. But this is usually not the case in projects, as packages let the programmer be selective in term of clustering classes by their characteristics or functionalities.

Example of a file named Exercise.java contained in the TopLevel.users.agenda package: package TopLevel.users.agenda;
public class Exercise // it's public for interaction between packages
// See Visibility Modifiers next step
{ // class definition }
The class above is defined within the TopLevel.users.agenda package. The file Exercise.java should be placed under the TopLevel/users/agenda folder.


IMPORTING JAVA files

As we discussed above, the first line of code before defining a class is package. The second line of code is 'import', also before defining a class .

If we need to use a class from a file that is not in the package (directory) where our file is, then we need to import that class from that package.

JAVA is 'package' friendly, and that means that if we have lots of files in the same package (directory), we would not have to worry about importing any of the classes of those files if we want to use them in our program. As discussed before, if all our JAVA files are in our working directory, we would not have to use either 'package' or 'import'. (not usually the case in company projects.)

We can import one class, many classes, or all classes. Using the * (wild card sign) we can import all classes of the package.

Example of importing only one class: package TopLevel.users.agenda; // package where this file Exercise.java is.
import TopLevel.users.schedule.Summary;
// importing the class "Summary" in the TopLevel.users.schedule package.
// Our program can use the Summary class contained in that package

public class Exercise // it's public for interaction between packages
{ public static void main(Stringp[] args)
{ Summary text = new Summary(); // class Summary is in the TopLevel.users.schedule package }
// continues with class definition
}
Example of importing all classes of a package: package TopLevel.users.agenda; // pacakge where this file Exercise.java is.
import TopLevel.users.schedule.*; // Notice the wild card * symbol.
// importing all classes in the TopLevel.users.schedule package.
// Our program can use all classes contained in that package

public class Exercise // it's public for interaction between packages
{ public static void main(Stringp[] args)
{ Summary text = new Summary(); // class Summary is in the TopLevel.users.schedule package
Outline form = new Outline(); // class OUtline is in the TopLevel.users.schedule package
}
// continues with class definition
}

We can import as many packages as needed. With the exception of java.lang, any other package that we use from JAVA programming packages, need to be imported.

For example, let's say that we want to use the JAVA awt GUI classes. For that we will need to import the java.awt package. If we need to use input/output methods which are under Stream classes, we need to import the java.io package.

Click here to go to the JAVA Mini-Course page



The BASE for JAVA LEARNING

by PRO FE S S OR


SECTION XI - PACKAGES and VISIBILITY MODIFIERS

Step 46: Visibility Modifiers


VISIBILITY MODIFIERS

Visibility modifiers are used to impart different levels of accessibility upon classes and their members.

Not all classes or members of a class can be accessed all the time. For instance, a private method can only be accessed by methods of its own class.

There are 4 Visibility modifier. From high visibility to lower visibility they are:
  • public
  • package (by default)
  • protected (in the case of Inheritance, is less restrictive than package)
  • private
In the case of Inheritance, it is important to notice that when an overriding class method exists, it is necessary that the Visibility modifier of the super class method be the same or more visible (less restrictive) than the sub-class method. For instance, if a super class method is defined as 'public', its counterpart method (same name, same signature and return type) in the sub-class has to be 'public'. (See Overriding under INHERITANCE - Section X.)


The 'public' visibility modifiers

A class and its members can be made public.

The 'public' visibility modifiers has the highest visibility of all. That means that any member or class that is public can be seen by any other class or member.

In order to make a member or class publicly visible, the keywrod 'public' is used.

Example: public class Exercise // class Exercise is made public to every other class
{ public int year; // variable 'year' is made public to every class.
public void test() // this method is made public to every class.
{ // method test is defined here }
// class definition continues here
}
Even though a class is public, that does not mean that you can use it in a file that is in a different package without importing that file. You still need to 'import' that package.


The 'package' (default) visibility modifier

By default all classes, method and variables are all 'package' visible. That's what we mean when we stated that JAVA is package friendly. There is no keyword to express this visibility. By not using any keywrod the class or member is then package visible.

Package visible means that any class contained within a package (directory) is visible to every other class. Any member of a class that is contained within a particular package is visible to any other members of any class within that same package.


The 'protected' visibility modifier

The 'protected' visibility modifier is more restrictive than package. However, in the case of Inheritance, it becomes more visible than package. That is, any member that is made protected in a class can be visible to its derived classes even if in different packages.

Only members can be made protected. Classes are not made protected in JAVA (with the exception of Inner Classes which is outside the scope of this Mini course).

When both the super class and sub-class are in the same package, then protected members of the parent class are only visible to the sub-classes.

Protected members of a class are only visible to those sub-classes that are derived from its class. Only sub-classes can access protected members of its super-class. It goes down the hierarchy levels. That is, protected members are not only visible to the first level of hierarchy (the child class), but they are also visible to the grand-child class, great-grand child class, etc.

Notice that classes do not have to be in the same package for its members to be protected.

Let's say that Exercise class has a sub-class Quiz, both classes in different packages; then a member of the Exercise class, 'int year' is protected. It is written as: protected int year;

Then the Quiz class can access 'year' even though the class is in another package. Of course, Quiz class still needs to be imported by Exercise.java.

Protected members of a super-class can only be seen by the sub-classes and lower level classes, but not by any other class. As Inheritance is single root and unidirectional, protected members of a class are not visible to its parent class (if any), only to its child classes and lower level classes.

Let's take the Exercise and Quiz Java files as Example here: //File: Exercise.java is in the TopLevel.users.agenda package.

package TopLevel.users.agenda;
public class Exercise // need 'public' for accessibility from mother package
{ protected int year; }


//File: Quiz.java is in the TopLevel.users.schedule package.

package TopLevel.users.schedule;
import TopLevel.users.agenda.Exercise; // Exercise class needs to be imported.
public class Quiz extends Exercise // need 'public' for accessibility from other package
{ public void test() // need 'public' for accessibility from other package
{ year = 22; // 'year' is inherited from Exercise }
}



The 'private' visibility modifier

The strictest visibility modifier is 'private'. When used on any member that member can only be accessed by its own class. Only members can be made private. Classes are not made private in JAVA (with the exception of Inner Classes which is outside the scope of this Mini course).

It is so restrictive that even in an Inheritance situation, a child class would not be able to access a member of its super-class if that member is 'private'. To convey Inheritance, the super class members would be public, package, or protected (as the case may be), but not private.

Let's take the same example used for the protected visibility above, and have both classes Exercise and Quiz, both in the same package, but the 'int year' member is made 'private'. Code will not compile, as we try to access a private member. public class Exercise
{ private int year; }

public class Quiz extends Exercise
{ void test()
{ year = 22; // this will not compile. }
}


Click here to go to the JAVA Mini-Course page



The BASE for JAVA LEARNING

by PRO FE S S OR


SECTION XI - PACKAGES and VISIBILITY MODIFIERS

Steps 47: INFORMATION HIDING and WHY?


INFORMATION HIDING and WHY?

Click on INFORMATION HIDING and read about one very important feature of Object-Oriented Programming.

In Object Oriented Programming the norm is to have attributes and methods hidden or not accessible outside the class where they are defined.

INFORMATION HIDING together with ENCAPSULATION are characteristics that make Object-Oriented programs easy to maintain, and very reliable.

Even though the norm in Object-Oriented programming is to have members of a class hidden to other classes, sometimes it is necessary or convenient to have several methods accessible to other classes. That way Objects can communicate their behaviors to other Objects.

The Constructor for instance is made public, or package as the case may be, but seldomly is made private, as we may want to be able to create Objects of a class, from other classes. Of course, there may be a class whose Object can only be created from within its class, and in that particular case, its Constructor can be private. (rarely implemented.)

In Object Oriented Programming, most variables are aimed towards privatization. Not all methods however, are made private. There are some methods that are used by Objects of other classes and need not to be private. In next Step we will be discussing ACCESSORS and MUTATORS. These are methods that must not be private because they are used by Objects of another class. An accessor is used to query an attribute of its class, and a mutator is used to modify an attribute of its class. (See next Step.)



Why INFORMATION HIDING ?

If you have an Object that encapsulates and hides its members, that Object is more difficult to tamper with, and it's de-coupled from other Objects in your program. When a change is made to one class within your program it does not affect any other class, if de-coupling is accomplished.

The principle of having private attributes is based on the fact that there is no need to know their values, as these attributes are processed only within their own classes. Other classes will not be able to tamper with these attributes. As a restul, SECURITY is accomplished. Also, the programmer has an insurance that Objects of his or her class can be easily de-coupled.


Click here to go to the JAVA Mini-Course page



The BASE for JAVA LEARNING

by PRO FE S S OR


SECTION XI - PACKAGES and VISIBILITY MODIFIERS

Steps 48: ACCESSORS and MUTATORS


ACCESSORS and MUTATORS


ACCESSORS

As the name implies, an Accessor is a method that is utilized by an Object of another class to query an attribute of its class.

Any Accessor is made public or package as the case may be, for assurance that it can be utilized by Objects of another class. It should never be made private. In an Inheritance case, it may be made 'protected' if it's desirable that only child classes can access the super-class variable.

Usually or by convention an Accessor would begin with the word "get" for easy identification in the code, and then followed by the attribute that acts upon. Examples: getName(), getNumber(), getYear()

Example of an Accessor in the class Exercise: class Exercise
{ private int year; // private variable

public int getYear(); // Accessor used to query the variable 'year'.
{ return year; // 'year' is the variable being queried by an outside Object }
}
You may wonder why would we need an Accessor, because if we declare a variable 'public' it would not be necessary to have an Accessor for that variable.

The thing of the matter is that an Accessor (as well as a Mutator) is within the class where the attribute is defined, and therefore the code is under the class control. What that means, is that you as programmer have the prerrogative of restricting the access of that variable. You may want to have an Accessor that would return the variable value, ONLY and ONLY when some condition is met. That is totally under your control, and therefore you can change the restriction as you see it fit.

For example, let's say that there is an Accessor used for retrieving the variable 'fullName', say 'getFullName(). Well, you can make that Accessor with a restriction that only returns the 'fullName' value when and only when none of the components of that variable is null. Otherwise it would return an error message.

Or in another case, you may want to have an Accessor that requires the passing of an ID as an arugment, by the Object of another class, and based on that ID, the Accessor would or would not return the value. Or even in another case you may want to return an encrypted value of that variable.

See Example below, Accessor name: getFullName() class Exercise
{ private StringBuffer fullName; // private variable
private StringBuffer firstName; // private component of 'fullName' variable
private StringBuffer lastName; // private component of 'fullName' variable

public StringBuffer getFullName() // accessor for variable 'fullName'.
{ if (firstName==null || lastName==null) fullName = new StringBuffer("Not Valid"); else fullName = new StringBuffer(firstName.toString() + lastName.toString());
return fullName; // 'fullName' is the variable queried by an outside Object
}
}
See another Example, Accessor name: getNumber(String argument) class Exercise
{ private int number; // private variable

public int getNumber(String tmpID) // accessor for variable 'number'.
{ if (tmpID.charAt(0)!='G') // check the 1st character of the passed String argument. number = 9999; // '9999' is error code
return number ; // a valid number is returned if ID contains 'G' as the 1st character. // Otherwise the error code '9999' would be returned.
}
}


MUTATORS

As the name implies, a Mutator is a method that is utilized by an Object of another class to modify an attribute of its class.

Any Mutator is made public or package as the case may be, for assurance that it can be utilized by Objects of another class. It should never be made private. In an Inheritance case, it may be made 'protected' if it's desirable that only child classes can modify the super-class variable.

Usually or by convention a Mutator would begin with the word "set" for easy identification in the code, and then followed by the attribute that acts upon. Examples: setName(...), setNumber(...), setYear(...)

Example of a Mutator in the class Exercise: class Exercise
{ private int year; // private variable

public void getYear(int tmpYear); // Mutator used to modify the variable 'year'.
{ year = tmpYear; // 'year' is the variable being modified by an outside Object }
}
You may wonder why would we need a Mutator, because if we declare a variable 'public' it would not be necessary to have a Mutator for that variable.

The thing of the matter is that a Mutator (as well as an Accessor) is within the class where the attribute is defined, and therefore the code is under the class control. What that means, is that you as programmer have the prerrogative of restricting the variable modification. You may want to have a Mutator that would modify the variable value, ONLY and ONLY when some condition is met. That is totally under your control, and therefore you can change the restriction as you see it fit.

For example, let's say that there is a Mutator used for modifying a variable 'number', say 'setNumber(int tmpNumber). The argument passed in the method is the new value to which 'number' will be set.

Well, you can make that Mutator so that it would modify the 'number' value when and only when the submitted value (argument passed) is within a particular range. Otherwise it would not modify it.

Or in another case, you may want to have a Mutator that requires the passing of an ID as an arugment, by the Object of another class, and based on that ID, the Mutator would or would not modify the value.

See Example below, Mutator name: setNumber(int tmpNumber) class Exercise
{ private int number; // private variable

public void setNumber(int tmpNumber) // Mutator for 'number'.
{ if (number < 1000 && number > 399) // Checking if within range
{
number = tmpNumber;
System.out.println("Variable number modified as requested.");
}
else System.out.println("Variable number outside range.");
}
}



Click here to go to the JAVA Mini-Course page