Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Easy Learn Java: Programming Articles, Examples and Tips - Page 488


Previous 1060 Stories (530 Pages, 2 Per Page) Next

Easy Java Lecture 13: Inheritance in Java. Part II. Teach/learn online

Go to all tips in Java Lectures by Anatoliy Malyarenko

Writing final classes and methods

You can declare that your class is final, that is, that your class cannot be subclassed. There are (at least) two reasons why you might want to do this: to increase system security by preventing system subversion, and for reasons of good object-oriented design.

One mechanism that hackers use to subvert systems is to create a subclass of a class and then substitute their class for the original. The subclass looks and feels like the original class but does vastly different things, possibly causing damage or getting into private information.

To prevent this kind of subversion, you can declare your class to be final and thereby prevent any subclasses from being created. The String class in the java.lang package is a final class for just this reason. This class is so vital to the operation of the compiler and the interpreter that the Java system must guarantee that whenever a method or object uses a String it gets exactly a java.lang.String and not some other string. This ensures that all strings have no strange, inconsistent, undesirable, or unpredictable properties.

If you try to compile a subclass of a final class, the compiler prints an error message and refuses to compile your program. In addition, the bytecode verifier ensures that the subversion is not taking place at the bytecode level. It does this by checking to make sure that a class is not a subclass of a final class.


You may also wish to declare a class as final for object-oriented design reasons. You may think that your class is "perfect" or that, conceptually, your class should have no subclasses.

To specify that your class is final, use the keyword final before the class keyword in your class declaration.

For example, if you wanted to declare your (perfect) ChessAlgorithm class as final, its declaration should look like this:

Code:

final class ChessAlgorithm {
  . . .
}

Final methods

Does creating a final class seem heavy-handed for your needs? Do you really just want to protect some of your class's methods from being overridden? You can use the final keyword in a method declaration to indicate to the compiler that the method cannot be overridden by subclasses. As just shown, the Object class does this; some of its methods are final and some are not.

You might wish to make a method final if it has an implementation that should not be changed and it is critical to the consistent state of the object. For example, instead of making your ChessAlgorithm class final, you might want instead to make the nextMove method final:

Code:

class ChessAlgorithm {
   . . .
   final void nextMove(ChessPiece pieceMoved,
      BoardLocation newLocation) {
         ...
   }
   . . .
}

Writing abstract classes and methods

Sometimes, a class that you define represents an abstract concept and, as such, should not be instantiated. Take, for example, food in the real world. Have you ever seen an instance of food? No. What you see instead are instances of carrot, apple, and (our favourite) chocolate.

Food represents the abstract concept of things that we all can eat. It doesn't make sense for an instance of food to exist.

Similarly in object-oriented programming, you may want to model an abstract concept without being able to create an instance of it. For example, the Number class in the java.lang package represents the abstract concept of numbers. It makes sense to model numbers in a program, but it doesn't make sense to create a generic number object.

Instead, the Number class makes sense only as a superclass to classes like Integer and Float, both of which implement specific kinds of numbers. A class such as Number, which represents an abstract concept and should not be instantiated, is called an abstract class. An abstract class is a class that can only be subclassed -- it cannot be instantiated.

To declare that your class is an abstract class, use the keyword abstract before the class keyword in your class declaration:

Code:

abstract class Number {
    . . .
  }

If you attempt to instantiate an abstract class, the compiler displays an error similar to the following and refuses to compile your program:

AbstractTest.java:6: class AbstractTest is an
abstract class. It can't be instantiated.
new AbstractTest();
^
1 error

Abstract methods

An abstract class may contain abstract methods, that is, methods with no implementation. In this way, an abstract class can define a complete programming interface, thereby providing its subclasses with the method declarations for all of the methods necessary to implement that programming interface. However, the abstract class can leave some or all of the implementation details of those methods up to its subclasses.

Let's look at an example of when you might want to create an abstract class with an abstract method in it. In an object-oriented drawing application, you can draw circles, rectangles, lines, Bezier curves, and so on. Each of these graphic objects share certain states (position, bounding box) and behaviour (move, resize, draw). You can take advantage of these similarities and declare them all to inherit from the same parent object -- GraphicObject.

However, the graphic objects are also substantially different in many ways: drawing a circle is quite different from drawing a rectangle. The graphics objects cannot share these types of states or behaviour. On the other hand, all GraphicObjects must know how to draw themselves; they just differ in how they are drawn. This is a perfect situation for an abstract superclass.

First you would declare an abstract class, GraphicObject, to provide member variables and methods that were wholly shared by all subclasses, such as the current position and the moveTo method. GraphicObject also declares abstract methods for methods, such as draw, that need to be implemented by all subclasses, but are implemented in entirely different ways (no default implementation in the superclass makes sense). The GraphicObject class would look something like this:

Code:

abstract class GraphicObject {
   int x, y;
   . . .
   void moveTo(int newX, int newY) {
      . . .
   }
   abstract void draw();
}

Each non-abstract subclass of GraphicObject, such as Circle and Rectangle, would have to provide an implementation for the draw method:

