Java Keywords (Part II): Modifiers
package
will remain listed until properly explained and illustrated.
Java keyword list
abstract | continue | for | new | switch |
assert | default | goto* | package | synchronized |
boolean | do | if | private | this |
break | double | implements | protected | throw |
byte | else | import | public | throws |
case | enum | instanceof | return | transient |
catch | extends | int | short | try |
char | final | interface | static | void |
class | finally | long | strictfp | volatile |
const* | float | native | super | while |
Modifiers
Aside from the already discussed access modifiers, there are four other modifier keywords in Java. These are:abstract
, final
, static
, and strictfp
. I will not discuss the strict floating point behavior keyword (strictfp
) at this time.
Method declaration
abstract
is used in both the method declaration and the class declaration.
public class MyClass
{
public void myMethod()
{
// Does something
}
}
public void printHelloWorld() {...}
is the method declaration. The only required elements of a method declaration are the method's return type, name, a pair of parentheses, (), and a body between braces "{}". The image below illustrates this, but also including "public" access modifier.
This is the simplest form of a method declaration. There are other components that could be added to a method declaration that will be discussed in other sections or in other articles. For now, let us discuss the usage of the keyword abstract
.
abstract
public abstract class MyClass
{
public void myConcreteMethod()
{
// Does something
}
public abstract void myAbstractMethod(); // DO NOT forget semicolon at the end of an abstract method declaration!
}
The opposite of an "abstract" method is a "concrete" method. A concrete method is a method with body (an implemented method). One question remains, what good is a method without body? A method without a body cannot be used because it will not be able to do anything. Therefore, abstract methods must be defined by someone before they can be used. But before we get to that, notice how the class declaration in the example above also contain the keyword abstract
. This is a safeguard feature added by the Java language. When a class contains at least one abstract method, the class definition MUST contain the keyword abstract
. When a Java class contains the keyword abstract
, it is said to be an abstract class. Here are two basic rules for declaring a class "abstract":
- A class MUST be abstract if at least one method is abstract
- A class CAN be abstract even if no method is abstract
Confusing? Let me show you code examples for these rules...
// Valid: A class MUST be abstract if at least one method is abstract
public abstract class MyClass
{
public abstract void myAbstractMethod();
}
// Valid: A class CAN be abstract even if no method is abstract
public abstract class MyClass
{
public void myConcreteMethod()
{
// Does something
}
}
The benefits of abstract classes will be discussed in a future article. In order to fully grasp this concept, we must discuss the concepts of inheritance and class constructors. Since this article is strictly about modifier keywords, it doesn't make sense to dive in further into these topics. That said, keep in mind that there is a bit more to discuss regarding abstract methods and classes. For now, just now that an abstract class, just like an abstract method, cannot be used (constructed in the case of classes) until that abstraction is realized (made concrete) by someone else. I promise this will become very clear when inheritance is discussed.
final
- When used in a class declaration, it means that the class cannot be extended.
- When used in a method declaration, it means that the method cannot be overridden.
- When used in a variable declaration, it means that the variable is a constant. (constant variable?)
As already mentioned, the keyword final
when used in a data member declaration, it means that the data member is a constant. Java is a language that is strongly based in C++. Because of this, the keyword const
was reserved, but never implemented. At this point, there is almost a zero chance that it will ever be implemented in the Java language. The concept of const
in C++ goes beyond declaring a data member as constant. In Java, to declare a data member as "constant", we simply add the keyword final
to the declaration.
public class Student
{
private int grade; // variable
private final String studentId; // constant
// Methods omitted
}
Assuming that a student ID assigned to a student can never be changed, the class "Student" above should make perfect sense: I modeled a person with a variable for "grade" and a constant for "studentId". If you are a high school student, your student ID has not changed ever since you were admitted into your current school district; even from elementary school. If you are a college student, your student ID has been the same since you were admitted into your current university or college. The code example above have two data members declared, but no values have been assigned yet (other than default values which will be discusses later).
Assigning a value to a constant data member, must be done in one of two ways: at development time, or at execution time. Assigning a value at development time means assigning the value right at the point where the constant data member is declared. This is shown in the code below.
public class Student
{
private int grade; // variable
private final String studentId = "D12345678"; // constant
// Methods omitted
}
- Its name is the same as the class that contains it, and...
- Has no return type
public class Student
{
private int grade; // variable
private final String studentId; // constant
// class constructor
public Student()
{
studentId = "D12345678"; // value assigned and cannot be changed
}
// Methods omitted
}
There are many rules to class constructors. And those merit a dedicated article. For now know that every class MUST have at least one constructor. Therefore, if you do not define a constructor inside a class, the Java compiler will create one for you that is known as the "default constructor". This "default constructor" is similar to the constructor shown in the code above except the body of the method will be empty. The meaning of this will be explained later when discussing "Constructors".
So far, none of the examples shown are good. The reason being is that if this code was used to create many distinct students, each one will have the same student ID. In order to use constant data members effectively, we must inject the value we want to assign to our student object via the class constructor.
public class Student
{
private int grade; // variable
private final String studentId; // constant
// class constructor
public Student(String value)
{
studentId = value; // value assigned and cannot be changed
}
// Methods omitted
}
public class Registrar
{
public static void main(String[] args)
{
Student janeDoe = new Student("D12345678"); // Jane Doe has a permanent student ID
Student johnDoe = new Student("D98765432"); // John Doe has a permanent student ID
}
}
The new
operator invokes the object constructor. In this example, the "Student" class contains a single String argument. The call to the Student constructor must pass the same number of arguments, in the right order, of the correct type. This example passes a single "String" argument for each Student object created. But this is not the only thing that the "new" operator does. This will be discussed in detailed when discussing the topic of "Constructors".
static
public class MyClass
{
public int nonStaticVariable = 1;
public int staticVariable = 4;
public void myNonStaticMethod()
{
// Does something
}
public static void myStaticMethod()
{
// Does something
}
}
public class MyClassDemo
{
public static void main(String[] args)
{
MyClass.myStaticMethod(); // calling a static method
int x = MyClass.staticVariable; // using a static variable
MyClass object = new MyClass();
object.myNonStaticMethod(); // calling a non-static method
int y = object.nonStaticVariable; // using non-static variable
}
}
Because static members belong to the class itself, creating an instance of the class to access its accessible members is not necessary. To access static members simply use the class name followed by a period (.), followed by the static member name. To access non-static members, an object of that class must be created first. Then, using the created object, access the members by using object's name followed by a period (.), followed by the non-static member name (see code above).
When should I use static members?
Static members should be used when the member's value (or behavior in the case of method) shall remain the same across all instances AND in the case of variables, a change in value is desired to affect all object instances. Again, this is simple to understand by using a real-world example. I am going to model a "Car" using a class.
public class Car
{
private static String make = "Ford";
private static String make = "Fiesta";
private final String color;
public Car(String value)
{
color = value;
}
public void rebrand(String newValue)
{
make = newValue;
}
public void showBrand()
{
System.out.println(brand);
}
}
public class FordFiestaProductionLine
{
public static void main(String[] args)
{
Car myCar = new Car("white");
Car yourCar = new Car("red");
Car.rebrand("Mazda");
// myCar and yourCar are now "Mazda"
myCar.showBrand();
yourCar.showBrand();
}
}
As you can see, using static data members can be very convenient when a particular behavior is universal across all instances of a class or a particular attribute of a class is shared across all its object instances. In the example above, the production line for Ford Fiesta produces the same make, the same model, but with different colors. If Ford is acquired by Mazda, it will not make sense to rebrand all vehicles individually (even though in the real-world there is no way around it). In programming, it makes more sense to apply this change to the template (class) and all created instances will immediately adopt the change.
Summary
In this post, I discussed the modifier keywordsabstract
, final
, and static
. In the process, I had to introduce the concepts of method declaration, as well as declaration and invocation of a class constructor. Lastly, there is yet an additional use of the keyword static
that will be cover later. This is because in order to discuss this usage, I need to introduced other keywords. For simplicity, it is better to leave this usage out of this article for later discussion.
Next up, Part III: Returning Values from Methods
Comments
Post a Comment