Interface and Abstract Class in Java

Overview

Q&A

  • Whenever we are creating a Child class object whether Parent class object will be created or not?
    • Whenever we are creating Child class object automatically Parent constructor will be executed to perform initialization for the instance variables which are inheriting from parent. But it will not create an object of Parent class. It will create the object of only the Child class.
  • Whenever we are creating a Child class object what is the need of executing Parent class constructor?
    • Child class constructor is used to initialize child class properties and Parent class constructor is used to initialize Parent class properties. When you are calling the Child class constructor you have to call Parent class constructor with the help of super keyword. If not the compiler will prompt compile time error.
    • In the below program InterfaceAndAbstractMain both Parent and Child constructor are executed for Child object initialization only.
    • Note: Whenever we are creating Child class object automatically Parent class constructor will be executed but it will create the object of Parent class.
    • The purpose of Parent constructor execution is to initialize Child object only. Of course for the instance of variables which are inheriting from Parent class.
 public class Person {
final private String name;
/* If you are using final keyword, then you can change the value of name variable only through constructor */
final private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}
 public class Student extends Person {
final private int rollNo;
final private int marks;

public Student(String name, int age, int rollNo, int marks) {
super(name, age);
this.rollNo = rollNo;
this.marks = marks;
}

public int getRollNo() {
return rollNo;
}

public int getMarks() {
return marks;
}

@Override
public String toString() {
return "Student :: Name :: " + getName() + " :: Age :: " + getAge() + " :: Roll No :: " + rollNo + " :: Marks :: " + marks;
}
}
 public class Teacher extends Person {
final private String subject;
final private String className;

public Teacher(String name, int age, String subject, String className) {
super(name, age);
this.subject = subject;
this.className = className;
}

public String getSubject() {
return subject;
}

public String getClassName() {
return className;
}

@Override
public String toString() {
return "Teacher :: Name :: " + getName() + " :: Age :: " + getAge() + " :: Subject :: " + subject + " :: ClassName :: " + className;
}
}
 public class InterfaceAndAbstractMain {
public static void main(String args[]) {
Student student1 = new Student("Jai Kishan", 12, 101, 246);
Student student2 = new Student("Suraj Kishan", 11, 102, 236);
Teacher teacher1 = new Teacher("Ramesh Pawar", 36, "Mathematics", "10 A");
Teacher teacher2 = new Teacher("Jitesh Mahatre", 39, "History", "8 B");
printStudentDetails(student1);
printStudentDetails(student2);
printTeacherDetails(teacher1);
printTeacherDetails(teacher2);
}

/* You can call only static methods in main method */
public static void printStudentDetails(Student student) {
System.out.println(student);
}

/* You can call only static methods in main method */
public static void printTeacherDetails(Teacher teacher) {
System.out.println(teacher);
}
}
  • We cannot create object of an Abstract class directly but can we create object of the Abstract class indirectly? Is it valid?
    • We cannot create object of an Abstract class either directly or indirectly. Such call is invalid and it will generate compile time error. 
  • We cannot create object of an Abstract class but we can create constructor of the Abstract class. What is the need of that constructor?
    • The constructor of an Abstract class is used to initialize its properties, if we won't use this constructor then we have to initialize every property of the Abstract class individually in every child class and this will create code redundancy. So to avoid code redundancy we have to create constructor of the Abstract class and to implement code reusability. So the main purpose of the constructor of an Abstract class is to perform initialization.
 public abstract class Person {
final private String name;
/* If you are using final keyword, then you can change the value of name variable only through constructor */
final private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}
  • Whenever we are creating child class object automatically parent class object will be created. Is it valid?
    • Whenever we are creating Child class object, it's Parent class object will not be created. But we can create the object of a Parent class explicitly using the conventional new keyword. 
  • Anyway we cannot create object of an Abstract class and Interface. But Abstract class can contain constructor but Interface does not. Why?
    • The main purpose of constructor is to perform initialization of an Object i.e. to provide values for Instance variables.
    • Abstract class can contain Instance Variables which are required for Child class Object. And to initialize the Instance Variables of the Abstract class we require constructor inside the Abstract class.
    • But every variable inside an Interface is always public, static and final, whether we declare it or not. Also every variable of an Interface must be initialized at the time of declaration so they are not Instance Variable. 
    • Due to this initialization of the variables at the time of declaration in an Interface, we do not need a Constructor. Also as the variable is final, we cannot change the variable once it is declared and initialized. Hence Constructor is not required in an Interface.
  • Inside Interface we can create only abstract methods. But in Abstract class we can create abstract methods as per requirements. Then what is the need of Interface?? Is it possible to replace Interface concept with Abstract class???
    • We can replace Interface with Abstract class but it is not Good Programming Practice. 
    • While extending X (Abstract class) we can't extend any other class. 
    • While implementing Y (Interface) we can extend any other class and hence we won't miss any Inheritance benefit.
    • Creating a new object via Abstract class is costly as compared to creating a new object via Interface.
    • Hence if Abstraction is highly recommended then you can use Interface instead of Abstract class.
    • If partial Implementation is required in a project then we can use only Abstract class. 
 public interface Semester {

String firstSemester = "First Semester";

void printFirstSemesterMarks();
void printSecondSemesterMarks();

// To write body of a method in Interface, you must declare it as default.
default String semesterName(String data) {
return data;
}
}
 public class Student extends Person implements Semester {
final private int rollNo;
final private int marks;

public Student(String name, int age, int rollNo, int marks) {
super(name, age);
this.rollNo = rollNo;
this.marks = marks;
}

public int getRollNo() {
return rollNo;
}

public int getMarks() {
return marks;
}

// Note, to use the variable of an Interface you won't have to implement the interface.
// As the variable itself is public and static by default, we can access the variable directly but, you can't change it as it is final.
@Override
public void printFirstSemesterMarks() {
System.out.println("Marks of " + Semester.firstSemester + " is: " + this.marks);
}

@Override
public void printSecondSemesterMarks() {
System.out.println("Marks of " + semesterName("Second Semester") + " is: " + this.marks);
}

@Override
public String toString() {
return "Student :: Name :: " + getName() + " :: Age :: " + getAge() + " :: Roll No :: " + rollNo + " :: Marks :: " + marks;
}
}
    • If everything is Abstract it is highly recommended to go for Interface but not Abstract class.
    • We can replace Interface with Abstract class but it is not a good programming practice (This is something like recruiting IAS Officer for sweeping purpose).

