For some applications we might want a generic base class that we 
              will never instantiate. Instead we will only create instances of 
              subclasses of that base class that add specific attributes.
             
              In the following frequently used type of example, we create a 
                base class Shape 
                to provide a method to return the area of 2-D shapes represented 
                by various subclasses.
               
                
                   
                    | public 
                        class Shape { double 
                        getArea ()
 { return 0.0;}
 }
 public 
                        class Rectangle extends 
                        Shape { double ht = 0.0;
 double 
                        wd = 0.0;
 
 public double 
                        getArea ()
 { return (ht*wd);
 
 public void 
                        setHeight(double 
                        ht)
 { this.ht = ht; 
                        }
 
 public void 
                        setWidth (double 
                        wd)
 { this.wd = wd; 
                        }
 }
 
 public 
                        class Circle extends 
                        Shape {
 double 
                        r = 0.0;
 
 public double 
                        getArea ()
 { return (3.14 
                        * r * r); }
 
 public void 
                        setRadius (double 
                        r)
 { this.r = r; 
                        }
 }
 | 
                
                The subclasses Rectangle 
                  and Circle 
                  extend Shape 
                  and each overrides the getArea() 
                  method. We could define similar subclasses for other shapes 
                  as well. Each shape needs a unique area calculation so we do 
                  not include a default area calculation in the base class.
               
              The capability to reference instances of Rectangle 
                and Circle 
                as Shape 
                types brings the advantage of treating a set of different types 
                of shapes as one common type. For example, in the following code, 
                a Shape 
                array passed in the argument list contains references to different 
                types of subclass instances.  
                 
               
                
                   
                    | void 
                        double aMethod (Shape []  
                        shapes){  areaSum = 0.0;
 for (int 
                        i=0; i < shapes.length; i++)
 {
 areaSum += shapes.getArea();
 }
 }
 | 
                
                We calculate the sum of the areas of the array 
                  objects with a simple loop that calls the getArea() 
                  method for each instance. 
                This polymorphic 
                  aspect of OOP means that the subclass's overriding version of 
                  getArea() 
                  will execute, not that of the base class.
               
              Abstract Class
              By declaring a method and a class abstract, 
                we make it explicit that the user of our classes must override 
                the method and must never instantiate the Shape 
                class 
              In the above case, we can redefine our Shape 
                class and the getArea() 
                method as abstract as shown here:
              
                 
                  | abstract 
                      class Shape { abstract int 
                      getArea();
 }
 | 
              
              Note that if any method is declared abstract, the class must 
                be declared abstract as well or the compiler will give an error 
                message. 
              An abstract class can include concrete methods and fields. 
                In fact, an abstract class does not need to include any abstract 
                methods. The abstract modifier simply indicates that the class 
                cannot be instantiated. 
              Note that an abstract method has no code body, no braces 
                {}. 
              All of the abstract methods must be overridden by methods 
                in the concrete subclasses.