By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,550 Members | 1,393 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

A quick introduction to Java concepts 3

10K+
P: 13,264
Overriding therefore allows you to use the same method name to refer to differently implemented methods. Here is an example using the famous shapes example.

Expand|Select|Wrap|Line Numbers
  1.  
  2. class Shape { 
  3.       public Shape() {
  4.  
  5.        }
  6.        public double getArea() {
  7.              return 5.0;
  8.        }
  9. }
  10.  
  11. class Circle extends Shape {
  12.       double radius;
  13.       public Circle(int radius) {
  14.              this.radius = radius;
  15.        }
  16.       public double getArea() {
  17.              return Math.PI * radius * radius;
  18.       }
  19. }
  20.  
  21. class Rectangle extends Shape {
  22.       int length;
  23.        int width;
  24.       public Rectangle(int length, int width) {
  25.              this.length = length;
  26.              this.width = width;
  27.        }
  28.  
  29.       public double getArea() {
  30.               return length * width;
  31.        }
  32. }
  33.  
  34.  
Here the Rectangle and Circle classes both extend from Shape and override the useless public double getArea() method in the Shape class to provide more meaningful implementations unique to each of these classes.
Access modifiers for an overriding method can allow more, but not less, access than the overridden method. i.e., a protected instance method in the super class can be made public, but not private, in the subclass. Remember that private methods are not accessible in subclasses and therefore cannot be overridden. If you want to override a method but want to use the result calculated by the super class version of the method you are overriding, then simply call that super class method using the keyword super as follows:

Expand|Select|Wrap|Line Numbers
  1. public double getArea() {
  2.      return 5 + super.getArea();
  3. }
  4.  
Here the getArea() method is being overridden but the value calculated from the direct super class is being used to come up with the new version of the overriding method.
That is pretty much all there is about overriding!
Do not confuse overloading and overriding. Overloading occurs between methods in the same class with the same name but different signatures while overriding occurs between methods in different classes with one being the subclass of the other and the methods must have the same signature and return type or covariant return types.

If class A extends class B then variables of type B can hold references to objects of type A but not vice versa. That's the English version of it, the java code version of it is:

Expand|Select|Wrap|Line Numbers
  1.  
  2. class B{
  3. }
  4. class A extends B{
  5. }
  6. then
  7.  
Expand|Select|Wrap|Line Numbers
  1. B bVariable = new B(); //obviously allowed
  2. B bVariable = new A(); //also allowed
  3. A aVariable = new A();
  4. A aVariable = new B();//! incompatible types.
  5.  
  6.  
Hiding is not overriding

Hiding occurs when a static method in a class has the same signature and return type as one in that class' super class.

Expand|Select|Wrap|Line Numbers
  1.  
  2. class B{
  3.      public static void test() {
  4.             System.out.println("test from b");
  5.      }
  6. }
  7. class A extends B{
  8.        public static void test() {
  9.               System.out.println("test from a");
  10.        }
  11. }
  12. public class Test{
  13.        public static void main(String[] args) {
  14.              B b = new B();
  15.              B a = new A();
  16.              b.test();
  17.             a.test();
  18.       }
  19. }
  20.  
  21.  
Prints
Expand|Select|Wrap|Line Numbers
  1.  test from b
  2. test from b (this is not a typing error)
  3.  
The method test is static in B and so belongs to the class.
In the main method the two variables b and a share the same class, B, and so calling a class method on them calls the same method.
Expand|Select|Wrap|Line Numbers
  1. A a = new A();
  2. a.test();
  3.  
will print test from a because now the class type is A and inside A, the test method from B is now hidden (not overridden by the test in A).
The difference with instance methods becomes clear with

Expand|Select|Wrap|Line Numbers
  1.  
  2. class B{
  3.      public static void test() {
  4.            System.out.println("test from b");
  5.      }
  6.      void testInst() {
  7.            System.out.println("testInst from b");
  8.      }
  9. }
  10. class A extends B{
  11.         public static void test() {
  12.               System.out.println("test from a");
  13.         }
  14.         void testInst() {
  15.              System.out.println("testInst from a");
  16.         }
  17. }
  18. public class ShapeTest{
  19.            public static void main(String[] args) {
  20.                  B b = new B();
  21.                  B a = new A();
  22.                  b.test();
  23.                  a.test();
  24.                  b.testInst();
  25.                  a.testInst();
  26.         }
  27. }
  28.  