Code:

class Circle extends GraphicObject {
    void draw() {
        . . .
    }
  }
class Rectangle extends GraphicObject {
    void draw() {
        . . .
    }
}

An abstract class is not required to have an abstract method in it. But any class that has an abstract method in it or that does not provide an implementation for any abstract methods declared in its superclasses must be declared as an abstract class.

Implementing nested classes

Java lets you define a class as a member of another class. Such a class is called a nested class and is illustrated here:

Code:

class EnclosingClass {
    . . .
    class ANestedClass {
        . . .
   
   
    }
}

Definition 2. A nested class is a class that is a member of another class.

You use nested classes to reflect and enforce the relationship between two classes.
You should define a class within another class when the nested class makes sense only in the context of its enclosing class or when it relies on the enclosing class for its function. For example, a text cursor makes sense only in the context of a particular text component.

As a member of its enclosing class, a nested class has a special privilege: It has unlimited access to its enclosing class's members, even if they are declared private. However, this special privilege isn't really special at all. It is fully consistent with the meaning of private and the other access specifiers. The access specifiers restrict access to members for classes outside of the enclosing class. The nested class is inside of its enclosing class so that it has access to its enclosing class's members.

Like other members, a nested class can be declared static (or not). A static nested class is called just that: a static nested class. A non-static nested class is called an inner class.

These are illustrated in the following code:

Code:

class EnclosingClass {
    . . .
    static class AStaticNestedClass {
        . . .
    }
    class InnerClass {
        . . .
    }
}

As with static methods and variables (normally called class methods and variables), a static nested class is associated with its enclosing class. And like class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class-it can use them only through an object reference.

As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's instance variables and methods. Also, because an inner class is associated with an instance, it cannot define any static members itself.

To help differentiate the terms nested class and inner class further, we suggest you think about them in the following way. The term "nested class" reflects the syntactic relationship between two classes; that is, syntactically, the code for one class appears within the code of another. In contrast, the term "inner class" reflects the relationship between instances of the two classes. Consider the following classes:

Code:

class EnclosingClass {
    . . .
    class InnerClass {
        . . .
    }
}

The interesting feature about the relationship between these two classes is not that InnerClass is syntactically defined within EnclosingClass. Rather, it's that an instance of InnerClass can exist only within an instance of EnclosingClass and that it has direct access to instance variables and methods of its enclosing instance. The following diagram illustrates this idea.


You may encounter nested classes of both kinds in the Java API and be required to use them. However, most nested classes that you write will be inner classes.

Definition 3. An inner class is a nested class whose instance exists within an instance of its enclosing class and has direct access to the instance members of its enclosing instance.

Other facts about nested classes

Like other classes, nested classes can be declared abstract or final. The meaning of these two modifiers for nested classes is the same as for other classes. Also, the access specifiers -- private, public, protected, and package -- may be used to restrict access to nested classes just as they do to other class members.

Any nested class, not just anonymous ones, can be declared in any block of code. A nested class declared within a method or other smaller block of code has access to any final, local variables in scope.

Inner classes

To help you get a handle on inner classes and what they are good for, let's revisit the Stack class. Suppose you want to add a feature to this class that lets another class enumerate over the elements in the stack using the interface defined in java.util.Enumeration. This interface contains two method declarations:

Code:

public boolean hasMoreElements();
public Object nextElement();

The Enumeration interface defines the interface for a single loop over the elements:

Code:

while (hasMoreElements())
nextElement()

If Stack implemented the Enumeration interface itself, you could not restart the loop and you could not enumerate the contents more than once. Also, you couldn't allow two enumerations to happen simultaneously. So Stack shouldn't implement Enumeration. Rather, a helper class should do the work for Stack.

The helper class must have access to the Stack's elements. It also must be able to access them directly because the Stack's public interface supports only LIFO access. This is where inner classes come in.

Here's an implementation of Stack that defines a helper class (called an adapter class) for enumerating over its elements:

Code:

public class Stack {
   private Vector items;
   //code for Stack's methods and constructors not shown...
   public Enumeration enumerator() {
      return new StackEnum();
   }
   
   class StackEnum implements Enumeration {
      int currentItem = items.size() - 1;
      public boolean hasMoreElements() {
         return (currentItem >= 0);
      }
      public Object nextElement() {
         if (!hasMoreElements())
            throw new NoSuchElementException();
         else
         return items.elementAt(currentItem--);
      }
   }
}

Note that the StackEnum class refers directly to Stack's items instance variable.

Inner classes are used primarily to implement adapter classes like the one shown in this example. If you plan on handling events from the AWT, then you'll want to know about using adapter classes because the event-handling mechanism in the AWT makes extensive use of them.

Anonymous classes

You can declare an inner class without naming it. Here's yet another version of the now-tired Stack class, in this case using an anonymous class for its enumerator:

Code:

public class Stack {
   private Vector items;
   //code for Stack's methods and constructors not shown...

