User Tools

Site Tools


java_class

Java Class

An object is an instance of a class, it is something real that lives in the memory of the computer, that has some attributes which define its state, and some methods to modify its state.

Classes and objects are strictly related, the former defines how the object is made and how to interact with it. A class is defined in a file with the keyword class to which one may add some access modifiers. Normally the class name starts with a capital letter and goes on CamelCase.

The following class is named Matrix that must be saved in the file Matrix.java and that can be compiled with Java as

javac Matrix.java

The compiler will create a bytecompiled file Matrix.class and one may invoke it with

java Matrix

This class defines a number of variables and methods with particular accessibility modifiers. The class wants to represent a matrix. The main properties of a matrix are its size and the numbers in the matrix:

private int N=0, M=0;
private double[][] data;

So, we say we will reserve an area of memory for doubles. N and M will be the rows and the columns. This are the properties of the Matrix. We see that the access modifier is private this means that they are not shared with the external world.

There are a few methods that enable us to read/write data into the matrix and to get its size.

Finally there is a constructor or a particular method that is used when the object is created and put in memory. The constructor will create a Matrix(N,M) only with positive parameters, and doing so it will reserve the memory for the data array. The size of the Matrix is not mutable.

public class Matrix {
    private int N=0, M=0;
    private double[][] data;
    public Matrix(int n, int m){
        if (n > 0 && m > 0) {
            N = n;
            M = m;
	    data = (double[][]) Array.newInstance(double.class, n, m);			
	} else {
	    throw new IllegalArgumentException ("Error with dimensions: " + n + " , " + m);
	}
    }
    public int getRows() {return N;}
    public int getCols() {return M;}
 
    /**
    * data setter
    */
    public void set(int row, int col , double val){
        if ((row >= 0 && row < N) && (col >= 0 && col < M))
	    data[col][row] = val; //rows and cols are inverted otherwise
	}
    /**
    * data getter
    */
    public double get(int row, int col) throws IllegalArgumentException{
	if ((row >= 0 && row < N) && (col >= 0 && col < M))
		return data[col][row];
	else throw new IllegalArgumentException("Cannot access at position: " + posX + " , " +posY);
    }
}

This is a simple class and gives not much functionality to the matrix. In this particular implementation we have used only private and public access modifiers.

Access Modifiers

There are 4 access modifiers for classes and its properties/methods.

  • public
  • protected
  • package private
  • private

The access modifiers change the visibility of the properties. What visibility means can be understood with a simple analogy with real world.

Say you have an object. This object has a top, that exposes part of its content, but has a black box in which you cannot look inside. However, there are buttons and other gadgets to interact with.

private

private properties reside inside the black box and nobody directly access them. They can be variables or methods. For instance the private void selfDestruct() method cannot be accessed!

public

public properties can be seen and changed by everyone.

package-private and protected

The previous modifiers are the easiest to understand and explain. To understand package-private and protected we need to expand our analogy a little bit.

First of all, we must know that classes may be extended and can inherit from other classes. We say that a class is a subclass of another one, or that a class is a superclass of another.

Second, we need to say that Java software is organized in packages, and that classes in a certain package are clearly more related than classes residing in different packages. Therefore Java enforces a different policy about visibility of properties/methods from same or different packages.

Third, not only who accesses the properties, but also from where is influenced by access modifiers. Let's try to explain this better.

who

Let's make an analogy, just to start expaining this concepts. Interacting with an object we must wear a pair of glasses. Say that we have red glasses, so all the red buttons on the objects will not be visible to us. On the contrary someone without glasses will see also the red buttons and will be able to operate them.

In this analogy, public methods will be green, therefore visible to everybody with or without glasses, private won't be visible to anyone, and protected will be red, therefore their visibility will be dependent on the fact that who interacts with it has glasses or not. It is a little bit more complicated than that but it gives the idea.

In Java, who refers to pieces of Java code and their relation with the other Java code they want to use.

