You are on page 1of 10

Chapter 7: Level-up, Advance Class Features.

(6 hrs) Chapter Objectives: Point out the use of the static keyword for variables, methods, inner classes and the static code block. Point out the use of the final keyword for variables, methods and classes including the rules on blank final variables Differentiate the use of version 5's new enum keyword versus the old way of doing it. Point out the use of the static import feature of version 5. Show the use of the abstract keyword for methods and classes while introducing the Template-Design Methodology. Show the importance of interfaces. The static keyword The static keyword can be used for attributes, methods and inner classes. Top level classes cannot be declared static. Once an attribute, method or an inner class is declared as static, it means the ownership of the instance will be owned by the class and not by any instance of any object. Consider the following example: 1 public class StaticExample1 2 { 3 public static int counter = 0; 4 private int serialNumber; 5 6 public StaticExample1() 7 { 8 counter++; 9 serialNumber = counter; 10 } 11 12 public static void main(String args[]) 13 { 14 System.out.println("Creating the first object: "); 15 StaticExample1 se1 = new StaticExample1(); 16 System.out.println("Creating the second object: "); 17 StaticExample1 se2 = new StaticExample1(); 18 19 System.out.println("A total of " + counter + " were created."); 20 } 21 } In line 3, we've declared the variable counter as static and in line 4, the serialNumber variable is non-static (also known as instance variables). This means that for every object instance of the class StaticExample1, there will exist an attribute serialNumber. In lines 15 and 17, we've created two instances of StaticExample1, therefore there are two copies of serialNumber one for each instance. But the static variable counter will always have a single copy because serialNumber is declared as static. A static variable will always have a single copy which will be owned by the class, unlike non-static variables (or instance variables) in which a copy will be given to each object that will be created (instantiated). We can access static variables by using the class' name instead of the instance. In line 19, we've accessed counter directly, but if you want to access the static attribute counter outside of the class, you need to access it this way:

Page 1 of 10

Prepared by: Lawrence G. Decamora III, scjp

public class SomeOtherClass { public void doSomething() { System.out.println(StaticExample1.counter); } } Static methods and static attributes have almost the same differences with instance variables and instance methods and even the way that they are being accessed. Consider the Math class and the System class. All attributes and methods of both classes are static, therefore every time you access an attribute or a method from those classes you access them using the class name because they are all static attributes and static methods. Check your java docs and examine the methods and attributes of the System and Math Classes. System.out.println(Math.PI); System.out.println(Math.max(20,30)); Static Imports Static imports are new for Java ver 5.0 and are used to import static members (attributes and methods) individually or collectively. Here's the syntax of static imports import static <pkg_list>.<class_name>.<member_name>; OR import static <pkg_list>.<class_name>.*; For example, we can rewrite the previous example this way. import static java.lang.Math.*; import static java.lang.System.out; out.println(PI); out.println(max(20,30)); The final keyword The final keyword can be used for attributes, methods and classes. Final classes cannot be subclassed. Final methods cannot be overridden and final attributes are constant values. Final attributes has two forms, the regular attribute declares a constant value. For example: public static final int SALES_VAT = 0.12; The SALES_VAT is not a variable, its a constant value. It's value cannot be changed during the life span or your application, any attempt to change it will cause a compilation error. Another use of the final keyword for attributes is for blank final variables.
Page 2 of 10 Prepared by: Lawrence G. Decamora III, scjp

Here's another example: 1 public class MyProduct 2 { 3 private final int productId; 4 5 public MyProduct() 6 { 7 productId = generateProductId(); 8 } 9 10 private int generateProductId() 11 { 12 // codes that will 13 // generate the product id. 14 } 15 } The enum keyword In the good old days, say J2SE 1.4 days, the concept of enumeration was already existing but Java has another way of handling it. public class public public public OldEnum { static final int YES = 0; static final int NO = 1; static final int MAYBE = 2;

public static void main(String args[]) { for (int i = 0; i < 3; i++) { switch(i) { case YES : System.out.println("Yes"); break; case NO : System.out.println("No"); break; case MAYBE : System.out.println("MayBe"); break; } } }

But starting Java version 5, an additional keyword is added that can handle enumerated values. public enum Answers YES, NO, MAYBE; } {

public class NewEnum { public static void main(String args[]) { for (Answers answer : Answers.values()) { switch(answer) { case YES : System.out.println("Yes"); break; case NO : System.out.println("No"); break;
Page 3 of 10 Prepared by: Lawrence G. Decamora III, scjp

} } }

case MAYBE : System.out.println("MayBe");

} In the old enumeration, there's no type safety checking, unlike in version 5, the limited number of enumerated answers are checked at compile time, thus eliminating the need for the default statement in your switch-case.. The abstract keyword The abstract keyword can only be used for classes and for methods. Abstract mean, no concrete implementation, therefore abstract methods does not have any body in it. Just the head. As a rule, if a class contains abstract methods, the class must be declared as abstract themselves. Therefore no object instantiation can be done in it. Animal

// abstract +eat() +breath() +sleep() // non-abstract +play()

Mammal

Bird

+eat() +breath() +sleep() +feedYoung()

+eat() +breath() +sleep() +layEggs() +buildNests()

Consider the given UML, the Animal class has abstract methods, therefore all subclasses of the Animal class MUST override all abstract methods of the superclass Animal. Here are the Java code equivalent of the give UML above. 1 // Animal.java 2 public abstract class Animal 3 { 4 // abstract methods 5 public abstract void eat();
Page 4 of 10 Prepared by: Lawrence G. Decamora III, scjp

6 7 8 9 10 11 12 13 14 }

