Java With Us
Home   |   Tutorial   |   Programs  

Java Tutorial

Introduction to Java
Hello World Program
Variables and Data types
More about data types
Displaying text using print and println
Displaying text using printf
Java Comments
Naming conventions for Identifiers
Mathematical operations in Java
Taking input from the user

Classes and Objects
Introduction to object oriented programming
The constituents of a Class
Creating objects and calling methods
Get and Set Methods
Default constructor provided by the compiler
Access Specfiers
Scope and lifetime of Variables
Call by value and Call by Reference

A few more topics
Casting
Class as a reference data type
Constants or literals
Final variables
Increment and decrement operators
Manipulating Strings
Operators
Overloading constructors and methods
Static methods and variables
The Java API
The Math class
this keyword
Wrapper classes

Control Structures
Control Statements
Repetition statements
Nested loops
Formulating algorithms
Branching Statements

Arrays
Arrays introduction
Processing arrays using 1oops
Searching and sorting arrays
Array of objects
Multi dimensional arrays
Taking input as command line arguments
Using ellipsis to accept variable number of arguments

Inheritance
Inheritance introduction
Relation between a super class and sub class
Final classes and methods
The protected access specifier
Class Object

Polymorphism
Introduction
Interfaces
Packages
Abstract classes and methods

Exception handling
Exception handling introduction
Exception hierarchy
Nested try catch blocks
Throwing exceptions


Inheritance

Inheritance is the process by which the variables and methods defined in one class become a part of a newly defined class too. The class which inherits can define its own variables and methods in addition to what have been inherited from the other class. As said in the beginning, you can take the analogy of inheritance of property from parents to children. The children inherit the property of their parents and are capable of adding their own earned property too. Also, property inherited may be sold and given a few face in the form of a new property. This can be implemented in Java's inheritance too. Variables and methods inherited may be overridden to give them a new definition. We will now look into how one class can inherit from another using the extends keyword. We will also study various other things vital for the application of inheritance in our projects. Lastly, we shall learn about the Object class from which all new classes inherit implicitly.

For the purpose of learning in a more natural way, we will continue with the Student example which we have dealt with in the beginning but slightly modify it to adapt it to this study on inheritance. We will have a class named Person which is more general in nature. This class contains the variables name and age which every person possesses. We also have a method printDetails() which prints the name and age. And then we develop a class Student that inherits from the Person class. A student will have a few additional variables like marks and rank. There will also be appropriate methods for the Student class. Inheritance is used either to provide additional functionality to a class in the form of new methods or to define a specific class from a general class. In this particular example, a Person is general in nature,, while Student is more specific. Of course, specific and general are relative and depend on the objects that are taken into consideration.

The class from which a new class inherits is known as the super class. It is also called by other names such as base class, main class and parent class. The class which inherits from the super class is known as the subclass, also referred to as derived class, extended class and child class. But, we generally use the terms super class and sub class. In this particular example, Person is the super class and Student is the Sub class. Let us first define the Person class in the following way with two variables, a constructor and a method.

public class Person {

    String name;
    int age;

    public Person(String n, int a) {
        name = n;
        age = a;
    }

    public void printDetails() {
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
    }
}

Now, we define the Student class and specify it to be a subclass of the Person class already defined. For this purpose, the extend keyword is used beside the class name and is followed by the name of the class it is extending which in this case is Person. So the class declaration of Student would be the following.

public class Student extends Person

A sub class inherits all the variables and methods of the super class even if they are private. The only difference with private variables is that they cannot be accessed in the sub class. So, our Student class has inherited the two variables, name and age and the method printDetails() from the Person class. We only need to define the additional variable marks and provide a proper constructor.

When a sub class members' are being initialised in the constructor of the class, an appropriate constructor of the super class has to be called from the sub class' constructor so that the variables defined in the super class are also initialised properly. This call may be made using the super keyword followed by parentheses in which the required arguments for the constructor of the super class are passed. This call to super should be the first line of the constructor. If we do not explicitly call the super class constructor, the compiler makes an automatic call to the default constructor of the super class (or the no argument constructor). In case, the super class does not have a no argument constructor, compilation errors will be generated. The following code shows the Person class with the variable marks declared and the constructor defined.

public class Student extends Person{

    int marks;

    public Student(String n, int a, int m) {
        super(n, m);
        marks = m;
    }
}

The class Student declared above has not just marks, but also a name and an age. To verify this, provide some method m() and try to access these variables and the method printDetails() in the following way. Compile the program and you will not receive any compilation errors. This confirms that variables and methods of the super class have been inherited by the sub class.

public void m() {
    name=null;
    age=-1;
    printDetails();
}

However, if we try to access private variables of the super class from the sub class, compilation errors occur. This is because the scope of private instance variables is limited to the class itself. In order to modify such variables from the super class, we need to provide set and get methods or other similar methods in the super class which can then be called from the sub class. In the above program, change name to private, and provide getName() and setName() method in the Person class. Call these methods from the method m() in the following way and compile.