Let's create a SuperClass a class that extends it, SubClass, and a class that has nothing to do with them, except being in the same package PackageClass. In the SuperClass we define 4 member variables and mark them with different access modifiers. We demonstrate what happens with the use of the access modifiers:

SubClass.java
class SuperClass {
    public static String whichclass = "Super"; // class variable
    // the following are instance variables
    private String privates = "private"; 
    String ps = "package-private/default";
    protected String protecteds = "protected";
    public String publics = "public";
 
    public static void main(String[] args){
        SuperClass sc = new SuperClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SuperClass.whichclass);
        System.out.println(sc.privates);
        System.out.println(sc.ps);
        System.out.println(sc.protecteds);
        System.out.println(sc.publics);
    }
 
}
 
public class SubClass extends SuperClass {
    public static String whichclass = "SubClass";
    private String privates = "*******************private subclass";
    public static void main(String[] args){
        SuperClass sc = new SuperClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SuperClass.whichclass); 
        //error: whichclass has private access in SuperClass
 
        //System.out.println(sc.privates); 
        //error: privates has private access in SuperClass
 
        System.out.println(sc.ps);
        System.out.println(sc.protecteds);
        System.out.println(sc.publics);
 
        SubClass sub = new SubClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SubClass.whichclass);
        System.out.println(sub.privates);
        System.out.println(sub.ps);
        System.out.println(sub.protecteds);
        System.out.println(sub.publics);
    }
}
 
class PackageClass {
    public static String whichclass = "PackageClass";
    public static void main(String[] args){
        SuperClass sc = new SuperClass();
        System.out.println("Invoking from " + whichclass + " on an instance of " + SuperClass.whichclass); 
        //error: whichclass has private access in SuperClass
 
        //System.out.println(sc.privates); 
        //error: privates has private access in SuperClass
 
        System.out.println(sc.ps);
        System.out.println(sc.protecteds);
        System.out.println(sc.publics);
    }
}

You can compile this code with

javac SubClass.java

and launch it with the 3 different classes java SuperClass , java SubClass, java PackageClass and the output is respectively

java SuperClass on an instance of Super
Invoking from Super
private
package-private/default
protected
public
Invoking from SubClass on an instance of Super
package-private/default
protected
public
Invoking from SubClass on an instance of SubClass
*******************private subclass
package-private/default
protected
public
Invoking from PackageClass on an instance of Super
package-private/default
protected
public

There is not much difference using the PackageClass or the SubClass in accessing the properties of the SuperClass because the classes are all in the same package. A major difference between the SubClass and the PackageClass is that the former inherits the variables from its superclass!

from where

So far we have experimented with files in the same package. Let's expand and use code in different packages. Let's reuse the code of before, putting it in the package package1 and let's create other code in package2.

In java, you differentiate code in packages by putting it in different subdirectories, so the following code will be residing in two subdirs (at the same level): ./package1 and ./package2. You will find the previous code with the package definition at the end of the page.

AnyClass.java
package package2;
import package1.*;
 
public class AnyClass {
    public static String whichclass = "AnyClass";
    public static void main(String[] args){
        SubClass sub = new SubClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SubClass.whichclass);
        //System.out.println(sub.privates);
        // error: privates has private access in SubClass
 
        //System.out.println(sub.ps);
        // error: ps is not public in SuperClass; cannot be accessed from outside package
 
        // System.out.println(sub.protecteds);
        // error: protecteds has protected access in SuperClass
 
        // the only visible variable in Superclass from outside the package and 
        // in a not inherited class is the public variable
        System.out.println(sub.publics);
 
    }
}
 
class AnySubClass extends SubClass { 
    public static String whichclass = "AnySubClass";
    public static void main(String[] args){
 
        SubClass sub = new SubClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SubClass.whichclass);
 
        //System.out.println(sub.privates);
        // privates has private access in SubClass
 