public abstract void breath(); public abstract void sleep(); // non-abstract methods public void play() { System.out.println("Have fun."); }

Lines 5, 6, and 7 are abstract method declarations. They do not have any body in them and they end with a semicolon (;). The abstract class Animal is a template for all types of animal, which means if you will declare a class that is of type Animal (a subclass of class Animal), that class must override all abstract methods of class Animal or else that class will end up being an abstract class itself because it will inherit all abstract methods. Here's the class Mammal and class Bird. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // Mammal.java public class Mammal extends Animal { // override all abstract methods public void eat() { System.out.println("Mammal Eats"); } public void breath() { System.out.println("Mammal Breath"); } public void sleep() { System.out.println("Mammal Sleeps"); } // my own mammalic methods public void feedYoung() { System.out.println("Feed Young"); }

1 // Bird.java 2 public class Bird extends Animal 3 { 4 // override all abstract methods 5 public void eat() 6 { 7 System.out.println("Bird Eats"); 8 } 9 public void breath() 10 { 11 System.out.println("Bird Breath"); 12 } 13 public void sleep() 14 {
Page 5 of 10 Prepared by: Lawrence G. Decamora III, scjp

15 16 17 18 19 20 21 22 23 24 25 26 27 }

System.out.println("Bird Sleeps");

// my own birdly methods public void layEggs() { System.out.println("Lay Eggs"); } public void buildNest() { System.out.println("Build Nests"); }

The test class is here. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 // TestAnimal1.java public class TestAnimal1 { public static void main(String args[]) { // cannot instantiate an object // from an abstract class //! Animal a = new Animal(); Mammal dog = new Mammal(); Bird eagle = new Bird(); doAnimalStuff(dog); doAnimalStuff(eagle);

} public static void doAnimalStuff(Animal a) { if (a instanceof Mammal) { Mammal m = (Mammal)a; m.eat(); m.breath(); m.sleep(); m.play(); m.feedYoung(); } else if (a instanceof Bird) { Bird b = (Bird) a; b.eat(); b.breath(); b.sleep(); b.play(); b.layEggs(); b.buildNest(); } } }

But this test class is not that well written, there are allot of redundancies. Lines 21 to 24 and lines 30 to 33 are redundant codes. Consider the other test class:
Page 6 of 10 Prepared by: Lawrence G. Decamora III, scjp

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

// TestAnimal2.java public class TestAnimal2 { public static void main(String args[]) { Mammal dog = new Mammal(); Bird eagle = new Bird(); doAnimalStuff(dog); doAnimalStuff(eagle); } public static void doAnimalStuff(Animal a) { a.eat(); a.breath(); a.sleep(); a.play(); if (a instanceof Mammal) { Mammal m = (Mammal)a; m.feedYoung(); } else if (a instanceof Bird) { Bird b = (Bird) a; b.layEggs(); b.buildNest(); }

} }

No more redundancies here. Java Interfaces. A public interface is a contract between the client code and the class that implements that interface. In Java, an interface can also be used to simulate multiple inheritance. Here's an example. GoFly
+takeOff() +land() +fly()

Airplane
+takeOff() +land() +fly()

Page 7 of 10

Prepared by: Lawrence G. Decamora III, scjp

The syntax for using an interface are as follows: <modifier> class <name> [extends <superclass>] [implements <interface> [,<interface>]* ] { <member_declaration>* } Go Fly Interface: GoFly.java 1 public interface GoFly 2 { 3 public void takeOff(); 4 public void land(); 5 public void fly(); 6 } Airplane class that implements GoFly: Airplane.java 1 public class Airplane implements GoFly 2 { 3 public void takeOff() 4 { 5 // increase speed 6 // lift landing gear 7 } 8 public void fly() 9 { 10 // keep those engines running 11 } 12 public void land() 13 { 14 // lower flaps 15 // reduce speed 16 } 17 } Here's another example:

Page 8 of 10

Prepared by: Lawrence G. Decamora III, scjp

Animal

GoFly

// abstract +eat() +breath() +sleep() // non-abstract +play()

+takeOff() +land() +fly()

Airplane

Mammal

Bird

+takeOff() +land() +fly()

+eat() +breath() +sleep() +feedYoung()

+eat() +breath() +sleep() +takeOff() +land() +fly() +layEggs() +buildNests()

So the Bird Class will now have this code: 1 // Bird.java 2 public class Bird extends Animal implements GoFly 3 { 4 // override all abstract methods 5 public void eat() 6 { 7 System.out.println("Bird Eats"); 8 } 9 public void breath() 10 { 11 System.out.println("Bird Breath"); 12 } 13 public void sleep() 14 { 15 System.out.println("Bird Sleeps"); 16 } 17 18 // my own birdly methods 19 public void layEggs() 20 { 21 System.out.println("Lay Eggs"); 22 }
Page 9 of 10 Prepared by: Lawrence G. Decamora III, scjp

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 }

public void buildNest() { System.out.println("Build Nests"); } // overriding all methods from GoFly interface public void takeOff() { // flap birdly wings } public void fly() { // flap...fly...soar } public void land() { // ready to land little birdy }

Page 10 of 10

Prepared by: Lawrence G. Decamora III, scjp

You might also like