Working with Inheritance
- Eclipse: Oxygen
- Java: 1.8
Inheritance
Inheritance is the process of defining a new class based on an existing class where a child class acquires the properties of the parent class. For using the properties of a class (superclass) we need to create a class(subclass) and then use the ‘extends’ keyword to use the common property in the extended subclass. This is the basic functionality of inheritance to reduce the redundant code.
Extend Keyword
Extend keyword is used to inherit the properties of the class.
Let us consider the following program that demonstrates that inherits some properties and methods in child class from the parent class.
Step 1: Let us create a class vehicle where we declare and define common properties and methods. Here, vehicle is a super-class.
1 2 3 4 5 6 7 8 |
public class Vehicle { public String engine; public int wheels; public int seats; public int fueTank; public String lights; } |
Step 2: We create a child class for example Bike, Car, Truck class which extends the above class Vehicle. Here all these classes use specific properties. You can observe these specific properties in blow statement.
Bike class
1 2 3 |
public class Bike extends Vehicle { public String handle; } |
Car class
1 2 3 4 5 6 7 |
public class Car extends Vehicle { public String steering; public String musicSystem; public String airConditioner; public String fridge; public String entertainmentSystem; } |
Truck class
1 2 3 4 5 6 |
public class Truck extends Vehicle { public String steering; public String musicsystem; public String airConditioner; public String container; } |
Step 3: We create a class called Demo for creating an object of Bike class and initialize the variable with string “short”.
1 2 3 4 5 |
public class Demo { public static void main(String[] args) { Bike bike = new Bike(); bike.handle = "short"; } |
Step 4: We can access the methods from super-class in the sub-class as if they are in the same class. e.g We create an object of bike class, which access the engine property of vehicle class.
1 2 3 4 5 6 7 8 9 |
public class Demo { public static void main(String[] args) { Bike bike = new Bike(); bike.handle = "short"; bike.engine = "Petrol"; System.out.println(bike.engine); } } |
Output
Petrol
We have defined the properties. Now we will learn how default constructors of Superclass are called automatically in the Subclass. Here in this post, we will learn how to inherit the default constructor from superclass to subclass.
For example, let’s return to the Vehicle example we used in the previous section and show two related classes that define the same method:
We define the String property “lights” as private in the parent class Vehicle. However, when I display the property lights without initializing and run the program we will receive an exception. I am not allowed to define “lights” as public. Why? Because lights entities are private entities we won’t access this private entity in the child class.
1 2 3 4 5 6 7 8 |
public class Vehicle { public String engine; public int wheels; public int seats; public int fueTank; private String lights; } |
Output
Exception in thread “main” java.lang.Error: Unresolved compilation problem:
The field Vehicle.lights is not visible
at org.studyeasy.Demo.main(Demo.java:11)
Access the private variables in the child class
In the following code, to access the private variables in java. We have provided a default constructor and parameterize constructor. In default constructor, we have initialized some default properties. You can provide public getter and setter methods to access or change the value of the private member variables. In the following example, we have already initialized the default value so no need to provide setter we will provide the only getter. So we are able to access the private method from the parent class.
Vehicle Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
public class Vehicle { private String engine; private int wheels; private int seats; private int fuelTank; private String lights; public Vehicle() { this.engine = "petrol"; this.wheels = 4; this.seats = 4; this.fueTank = 35; this.lights = "LED"; } public Vehicle(String engine, int wheels, int seats, int fuelTank, String lights) { this.engine = engine; this.wheels = wheels; this.seats = seats; this.fueTank = fueTank; this.lights = lights; } public String getEngine() { return engine; } public int getWheels() { return wheels; } public int getSeats() { return seats; } public int getFueTank() { return fueTank; } public String getLights() { return lights; } } |
Bike Class
We have initialized the “handle” property in the default constructor. By using super keyword we called the default constructor of parent (Vehicle) class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class Bike extends Vehicle { private String handle; public Bike() { super(); this.handle = "short"; } public Bike(String handle) { super(); this.handle = handle; } public String getHandle() { return handle; } } |
Demo Class
By accessing the getHandle() and getEngine() method we display the properties values of bike class.
1 2 3 4 5 6 7 8 9 10 |
public class Demo { public static void main(String[] args) { Bike bike = new Bike(); System.out.println(bike.getHandle()); System.out.println(bike.getEngine()); } } |
Output:
short
petrol
Note: In this program, we are making use of the default constructor. In the next tutorial, we will make use of the parameterized constructor.
We have learned how the default constructors of Superclass are called automatically in the Subclass. Here, we will learn how to derive parameterized constructor from superclass to subclass.
1 2 3 4 5 6 7 8 9 10 |
public class Demo { public static void main(String[] args) { Bike bike = new Bike(); System.out.println("Handle: " + bike.getHandle()); System.out.println("Engine type: " + bike.getEngine()); } } |
Output
Handle: short
Engine type: petrol
Parent class parameterized constructor is called in child class using super ().super () should be the written in the first line inside the constructor. For example, the output of the following program is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Vehicle { private String engine; private int wheels; private int seats; private int fuelTank; private String lights; public Vehicle() { this.engine = "petrol"; this.wheels = 4; this.seats = 4; this.fuelTank = 35; this.lights = "LED"; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public Vehicle(String engine, int wheels, int seats, int fuelTank, String lights) { this.engine = engine; this.wheels = wheels; this.seats = seats; this.fuelTank = fueTank; this.lights = lights; } public String getEngine() { return engine; } public int getWheels() { return wheels; } public int getSeats() { return seats; } public int getFueTank() { return fuelTank; } public String getLights() { return lights; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class Car extends Vehicle { private String steering; private String musicSystem; private String airConditioner; private String fridge; private String entertainmentSystem; public Car() { super(); this.steering = "Power Steering"; } public Car(String steering, String engine, int wheels, int seats, int fueTank, String lights) { super(engine,wheels, seats,fueTank,lights); this.steering = steering; } public String getSteering() { return steering; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Demo { public static void main(String[] args) { Car car = new Car("Power steering", "deisel", 4, 4, 40, "LED"); System.out.println("Steering: "+car.getSteering()); System.out.println("Engine type: "+car.getEngine()); System.out.println("Number of seats: "+car.getSeats()); System.out.println("Fuel tank capacity: "+car.getFueTank()); System.out.println("Head lamp type: "+car.getLights()); System.out.println("Number of wheels: "+car.getWheels()); } } |
Output:
Steering: Power steering
Engine type: Deisel
Number of seats: 4
Fuel tank capacity: 40
Headlamp type: LED
Number of wheels: 4
Java toString() method
In Java toString() method is used to get a String representation of an object.
We can override the object’s toString() method during implementation. The toString() method of the Object class helps us to return values of the object, so we don’t need to write much code.
Example
In the following example, We have initialized the properties of Car using the constructor, printing the object of the car class prints the hashCode (org.studyeasy.vehicles.Car@15db9742) values of the objects.
1 2 3 4 5 6 7 8 |
public class Demo { public static void main(String[] args) { Car car = new Car("Power steering", "diesel", 4, 4, 40, "LED"); System.out.println(car); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Car extends Vehicle { private String steering; private String musicSystem; private String airConditioner; private String fridge; private String entertainmentSystem; public Car() { super(); this.steering = "Power Steering"; } public Car(String steering, String engine, int wheels, int seats, int fueTank, String lights) { super(engine, wheels, seats, fueTank, lights); this.steering = steering; } public String getSteering() { return steering; } |
Output
org.studyeasy.vehicles.Car@15db9742
Let’s see the real example of toString () method in following code. We override the toString() method with the properties that we want to display.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class Car extends Vehicle { private String steering; private String musicSystem; private String airConditioner; private String fridge; private String entertainmentSystem; public Car() { super(); this.steering = "Power Steering"; } public Car(String steering, String engine, int wheels, int seats, int fueTank, String lights) { super(engine, wheels, seats, fueTank, lights); this.steering = steering; } public String getSteering() { return steering; } @Override public String toString() { return "Car [getSteering()=" + getSteering() + ", getEngine()=" + getEngine() + ", getWheels()=" + getWheels() + ", getSeats()=" + getSeats() + ", getFueTank()=" + getFueTank() + ", getLights()=" + getLights() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]"; } } |
Output
Car [getSteering()=Power steering, getEngine()=deisel, getWheels()=4, getSeats()=4, getFueTank()=40, getLights()=LED, getClass()=class org.studyeasy.vehicles.Car, hashCode()=366712642, toString()=org.studyeasy.vehicles.Car@15db9742]
We have discussed superclasses and subclasses. Now, we will discuss method overriding.
Method overriding
The method override is used for the runtime polymorphism. It helps to define a behavior that is specific to the subclass or child class type, which means a subclass can implement a parent class based on your request.
Rules for Java Method Overriding
- The method must have the same name as in the parent class
- The method must be IS-A relationship(inheritance)
- The method must have the same parameters as in the parent class.
In the following example we demonstrate method overriding, the run () method of Parent class is defined in child class with the same implementation, so output will be “Running vehicle”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
public class Vehicle { private String engine; private int wheels; private int seats; private int fueTank; private String lights; public Vehicle() { this.engine = "petrol"; this.wheels = 4; this.seats = 4; this.fueTank = 35; this.lights = "LED"; } public Vehicle(String engine, int wheels, int seats, int fuelTank, String lights) { this.engine = engine; this.wheels = wheels; this.seats = seats; this.fueTank = fueTank; this.lights = lights; } public String getEngine() { return engine; } public int getWheels() { return wheels; } public int getSeats() { return seats; } public int getFueTank() { return fueTank; } public String getLights() { return lights; } public void run() { System.out.println( "Running vehicle"); } } public class Demo { public static void main(String[] args) { Car car = new Car("Power steering", "deisel", 4, 4, 40, "LED"); System.out.println(car); car.run(); } } |
Output
Car [getSteering()=Power steering, getEngine()=deisel, getWheels()=4, getSeats()=4, getFueTank()=40, getLights()=LED, getClass()=class org.studyeasy.vehicles.Car, hashCode()=366712642, toString()=org.studyeasy.vehicles.Car@15db9742]
Running vehicle
In the following example, we have defined the run method in the child class, as defined in the parent class but child class wants to specify its own implementation. The name of the method and parameter must be the same and there must be an IS-A relationship between the classes. Therefore, there is method overriding. When we execute this method, it generates “Running car” instead of “Running vehicle”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
public class Car extends Vehicle { private String steering; private String musicSystem; private String airConditioner; private String fridge; private String entertainmentSystem; public Car() { super(); this.steering = "Power Steering"; } public Car(String steering, String engine, int wheels, int seats, int fuelTank, String lights) { super(engine, wheels, seats, fueTank, lights); this.steering = steering; } public String getSteering() { return steering; } @Override public String toString() { return "Car [getSteering()=" + getSteering() + ", getEngine()=" + getEngine() + ", getWheels()=" + getWheels() + ", getSeats()=" + getSeats() + ", getFueTank()=" + getFueTank() + ", getLights()=" + getLights() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]"; } public void run() { System.out.println("Running car"); System.out.println(toString()); } } |
1 2 3 4 5 6 7 8 |
public class Demo { public static void main(String[] args) { Car car = new Car("Power steering", "deisel", 4, 4, 40, "LED"); car.run(); } } |
Output
Running car
Car [getSteering()=Power steering, getEngine()=deisel, getWheels()=4, getSeats()=4, getFueTank()=40, getLights()=LED, getClass()=class org.studyeasy.vehicles.Car, hashCode()=366712642, toString()=org.studyeasy.vehicles.Car@15db9742]
Contributed by: Poonam Tomar