String str=getName();
setName("No name");

Variables and methods inherited from the super class retain their access specifiers. A public variable is still public and a variable whose access specifier is unmentioned is still treated in the same way in the sub class also. For example, we can write a Test program for the Student class, create its objects and access the variables name and age through the object as they are still public.

Student s = new Student ("Sai", 19, 99);
s.age=18; // valid

If we declare variables in the sub class which have the same name as the variables declared in the super class, then these variables would hide the ones declared in the super class. This is similar to how local variables hide instance variables. For example, define a new variable age in the Student class.

int age;

This age variable hides the age variable that has been declared in the super class. Now, the Student class has two age variables, one of which has been defined in the Person class and the other defined in the Student class itself. When we refer to the variable age in a method of the sub class, we get access to the sub class version of age and not the super class version. The sub class version has hidden the super class version. To get access to the super class variable, we use the super keyword in the following way:

super.age= 10; // gives access to the super class' version

In a similar way, we can also hide the methods of the super class. This is more aptly referred to as method overriding. A method in the super class is said to override the method in the sub class when it has the same method signature which includes method name and the number, order and type of parameters. The names of parameters are irrelevant. We can override the method printDetails() in the Student class so that the marks of the Student are printed in addition to the name and age of the Student. Note that we can also call the super class version of printDetails() in order to display the first two items.

public void printDetails(){
    super.printDetails();
    System.out.println("Marks: "+marks);
}

If a method in the sub class has the same name and parameter list as another method defined in the super class, then it needs to have the same return type also. Otherwise compilation errors occur. Moreover, stricter access specifications may not be applied to the overridden methods. This is known as attempting to assign weaker access privileges. The weakest of access privileges is private followed by unspecified, protected and public. A method that was public may not be overridden with a method that is private. However, a private method may be overridden with a public method. Also, to make sure that we are writing an overridden version of an already method and not a new method, we may use the '@ Override ' annotation. This is specified prior to method declaration in eth following way.

@Override
public void printDetails(){
    //code
}

It is always recommended to use this annotation whenever methods are being overridden. When this annotation is used, the compiler checks that this method's signature matches with the ones existing in the super class. If no match is found, a compilation occur occurs. This is important to ensure that our code is not affected by typographical errors. For example, if in the Student class, we incorrectly type the method name as printDetails() instead of printDetails(), the method will be considered to be a new method. When Objects of Student are created and the printDetails() method is invoked on them, the method defined in super class called. In order to avoid such trivial errors, the use of @Override annotation is recommended.

The principle of least privileges is not applicable to variables. We may have a public variable in the super class and a private variable in the subclass both with the same which isn't possible with methods. When the objects of sub class are created and the access to this variable is given based on the specifiers associated with the variable defined in the subclass, which in this case is private leading to denial of access. Moreover, such variables are also not accessible in classes derived from theses sub classes.

Subclasses may be further extended to another class. This is known as multi-level inheritance. For example, we can extend the Student class above to a new sub class StudentWithDisabilities. Now, this new class will have the variables and methods of both of its super classes. A class is called as either a super class or a sub class depending on the context in which it is being seen. For example, the Student class is a sub class with respect to the class Student while it is a super class with respect to the class StudentWithDisabilities. We will look into multi-level inheritance later on. The inheritance which we have seen till now is single inheritance where a class extends a single super class. Java does not support multiple inheritance (not to be confused with multi-level inheritance) Multiple inheritance is the form of inheritance where a class can extend more than one super class. We will look into multiple inheritance later on. For now, here is the complete Student sub class with the overridden method and a Test class. we have also provided an extra method showGrade() which displays the grade of the Student.

public class Student extends Person {

    int marks;

    public Student(String n, int a, int m) {
        super(n, a);
        marks = m;
    }

    @Override
    public void printDetails() {
        super.printDetails();
        System.out.println("Marks: " + marks);
    }

    public void showGrade() {
        char grade;
        if (marks >= 90) {
            grade = 'A';
        } else if (marks >= 75) {
            grade = 'B';
        } else if (marks >= 50) {
            grade = 'C';
        } else {
            grade = 'D';
        }
        System.out.println("Grade: " + grade);
    }
}

And here is the Test class

public class StudentTest {

    public static void main(String[] args) {
        Person p = new Person("Ram", 18);
        p.printDetails();
        Student s = new Student("Sai", 7, 97);
        s.age = 19;
        s.marks = 100;
        s.printDetails();
        s.showGrade();
    }
}

We have created two objects, one of the Person class and one of the Student class and assigned them to the corresponding variables. We have accessed the age and marks of the Student object and changed them. This is possible as they have been declared to be public variables. And then, the printDetails() method was invoked on both these objects. Here is the output:

Name: Ram
Age: 18
Name: Sai
Age: 19
Marks: 100
Grade: A

Privacy Policy