A limited form of multiple inheritance is achieved with interfaces,
   which is the next topic.
   Inheritance Example  
     public class NormedComplex
             extends Complex         // the inheritance 
     {
        private double norm;
        
         NormedComplex(double x, double y)
        {
           super(x,y);    // if this is not here, super() is assumed.
                          // if super() not defined, compiler error.
           norm = x*x-y*y;
        }
        NormedComplex()
        {
          this(0,0);     // No call to super() as "this" will call super.
        } 
       
        public void normalize()
        {
          setReal(getReal()/norm);            // getReal is inherited
          setComplex(getImaginary()/norm);
        }
       ....
      }
  
 Shadowing/Overriding 
 
  -   Super can be used to access data member and member functions of the
 superclass (the one which was extended). 
 
 -  In the subclass, one can use the same variable name or method name
   as in the superclass.
     This shadows  (hides) the inherited value. To get the inherited
     value use super.x. 
 
 -  One can also shadow methods, which is called overriding .
      Again to get the inherited method, use super.method(...).
  
 -  You cannot go up more than one level, by using super.super....
  
 -  You can prevent shadowing/overriding by declaring the member
   to be final. It is common to declare constants to be final.
  
 -  You cannot increase the accessibility in subclasses.
 
 
  Casting 
  
   -  Casting converts an instance of one type  to another type, via
      the prefix operator (type).
   
 -  Casting can be explicit or implicit.
   
 -  Examples of implicit casting:
      
         -   3+4.2    Here 3 is cast from integer to float.
         
 -   "sam"+3  Here 3 is cast from integer to String.
       
 
    -  Implicit casting is also called upcasting or widening,
       as the object gains additional fields, usually set to
     some default value.
    
 -   Explicit casting typical narrows or removes fields, which
    is called downcasting.
    This can be dangerous as information maybe lost. For example:
       
         int i = 1000;
         byte b = (byte) i;       
      
    If you are sure of the range of variable's value, casting may not
   hurt, as in:
      
          int i  = 4;
          byte b = (int)4;
        
       
     - 
     A typical use of casting occurs when retrieving elements
    from some container, such as a Vector. 
    
       Vector v = new Vector();
       v.addElement(Complex c = new Complex(3,4));   // c is upcast to object
       Complex c1 = v.getElementAt(0);   // This is an error, instead use
       Complex c1 = (Complex) v.getElementAt(0);  // downcasting
    
    Notice that in Java Vectors are unsafe as Vectors (and other containers)
   only hold Objects. Without undue cost, you can't enforce a Vector
   of a particular type. Here Java is not as strongly typed as C++ is,
which would accomplish the task via templates.
   
    
   Abstract Classes 
  
    -  An  abstract  method consists of the signature followed by 
      a semicolon, e.g.  double area();
    
 -  An abstract method is used to set up a promise or contract that
      every concrete subclass will implement the abstract method.
  
 -  A class is abstract 
      if it has at least one  method without an implementation or
       if it is declared abstract.
   
 -  A class that contains an abstract method must be declared
       abstract.
    
 -  You cannot instantiated (have an instance of) an abstract class.
     
 -  Subclasses of an abstract class may be abstract.
     
 -  Subclasses of a concrete class can be abstract.
     
 -  If a subclass overrides all the abstract methods, then it
       can be instantiated.
  
 
  Polymorphism Example 
  abstract class Shape  //  can't be instantiated
  {
    double  area();  // notice prototype
    double perimeter();
  }
  class Rectangle extends Shape 
   {                            
     double length, width;
     Rectangle(double length , double width)
      { 
        this.length = length;
        this.width = width;
      }
     double area()
    {
      return length*width;
    }
     double perimeter()
     {
      return 2*length + 2*width;
      }
    }
  class Square extends Rectangle 
     {
        square(double side)
       {
          super(side,side);
       }
     }
 class Circle extends Shape
   {
     double radius;
     circle(double radius)
     {
       this.radius = radius;
     }
    double area()
   {
     return Math.PI*radius*radius;
   }
   double perimeter()
  {
    return Math.PI*diameter(); // you don't worry about order of declaration
  }
  double diameter()
  {
    return 2*radius;
 }
 Polymorphism Example 2 
 Suppose we have graphical objects like buttons, scrollbars,
textfields, canvas, radio buttons and the like.
 Suppose each is derived from a superclass class component, which
 has a paint method.
 Suppose each graphical object overrides the paint method, saying
 how it should be drawn on display.
 
 Suppose we have a method update() which has a container for
all the objects on display and simple calls paint on each of them.
 
 Notice how easy it will be to add a new graphical object.
 
 This is how  Applet draw on the screen.
 
 What have we accomplished? 
 
 -  guaranteed that all implementation of shape have area function,
    otherwise compile-time error.
 
 -  allowed for uniform determination of area via polymorphism,
  e.g. we could have a vector of shapes which was a mixture of
  rectangles, squares, and circles and we could loop through them
  and determine each objects area. But remember we need to cast them
  to shape.
 
 
   Accessibility Rules  
 The boundaries of accessibility are determined by class, subclass
and package. If you write your code(classes) in one  directory, then the
classes are all part of the same anonymous package.
  
    -   Public  means accessible to anyone.
    
 -   Private  means accessible only to members of the class
   or to its inner classes.
    
 -   No designation  means package or friendly accessibility,
   ie. full visibility of methods and data to anyone in  the same package.
    
 -   Protected  means accessible to subclasses
    and to package members.
    
 -    Private Protected  means accessible only to subclasses.
    
 -  Note: when you subclass and override, you cannot increase the
         accessibility. This would lead to a compile error.