Abstract Class
An abstract class is a class that contains at least one pure virtual function. It is designed to be used as a base class for other classes, providing a common interface and shared functionality. An abstract class cannot be instantiated directly, but it can be used as a reference or pointer type. Here's an example:
class Shape {
public:
virtual void draw() = 0;
virtual double area() = 0;
};
class Circle : public Shape {
public:
void draw() {
// Implementation for drawing a circle
}
double area() {
// Implementation for calculating the area of a circle
}
};
In this example, the Shape class is an abstract class because it contains pure virtual functions (draw() & area()). The Circle class inherits from Shape & provides implementations for the pure virtual functions. By using an abstract class, we can define a common interface that derived classes must adhere to, ensuring a consistent structure & behavior.
Importance of Interfaces
-
Abstraction: Interfaces allow for the separation of the interface from the implementation. They define a set of methods that a class must implement, without specifying how those methods should be implemented. This abstraction enables modular design & reduces dependencies between classes.
-
Multiple Inheritance: C++ supports multiple inheritance, which means a class can inherit from multiple base classes. However, multiple inheritance can lead to ambiguity & complexity. Interfaces provide a clean way to achieve multiple inheritance without the associated problems. A class can inherit from multiple interfaces, implementing the required methods without the risk of conflicts.
-
Polymorphism: Interfaces facilitate polymorphism, which allows objects of different classes to be treated as objects of a common interface. This enables code reusability & flexibility. By using interfaces, you can write generic code that works with any object that implements the interface, regardless of its specific class.
- Loose Coupling: Interfaces promote loose coupling between classes. When a class depends on an interface rather than a concrete class, it reduces the dependencies & makes the code more maintainable. Changes to the implementation of a class do not affect the code that uses the interface, as long as the interface remains unchanged.
Rules While Using Interfaces
When working with interfaces in C++, there are certain rules & guidelines to follow:
-
Pure Virtual Functions: An interface must contain at least one pure virtual function. This ensures that the interface is abstract & cannot be instantiated on its own.
-
No Implementation: Interfaces should not provide any implementation for the functions they declare. The implementation is the responsibility of the derived classes. Interfaces only define the function signatures.
-
No Data Members: Interfaces should not contain any data members. They are intended to define a contract for behavior, not to store data. Data members should be part of the derived classes that implement the interface.
- No Constructor or Destructor: Interfaces do not have constructors or destructors. They are not responsible for object creation or destruction. The derived classes handle these aspects.
-
Inheritance: A class can inherit from multiple interfaces using the public inheritance mode. This allows the class to implement the functions declared in the interfaces.
-
Override Functions: When a class inherits from an interface, it must override all the pure virtual functions declared in the interface. Failure to do so will result in the derived class also being abstract.
- Pointer or Reference: Interfaces are typically used through pointers or references. This allows for runtime polymorphism, where the specific implementation of an interface can be determined dynamically.
Example
class Printable {
public:
virtual void print() = 0;
};
class Document : public Printable {
public:
void print() {
// Implementation for printing a document
}
};
void printItem(Printable* item) {
item->print();
}
In this example, the Printable class is an interface with a pure virtual function print(). The Document class inherits from Printable & provides an implementation for the print() function. The printItem() function takes a pointer to Printable, allowing it to work with any object that implements the Printable interface.
Examples
Example 1: Shape Interface
class Shape {
public:
virtual double area() = 0;
virtual void draw() = 0;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() {
return 3.14 * radius * radius;
}
void draw() {
// Code to draw a circle
}
};
class Rectangle : public Shape {
private:
double width;
double height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() {
return width * height;
}
void draw() {
// Code to draw a rectangle
}
};
In this example, we have a Shape interface that declares two pure virtual functions: area() & draw(). The Circle & Rectangle classes inherit from Shape & provide their own implementations for these functions. This allows us to treat Circle & Rectangle objects as Shape objects, enabling polymorphism.
Example 2: Animal Interface
class Animal {
public:
virtual void makeSound() = 0;
};
class Dog : public Animal {
public:
void makeSound() {
cout << "Woof!" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() {
cout << "Meow!" << endl;
}
};
void animalSound(Animal* animal) {
animal->makeSound();
}
In this example, we have an Animal interface with a pure virtual function makeSound(). The Dog & Cat classes inherit from Animal & provide their own implementations for the makeSound() function. The animalSound() function takes a pointer to Animal, allowing it to work with any object that implements the Animal interface.
Frequently Asked Questions
Can an interface have a constructor or destructor?
No, interfaces cannot have constructors or destructors. They are not responsible for object creation or destruction.
Can an interface contain data members?
No, interfaces should not contain data members. They are intended to define behavior, not store data.
Can a class inherit from multiple interfaces?
Yes, a class can inherit from multiple interfaces using multiple inheritance. This allows the class to implement multiple interfaces.
Conclusion
In this article, we explained the concept of interfaces in C++. We learned about pure virtual functions, abstract classes, & the importance of interfaces in designing modular & flexible code. We also discussed the rules to follow while using interfaces & saw practical examples which helped us in clearing all the doubts. Interfaces provide a powerful mechanism for defining common behavior, achieving polymorphism, & promoting loose coupling between classes.
You can refer to our guided paths on Code 360. You can check our course to learn more about DSA, DBMS, Competitive Programming, Python, Java, JavaScript, etc. Also, check out some of the Guided Paths on topics such as Data Structure andAlgorithms, Competitive Programming, Operating Systems, Computer Networks, DBMS, System Design, etc., as well as some Contests, Test Series, and Interview Experiences curated by top Industry.