Overloading
Java allows you to have multiple methods having the same name, as long as each method accept different sets of argument types. This technique is called method overloading. The return value of the method is not taken into consideration


public class Person {
    String name;
    int age;
    Person(){
        name = "Penda";
        age = 20;
    }
    Person(String name){
        this.name=name;
        age=20;
    }
    Person(int age){
        name="Pijo";
        this.age=age;
    }
    Person(String name, int age){
        this.name=name;
        this.age=age;
    }
    public static void main(String[] arg){
        Person ps[]=new Person[4];
        ps[0]= new Person();
        ps[1]= new Person(22);
        ps[2]= new Person("Kami");
        ps[3]= new Person("Simo",26);
        main(ps);
    }
    public static void main(Person[] ps){
        for(int i=0;i<ps.length;i++){
            System.out.print(ps[i].name);
            System.out.println("   age: "+ps[i].age);
        }
    }
    

}
Penda   age: 20
Pijo   age: 22
Kami   age: 20
Simo   age: 26

 

Inheritance

Inheritance creates a new class definition by building upon an existing definition (you extend the original class)

The new class can, in turn, can serve as the basis for another class definition

The keyword extends is used to base a new class upon an existing class

Several pairs of terms are used to discuss class relationships (these are not keywords)


"is a "    relation. A derived class instance may be used in any place a base class instance would work - as a variable, a return value, or parameter to a method

Inheritance is used for a number of reasons (some of the following overlap)

When extending a class, you can add new properties and methods, and you can change the behavior of existing methods (which is called overriding the methods)

 


class SupClasse{
        float fl;
        void func() {…}
}

class ExtClasse extends SupClasse{     //2 data members and 2 methods
        int in;
        void func2(){…};
}

Variables with the same names

class SupClasse{
        float fl;
        int s;
        void func() {…}
}

class ExtClasse extends SupClasse{     //4 data members and 2 methods
        int in; 
        int s;
        void func2(){
             int s2 = s;
           
int s1 = super.s;
            

       };

}

   

Methods with the same names - overriding

When a method is called through a reference, the JVM looks to the actual class of the instance to find the method. If it doesn't find it there, it backs up to the ancestor class (the class this class extended) and looks there (and if it doesn't find it there, it backs up again, potentially all the way to Object).

Sooner or later, it will find the method, since if it wasn't defined somewhere in the chain of inheritance, the compiler would not have allowed the class to compile.

In this manner, what you could consider the most advanced (or most derived) version of the method will run, even if you had a base class reference

start with:    java Shapes


class Shape {
    public String toString() { return "Shape"; }
}

class Circle extends Shape {
    public String toString() { return "Circle"; }
}

class Square extends Shape {
    public String toString() { return "Square"; }
}

class Triangle extends Shape {
    public String toString() { return "Triangle"; }
}

public class Shapes{
    public static void main(String a[]){
        Shape[] sh = {new Shape(),new Circle(), new Square(), new Triangle()};
        for (int i=0; i< sh.length; i++)
            System.out.println(i+": "+sh[i]);
    }
}

       0: Shape        
       1: Circle
       2: Square
       3: Triangle

Inheritance Examples


One of the classes used in the GUI is Window - its family tree looks like:







Base class - Point, derived class - PointC:

package deriv1;
public class Point {
         protected double x=3.4, y=5.6 ;
         protected String name =" point";
         public String  toString(){
                return "point: (" + x + "," + y+")" ;
         }
         public void move(double dx, double dy){
                System.out.println("Moving the point");
                x+=dx;
                y+=dy;
         }
}







-------------------------------------------------

 package deriv1;
public class PointC extends Point{
         private byte col=3;
         private String name ="color point";
         public void dspl(){
                System.out.print("point col:("+x+","+y+  ","+col+")\t");
                System.out.print("name: "+name+"\t");           //name locale
                System.out.println("with base class: "+super.name);
         }
         public void inc(){
                x++; y++;
         }
}
package deriv1;
public class Test {
         public static void main(String arg[]){
                Point p = new Point();
                System.out.println("p:"+p+"\n");
               
                PointC pc = new PointC();
                System.out.println("pc using toString from base: "+pc);
                System.out.print("using dspl(): ");
                pc.dspl();
               
                pc.inc();
                System.out.println("\n\n After inc():");
                System.out.println("using toString from base: "+pc);
                System.out.print("using dspl(): ");
                pc.dspl();  
         }
}

 

-----------------------------------------

Result:

p:point: (3.4,5.6)

pc using toString from base: point: (3.4,5.6)
using dspl(): point col:(3.4,5.6,3)    name: color point    with base class:  point


 After inc():
using toString from base: point: (4.4,6.6)
using dspl(): point col:(4.4,6.6,3)    name: color point    with base class:  point

The Point & PointC with constructors

One base class constructor will always run when instantiating a new derived class object

Constructors with parameters

Within a derived class constructor, however, you can use super( parameterList ) to call a base class constructor

public class Point {
         protected double x, y;
         public Point(){
                System.out.println("Constructor base no prs");
                x=3.4; y=5.6;
         }
         public Point(double x, double y){
                System.out.println("Constructor base 2 prs");
                this.x=x;   this.y=y;
         }
         public String  toString(){
                return "point: (" + x + "," + y+")" ;
         }
         public void move(double dx, double dy){
                System.out.println("Moving the point");
                x+=dx;
                y+=dy;
         }
}

----------------------------------------------------------------------
public class PointC extends Point{
         private byte col;
         public PointC(){
                System.out.println("Constructor drvd no par");
                col=3;
         }
         public PointC(double x,double y,byte col){
                super(x,y);
                System.out.println("Constructor drvd 3 par");
                this.col = col;
         }
         public void dspl(){
                System.out.println("point col:("+x+","+y+","+col+")");
         }
         public void inc(){
                x++; y++;
         }
}

--------------------------------------------------------------------------

 

public class Test {
         public static void main(String arg[]){
                Point p = new Point();
                System.out.println();
                
                Point p1 = new Point(1.4,2.6);
                System.out.println(p +"  "+p1);
                System.out.println();
                
                PointC pc = new PointC();
                pc.dspl();
                System.out.println();
                
                PointC pc1 = new PointC(4.1, 5.2,(byte)4);
                pc1.dspl();
         } 
}
 Result:

Constructor base no prs

Constructor base 2 prs
point: (3.4,5.6)  point: (1.4,2.6)

Constructor base no prs
Constructor drvd no par
point col:(3.4,5.6,3)

Constructor base 2 prs
Constructor drvd 3 par
point col:(4.1,5.2,4)


Methods with differing type signatures are overloaded - not overridden.
class A {
  int i, j;

  A(int a, int b) {
    i = a;
    j = b;
  }

  void show() {
    System.out.println("i and j: " + i + " " + j);
  }
}

class B extends A {
  int k;

  B(int a, int b, int c) {
    super(a, b);
    k = c;
  }

  void show(String msg) {
    System.out.println(msg + k);
  }
}

class Test {
  public static void main(String args[]) {
    B subOb = new B(1, 2, 3);

    subOb.show("This is k: "); // this calls show() in B
    subOb.show(); // this calls show() in A
  }
}