Inheritance:

Interface supports multiple inheritance:
 public class Person {
final private String name;

final private int age;
final private double salary;

public Person(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public double getSalary() {
return salary;
}

public void showPersonClassName() {
System.out.println(this.hashCode());
}
}
 public class Doctor extends Person {
final private String hospitalName;

public Doctor(String name, int age, double salary, String hospitalName) {
super(name, age, salary);
this.hospitalName = hospitalName;
}

public String getHospitalName() {
return hospitalName;
}

public void showDoctorClassName() {
System.out.println(this.hashCode());
}
}
 public class Programmer extends Person implements ProgrammerInterface {

private String companyName;

public Programmer(String name, int age, double salary, String companyName) {
super(name, age, salary);
this.companyName = companyName;
}

public String getCompanyName() {
return companyName;
}

public void setCompanyName(String companyName) {
if (validateProgrammer()) {
this.companyName = companyName;
}
}

@Override
public boolean validateProgrammer() {
if (validateName() && validateAge()) {
System.out.println("The inputs are valid");
return true;
} else {
System.out.println("Please fill in the details carefully!!! The inputs are not valid.");
return false;
}
}

@Override
public boolean validateName() {
return !this.getName().equals("");
}

@Override
public boolean validateAge() {
return this.getAge() > 18;
}

@Override
public void validateTeacher() {

}

public void showProgrammerName() {
System.out.println(this.hashCode());
}
}
 public class Teacher extends Person {

final private String schoolName;

public Teacher(String name, int age, double salary, String schoolName) {
super(name, age, salary);
this.schoolName = schoolName;
}

public String getSchoolName() {
return schoolName;
}

public void showTeacherClassName() {
System.out.println(this.hashCode());
}
}
 public interface PersonInterface {
boolean validateName();

boolean validateAge();
}
 public interface TeacherInterface {
boolean validateName();

void validateTeacher();
}
 public interface ProgrammerInterface extends PersonInterface, TeacherInterface {
boolean validateProgrammer();
}
 public class InheritanceMain {
public static void main(String[] args) {
/* For Doctors*/
Person doctor1 = new Doctor("Joe Dane", 24, 56000.0, "Apollo Hospital");
// Doctor doctor3 = new Person("Kate Upton", 26, 95000.0);
/* This is an example of Polymorphism */
doctor1.showPersonClassName();
/* This below code is invalid, it prompts compile time error. */
/* Because reference of Parent class can create object of child class but
can't access properties and methods of child class */
// doctor1.showDoctorClassName();
Doctor doctor2 = new Doctor("Jane Perry", 24, 65000, "Seven Hospital");
/* This below code is valid */
/* Because object of child class can access properties and methods of parent class */
doctor2.showPersonClassName();
doctor2.showDoctorClassName();
/* This below code is invalid. Because reference of Child class can't be used to create object of Parent class */
// Doctor doctor3 = new Person("Kate Upton", 26, 95000.0);
/* For Teachers */
Person teacher1 = new Teacher("Sumit Vyas", 35, 56000.0, "K.B.C.H");
/* For Programmers */
Person programmer1 = new Programmer("Abhishek Tiwari", 28, 125000.0, "Kotak Mahindra");
Programmer programmer2 = new Programmer("Kiran Rathod", 17, 75000.0, "Shaw Info Solutions");

/* For Common People */
printDetails(doctor1, doctor2, teacher1, programmer1, programmer2);
}

public static void printDetails(Person... person) {
for (Person p : person) {
System.out.println("Name: " + p.getName());
System.out.println("Institution: " + p.getSalary());
}
}
}

Do's and Dont's

  • You can create a constructor of an Abstract class but you can't create an object of an Abstract class directly. We can create object of an Abstract class indirectly.
  • You cannot create a constructor and object of an Interface.
  • new keyword is used to create an object.
  • Constructor is used to initialize an object.
  • In the event of creating an object: first the new keyword is executed to create an object and then the constructor method of a class is called to initialize the object.
  • To use code reusability we should create constructor of an Abstract class.
  • Interface support multiple inheritance.
  • The purpose of Constructor is to create an Object: Invalid
  • The purpose of Constructor is to initialize an Object but not to create an Object: Valid
  • Once Constructor completes then only Object creation completes: Invalid.
  • First Object will be created and then Constructor will be executed: Valid.
  • The purpose of new keyword is to create an Object and the purpose of Constructor is to initialize the Object: Valid.
  • We can't create Object of an Abstract Class directly but we can create an Object of Abstract Class indirectly: Invalid.
  • Whenever we are creating Child class Object automatically Parent class Object will be created internally: Invalid.
  • Whenever we are creating Child class Object automatically Abstract Class constructor will be executed: Valid.
  • Whenever we are creating Child class Object automatically Parent Object will created: Invalid.
  • Whenever we are creating Child class Object automatically Parent Constructor will be executed but Parent Object won't be created: Valid.
  • Either directly or indirectly we can't create Object for Abstract class and hence Constructor concept is not applicable for Abstract class: Invalid.
  • Interface can contain Constructor: Invalid.

Reference



Comments