        //System.out.println(sub.ps);
        //error: ps is not public in SuperClass; cannot be accessed from outside package
 
        //System.out.println(sub.protecteds);
        // error: protecteds has protected access in SuperClass
 
        System.out.println(sub.publics);
 
        AnySubClass asub = new AnySubClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + AnySubClass.whichclass);
        //System.out.println(asub.privates);
        // error: privates has private access in SubClass
 
        //System.out.println(asub.ps);
        // error: ps is not public in SuperClass; cannot be accessed from outside package
 
        System.out.println(asub.protecteds);
        System.out.println(asub.publics);
 
    }
 
}
 
class AnySubClass2 extends SubClass { 
    public static String whichclass = "AnySubClass2";
}

To compile issue

javac package1/SubClass.java package2/AnyClass.java

and one can run with java package2.AnyClass and java package2.AnySubClass

Things get more interesting now. As you can see from the output of the code, AnyClass has access only to public members, while AnySubClass has access to any protected and public variables.

The output is

Invoking from AnySubClass on an instance of SubClass
public
Invoking from AnySubClass on an instance of AnySubClass
protected
public
Invoking from AnyClass on an instance of SubClass
public

To add a bit of confusion, the subclass AnySubClass2 extends SubClass but in practice it is the same thing, as only the static variable whichclass is defined (hidden).

java package2.AnySubClass2

has the following output

Invoking from SubClass on an instance of Super
package-private/default
protected
public
Invoking from SubClass on an instance of SubClass
*******************private subclass
package-private/default
protected
public

WHAT???? This has to do with the cumbersome subject of method hiding that happens with static methods, as main in this case.

Static methods/variables are a unique property of the class and can live without an instance of it. Because of this, with static methods the actual code to be run is decided at compile-time and only the type decides the code to be run.

In a case like this one, in AnySubClass2 we inherited the static method main, and because it is defined in the type SubClass, Java uses the implementation of the method in the SubClass (together with the variables in there, that are the only known variables to the method in SubClass). In practice Java is protecting your code!

SubClass.java
package package1;
 
class SuperClass {
    public static String whichclass = "Super"; // class variable
    // the following are instance variables
    private String privates = "private"; 
    String ps = "package-private/default";
    protected String protecteds = "protected";
    public String publics = "public";
 
    public static void main(String[] args){
        SuperClass sc = new SuperClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SuperClass.whichclass);
        System.out.println(sc.privates);
        System.out.println(sc.ps);
        System.out.println(sc.protecteds);
        System.out.println(sc.publics);
    }
 
}
 
public class SubClass extends SuperClass {
    public static String whichclass = "SubClass";
    private String privates = "*******************private subclass";
    public static void main(String[] args){
        SuperClass sc = new SuperClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SuperClass.whichclass); 
        //error: whichclass has private access in SuperClass
 
        //System.out.println(sc.privates); 
        //error: privates has private access in SuperClass
 
        System.out.println(sc.ps);
        System.out.println(sc.protecteds);
        System.out.println(sc.publics);
 
        SubClass sub = new SubClass();
        System.out.println("Invoking from " + whichclass+ " on an instance of " + SubClass.whichclass);
        System.out.println(sub.privates);
        System.out.println(sub.ps);
        System.out.println(sub.protecteds);
        System.out.println(sub.publics);
    }
}
 
class PackageClass {
    public static String whichclass = "PackageClass";
    public static void main(String[] args){
        SuperClass sc = new SuperClass();
        System.out.println("Invoking from " + whichclass + " on an instance of " + SuperClass.whichclass); 
        //error: whichclass has private access in SuperClass
 
        //System.out.println(sc.privates); 
        //error: privates has private access in SuperClass
 
        System.out.println(sc.ps);
        System.out.println(sc.protecteds);
        System.out.println(sc.publics);
    }
}
java_class.txt · Last modified: 2016/09/09 16:01 by 178.237.8.52