Use: In one sentence, use overriding to achieve more particular implementations of methods inherited from super classes.

abstract keyword

A class can be declared abstract meaning that no objects can be created using that class.

Expand|Select|Wrap|Line Numbers
  1.  abstract class A {
  2. }
  3. A a = new A();//!compile time error.
You may be beginning to think that an abstract class is quite useless. That's only until inheritance comes in. You can inherit from an abstract class allowing you to create a class that can be instantiated. The idea of making a class abstract is that you have a general group which objects belong to but instantiating an object of the general group really does not make sense since every object belongs to a more particular group. This is the case with the shapes example. The class Shape should be made abstract because a shape can be identified more precisely that just by calling it a shape. So
Expand|Select|Wrap|Line Numbers
  1. abstract class Shape {
  2. }
  3. class Circle extends Shape {
  4. }
  5.  
is more meaningful.

Methods can be declared abstract as well in which case you don't provide the method body but leave that to inheriting subclasses. In the shapes example you know that
all shapes have a getArea method but cannot write any code for it because the implementation is different for each shape so declare the getArea() method in the shape class
because that's where it belongs (all shapes have a getArea method) but you leave it abstract because you donít know how to write it yet.

Expand|Select|Wrap|Line Numbers
  1. abstract class Shape {
  2. public abstract double getArea();
  3. }
  4.  
Note that no {} are used. Just the signature and the ; at the end.
If a class contains an abstract method then that class is implicitly abstract and must the declared abstract otherwise the compiler will complain.
If a class inherits from an abstract class, then that class must provide implementations of all the abstract methods in the super class otherwise that inheriting class must also be declared abstract.
These things are not at all abstract and you should try them out on the compiler to see the effects.

Interfaces

An interface is a reference type whose members can be classes, other interfaces, constants and abstract methods.
They differ from classes in that they have no implementation. This is obvious since all their methods are abstract. Therefore all interfaces are abstract but you should not
put the public modifier. All interface members are implicitly public. Basically an interface is a contract that classes can choose to sign. Classes sign this contract by implementing the interface using the implements keyword.
Here are two example interfaces

Expand|Select|Wrap|Line Numbers
  1. interface Shape {
  2. double getArea();
  3. }
  4. interface Drawable {
  5. void draw();
  6. }
  7.  
These interfaces each contain one method. If any class implements the Shape interface then it must provide an implementation of the getArea() method otherwise that class must be declared abstract.
It is really as simple as that. Implement or else you're abstract, that's the rules of the contract. The interface is the boss. All this is checked at compile time.
Interfaces can declare constants as well which become available in implementing classes. A class can implement any number of interfaces. You can use this to achieve some level of multiple inheritance in Java by implementing multiple interfaces and thus being able to characterize an object into multiple groups. Here is an example. We want to be able to say that a Circle is a Drawable object and also that a Circle is a Shape.
Extending the Shape class says that a Circle is a shape. Extending the Drawable class says a Circle is a Drawable object. But we can only inherit from one class at a time so we make one of them an interface, implement it and
extend the other or we make both of them interfaces and implement them. The decision is ours, however, interfaces do not really provide any code reuse because they don't contain any implementations so it's wiser to choose a method that allow us the best in terms of code reuse. What interfaces provide is polymorphism. One interface, multiple implementations. By defining the Drawable interface, for example, we can implement it differently in all the classes that choose to implement this interface. If we had one method in some class draws shapes, we would simply need to pass an interface variable and call its draw method.

Expand|Select|Wrap|Line Numbers
  1.  
  2.  
  3. class Painter {
  4. void drawShape(Drawable d) {
  5. d.draw();
  6. }
  7. }
  8.  
  9.  
Now we can create classes that extend Shape and implement Drawable. In these classes since we have implemented Drawable, we then provide customized implementations of the draw method. If we wish to draw any shape, we pass it to the Painter's drawShape method which calls the draw method for that particular shape. When we change the draw method for the Circle class, the Painter is not affected, neither is any of the other shapes. This is one of the main goals of OOP. To be able to create a design which minimizes effects of changes in parts of the system. The classes in the Java packages make unforgiving use of these principles to define classes that can be used in varied circumstances by programmers.
Feb 5 '07 #1
Share this Article
Share on Google+