Monday, November 9, 2009

SCJP 1.6 Study Guide: Declarations and Access Controls Part 6

Declaring Class Members and Access Modifiers

By this time I hope you have grasped all the required concepts in declaring and modifying classes. If not go back and I suggest you try coding at the same time. Those concepts are necessary before reading the next posts regarding declaring class members.

Class Members. When we mention class members we are talking about instance variables, static variables, instance methods and static variables.

Both instance and static variables are variables declared inside a class but outside any methods. The most obvious difference that you will see between instance and static variables is that static variables are variables declared with the static keyword, which is the same with instance and static methods.

Example:
public class Student{
public int yearLevel; // instance variable
public static int noOfStudents; // static variable

public void doHomework(){} // instance method
public static void getNoOfStudents(){} // static variables
}
We'll go deeper with static variables and methods in later posts.

Access Modifiers. As we've discussed in an earlier post, Java has four access control levels (public, private, protected and default access), but only three modifiers (public, private and protected). You get the default access when you don't specify any access modifier.

Unlike classes where you can only have two access control levels (public and default), you can have all four with class members.

The following are the things you should remember when a class (class A) has access to members of another class (class B):
  • A method in class A has access to class members of class B.
    package bobhub;
    public class B{
    public int x;

    public void doBThings(){}
    }
    package scjp;
    import bobhub.B;
    public class A{
    public void doAThings{
    B b = new B();
    b.x = 2; // doBThings has access to x from a reference of class B
    b.doBThings(); // doBThings can invoke doAThings() from a reference of class B
    }
    }
  • What class members are inherited by class A when it extends class B.
    package bobhub;
    public class B{
    public int x;

    public void doAThings(){}
    }
    package scjp;
    import bobhub.B;
    public class A extends B{
    public void doAThings{
    doBThings(); // since A extends B and it inherits doBThings()
    // it can invoke doBThings() as if it is declared in
    // class A. Sometimes you can use the this reference
    // for clarity. e.g. this.doBThings();
    x = 24; // A also inherits x from B
    }
    }
Now that we have access modifiers for classes and for its members we must consider combination of access modifiers. Of course, you need to take a look at the class first, if class B is not visible to class A then all the members of class B is not visible to class A. When class B is visible to class A that's the time you need to take a look at the visibility of each member of class B. For the next post let's assume that all classes are visible unless stated in the examples.

Public Members. A class member is considered a public member when it is declared with the public keyword (e.g. public String name; public void doSomething();).

A public member is accessible to all other classes regardless of package(See example). Public members are inherited by subclasses of its class(See example).

Private Members. Declaring class members with the private keyword makes them inaccessible to any class except to the class where it was declared.

Example:
package bobhub;
public class B{
private int x;

private void doBThings(){}
}
package scjp;
import bobhub.B;
public class A extends B{
public void doAThings{
B b = new B();
b.x = 24; // compiler error

doBThings(); // compiler error
}
}
Class B above compiles just fine but we will run through an error in A when it tries to access x(b.x = 24;), since x is declared with the private keyword B is the only class allowed to access x.

Another line which will result into a compiler error is when doAThings() method tries to invoke doBThings() method because subclasses do not inherit private members of its superclass. However, you can declare a method in A with the same signature as doBThings() method but it's not considered as overriding(We will discuss more on overriding on later posts). Try this in coding.

Default Members. When you don't explicitly provide an access modifier you get the default access. Default members may be accessed only by classes in the same package where you declared the members.

Example:
package bobhub;
public class B{
int x;

void doBThings(){}
}
package scjp;
import bobhub.B;
public class A extends B{
public void doAThings{
B b = new B();
b.x = 24; // compiler error

doBThings(); // compiler error
}
}
Accessing x in doAThings() method results in compiler error since x has default access and A is in a different package than B. Also invoking doBThings() thruough inheritance will result to compiler error because just like private members, a subclass does not inherit protected members of its superclass.

Protected Members. Members declared with the protected keyword behaves like default members most of the times except with inheritance. Protected members like default members are accessible only to classes within the same package AND also are visible through inheritance by subclasses even if they are on a different package.

Example:
package bobhub;
public class B{
protected int x;

protected void doBThings(){}
}
package scjp;
import bobhub.B;
public class A extends B{
public void doAThings{
B b = new B();
b.x = 24; // compiler error

doBThings(); // compiles
}
}
Accessing x in doAThings() method using a reference to an object B results in compiler error since x has protected access and A is in a different package than B. However, invoking doBThings() through inheritance will NOT result to compiler error since subclasses, even if they are in a different package, will inherit its superclass' protected members.

Local Variables and Access Modifiers. Local variables are variables usually inside a method. Local variables CANNOT be marked with access modifiers. And there is only one modifier you can use with local variables and that is the final keyword.

Below is a table from SCJP 1.6 Study Guide Book to summarize visibility of class members using access modifiers.







VisibilityPublicProtectedDefaultPrivate
Same classYesYesYesYes
Any class in the same packageYesYesNoYes
A subclass in the same packageYesYesYesNo
A subclass outside the same packageYesYesNoNo
A non-subclass outside the same packageYesYesNoNo


We will discuss class members and non-access modifiers in the next post.

0 comments:

Post a Comment