   public Enumeration enumerator() {
      return new Enumeration() {
         int currentItem = items.size() - 1;
         public boolean hasMoreElements() {
         return (currentItem >= 0);
      }
      public Object nextElement() {
         if (!hasMoreElements())
            throw new NoSuchElementException();
         else
            return items.elementAt(currentItem--);
         }
      }
   }
}

Anonymous classes can make code difficult to read. You should limit their use to those classes that are very small (no more than a method or two) and whose use is well-understood (like the AWT event-handling adapter classes).

Problem for pass with distinction. Implement the complex number class. At a minimum it should have a constructor, a toString() method, and methods to add, subtract, and multiply two complex numbers, and to return the real and imaginary parts.


14548 bytes more | comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by jalex on Wednesday, November 29, 2006 (01:00:00) (5890 reads)

Funny dedication I found on the Net :-)

Go to all tips in Entertaining

Although my finding is not about Java I could leave it unpublished.. I have share it with you!

Dedication

"This HOWTO is dedicated to Anne Line Norheim Langfeldt. Though she will probably never read it since she's not that kind of girl."

Smile Smile Smile Smile Smile Smile Smile Smile Smile

from DNS-HOWTO (Linux)



comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by jalex on Sunday, November 26, 2006 (12:00:00) (4478 reads)

Previous 1060 Stories (530 Pages, 2 Per Page) Next

530| 529| 528| 527| 526| 525| 524| 523| 522| 521| 520| 519| 518| 517| 516| 515| 514| 513| 512| 511| 510| 509| 508| 507| 506| 505| 504| 503| 502| 501| 500| 499| 498| 497| 496| 495| 494| 493| 492| 491| 490| 489|
488
| 487| 486| 485| 484| 483| 482| 481| 480| 479| 478| 477| 476| 475| 474| 473| 472| 471| 470| 469| 468| 467| 466| 465| 464| 463| 462| 461| 460| 459| 458| 457| 456| 455| 454| 453| 452| 451| 450| 449| 448| 447| 446| 445| 444| 443| 442| 441| 440| 439| 438| 437| 436| 435| 434| 433| 432| 431| 430| 429| 428| 427| 426| 425| 424| 423| 422| 421| 420| 419| 418| 417| 416| 415| 414| 413| 412| 411| 410| 409| 408| 407| 406| 405| 404| 403| 402| 401| 400| 399| 398| 397| 396| 395| 394| 393| 392| 391| 390| 389| 388| 387| 386| 385| 384| 383| 382| 381| 380| 379| 378| 377| 376| 375| 374| 373| 372| 371| 370| 369| 368| 367| 366| 365| 364| 363| 362| 361| 360| 359| 358| 357| 356| 355| 354| 353| 352| 351| 350| 349| 348| 347| 346| 345| 344| 343| 342| 341| 340| 339| 338| 337| 336| 335| 334| 333| 332| 331| 330| 329| 328| 327| 326| 325| 324| 323| 322| 321| 320| 319| 318| 317| 316| 315| 314| 313| 312| 311| 310| 309| 308| 307| 306| 305| 304| 303| 302| 301| 300| 299| 298| 297| 296| 295| 294| 293| 292| 291| 290| 289| 288| 287| 286| 285| 284| 283| 282| 281| 280| 279| 278| 277| 276| 275| 274| 273| 272| 271| 270| 269| 268| 267| 266| 265| 264| 263| 262| 261| 260| 259| 258| 257| 256| 255| 254| 253| 252| 251| 250| 249| 248| 247| 246| 245| 244| 243| 242| 241| 240| 239| 238| 237| 236| 235| 234| 233| 232| 231| 230| 229| 228| 227| 226| 225| 224| 223| 222| 221| 220| 219| 218| 217| 216| 215| 214| 213| 212| 211| 210| 209| 208| 207| 206| 205| 204| 203| 202| 201| 200| 199| 198| 197| 196| 195| 194| 193| 192| 191| 190| 189| 188| 187| 186| 185| 184| 183| 182| 181| 180| 179| 178| 177| 176| 175| 174| 173| 172| 171| 170| 169| 168| 167| 166| 165| 164| 163| 162| 161| 160| 159| 158| 157| 156| 155| 154| 153| 152| 151| 150| 149| 148| 147| 146| 145| 144| 143| 142| 141| 140| 139| 138| 137| 136| 135| 134| 133| 132| 131| 130| 129| 128| 127| 126| 125| 124| 123| 122| 121| 120| 119| 118| 117| 116| 115| 114| 113| 112| 111| 110| 109| 108| 107| 106| 105| 104| 103| 102| 101| 100| 99| 98| 97| 96| 95| 94| 93| 92| 91| 90| 89| 88| 87| 86| 85| 84| 83| 82| 81| 80| 79| 78| 77| 76| 75| 74| 73| 72| 71| 70| 69| 68| 67| 66| 65| 64| 63| 62| 61| 60| 59| 58| 57| 56| 55| 54| 53| 52| 51| 50| 49| 48| 47| 46| 45| 44| 43| 42| 41| 40| 39| 38| 37| 36| 35| 34| 33| 32| 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1|


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy