You are on page 1of 20

Object Oriented

Programming
• Lecture 7: Abstract Classes
Abstract classes
• The purpose of an abstract class is to provide a base class (i.e. a
general concept) from which other classes can inherit.
• Abstract types cannot be used as parameter types, as function
return types, or as the type of an explicit conversion. However,
pointers and references to an abstract class can be declared.
• An abstract class serves only as an interface
• Attempting to instantiate an object of an abstract class causes a
compilation error.

2
Abstract classes – cont’d
• A class that is derived from an abstract class should implement the
pure virtual functions in the abstract class, otherwise, the derived
class will also be considered an abstract class.
• The abstract classes provides an architecture that allows new
functionalities to be added to the system easily, just by inheriting
from the related abstract class.

3
Abstract classes – cont’d
• Abstract classes should not be confused with OOP data abstraction
• OOP Data Abstraction: Keep implementation details separate from
associated data
• An abstract class can have constructors with implementation on it.
• Classes that inherit from the abstract class and implement its virtual
methods are called concrete classes.

4
Abstract classes – virtual functions
• A class is made abstract by declaring at least one of its functions as
pure virtual function.
• A pure virtual function is specified by placing “=0” in it declaration.
• A pure virtual function is one which must be overridden by any
concrete (i.e., non-abstract) derived class.
• The declaration of a virtual function has the following syntax:
virtual return-type func-name(func-params)=0;

5
Abstract classes - Syntax

6
Abstract Class – Example 1
#include
#include <iostream>
<iostream> class
class Abstract2
Abstract2 :: public
public Concrete
Concrete {{
using
using namespace
namespace std;
std; public:
public:
void
void g()=
g()= 0;
0; //
// pure
pure virtual
virtual overrider
overrider
class
class Abstract
Abstract {{ };}; //
// "Abstract2"
"Abstract2" isis abstract
abstract
public:
public:
virtual
virtual void
void f()
f() == 0;
0; //
// pure
pure virtual
virtual int
int main()
main()
};}; //
// "Abstract"
"Abstract" isis abstract
abstract {{
//Abstract
//Abstract a; a; //
// Error:
Error: abstract
abstract class
class
class
class Concrete
Concrete :: public
public Abstract
Abstract {{ Concrete
Concrete b; b; //
// OK
OK
public:
public: Abstract&
Abstract& aa == b; b; //
// OK
OK to
to reference
reference abstract
abstract base
base
void
void f()
f() {}{} //
// non-pure
non-pure virtual
virtual a.f();
a.f(); //
// virtual
virtual dispatch
dispatch toto Concrete::f()
Concrete::f()
virtual
virtual void
void g(){};
g(){}; //
// non-pure
non-pure virtual
virtual //Abstract2
//Abstract2 a2; a2; //
// Error:
Error: abstract
abstract class
class (final
(final overrider
overrider of
of g()
g() isis pure)
pure)
};}; //
// "Concrete"
"Concrete" isis non-abstract
non-abstract return
return 0;0;
}}

7
Abstract Class – Example 2
#include
#include <iostream>
<iostream> //
// definition
definition of
of the
the pure
pure virtual
virtual function
function int
int main()
main()
using
using namespace
namespace std;
std; void
void Abstract::f()
Abstract::f() {{ cout
cout <<
<< "A::f()\n";
"A::f()\n"; }} {{
Concrete
Concrete b;
b;
class
class Abstract
Abstract {{ class
class Concrete
Concrete :: public
public Abstract
Abstract {{ Abstract&
Abstract& aa == b;
b;
public:
public: public:
public: a.f();
a.f();
virtual
virtual void
void f()
f() == 0;
0; //
// pure
pure virtual
virtual void
void f()
f() override
override {{ }}
virtual
virtual void
void g()
g() {}{} //
// non-pure
non-pure virtual
virtual Abstract::f();
Abstract::f();
~Abstract()
~Abstract() {{ //
// OK:
OK: calls
calls pure
pure virtual
virtual function
function Output
g();
g(); //
// OK:
OK: calls
calls Abstract::g()
Abstract::g() }}
//
// f();
f(); //
// undefined
undefined behavior
behavior void
void g()
g() override
override {}{} A::f()
Abstract::f();
Abstract::f(); //// OK:
OK: non-virtual
non-virtual call
call ~Concrete()
~Concrete() {{ A::f()
}} g();
g(); //// OK:
OK: calls
calls Concrete::g()
Concrete::g() A::f()
};}; f();
f(); //
// OK:
OK: calls
calls Concrete::f()
Concrete::f()
}}
};};
8
Abstract Class – Example 2
#include
#include <iostream>
<iostream> class
class Square
Square :: public
public Rectangle{
Rectangle{
using
using namespace
namespace std;
std; public
public ::
Square(float
Square(float side):Rectangle(side,side){}
side):Rectangle(side,side){}
class
class Shape{
Shape{ //Abstract
//Abstract class/
class/ interface
interface char*
char* getName(){return
getName(){return "Square";}
"Square";}
public
public :: };};
float
float width,
width, height;
height; class
class Circle:
Circle: public
public Shape{
Shape{
virtual
virtual float
float getArea()=0;
getArea()=0; //Pure
//Pure virtual
virtual function
function public
public ::
virtual
virtual char*
char* getName(){return
getName(){return "Shape";};
"Shape";}; Circle(float
Circle(float radius){
radius){
};}; width
width == height
height == radius*2;
radius*2;
class
class Rectangle:
Rectangle: public
public Shape
Shape {{ }}
public
public :: float
float getArea(){
getArea(){
Rectangle(float
Rectangle(float w,float
w,float h){
h){ width
width == w;
w; height
height == h;
h; }} return
return ((3.1415/4.0)*width*height);
((3.1415/4.0)*width*height);
float
float getArea(){
getArea(){ return
return width*height;
width*height; }} }}
char*
char* getName(){return
getName(){return "Rectangle";}
"Rectangle";} char*
char* getName(){return
getName(){return "Circle";}
"Circle";}
};}; };};
9
Abstract Class – Example 2(Cont’d)
void
void main()
main() {{ Output
Shape
Shape ** shapes[5];
shapes[5];
Area of Circle is 706.838
shapes[0]
shapes[0] == new
new Circle(15.0);
Circle(15.0); Area of Rectangle is 68
shapes[1]
shapes[1] == new
new Rectangle(34.0,2.0);
Rectangle(34.0,2.0); Area of Circle is 16.6185
shapes[2]
shapes[2] == new
new Circle(2.3);
Circle(2.3); Area of Square is 11.0889
shapes[3]
shapes[3] == new
new Square(3.33);
Square(3.33); Area of Rectangle is 44.4312
shapes[4]
shapes[4] == new
new Rectangle(5.61,7.92);
Rectangle(5.61,7.92);

for
for (int
(int k=0;
k=0; k<5;
k<5; k++)
k++) {{
cout
cout <<<< "Area
"Area of of "<<shapes[k]->getName()
"<<shapes[k]->getName()
<<"
<<" isis "" <<
<< shapes[k]->getArea()
shapes[k]->getArea() <<
<< endl;
endl;
}}

}}
10
Interfaces
• There is no reserved/specific keyword for defining an interface
• An interface is implemented using abstract classes
• An interface is a class that has all its methods defined as pure virtual
methods
• An interface does not have implementation in any of its methods

11
Static Variables
• Static elements are allocated storage only once in a program
lifetime in static storage area.
• Static variables have a scope till the program lifetime
• A static keyword can be used for
• Static variables in a function
• Static class objects
• Static member variable in class
• Static methods in class

12
Static Variables
• Static variables in a Function: When a variable is declared as static,
space for it gets allocated for the lifetime of the program. Even if
the function is called multiple times, space for the static variable is
allocated only once and the value of variable in the previous call
gets carried through the next function call.
• A static variable inside a class must be initialized explicitly using the
class name and scope resolution operator outside the class.
• Non-static class attributes cannot be used in a static method in a
class.

13
Static variables in a function
#include
#include <iostream>
<iostream> int
int main()
main()
using
using namespace
namespace std;
std; {{
for
for (int
(int i=0;
i=0; i<5;
i<5; i++)
i++)
void
void demo()
demo() demo();
demo();
{{ return
return 0;0;
//
// static
static variable
variable }}
static
static int
int count
count == 0;
0;
cout
cout <<
<< count
count <<
<< "" ";
";

//
// value
value isis updated
updated and
and will
will be
be carried
carried to
to next
next Output
//
// function
function calls
calls
count++;
count++; 01234
}}

14
Static class objects
class
class Demo
Demo int
int main()
main()
{{ {{
public:
public: int
int x=0;
x=0;
Demo()
Demo() if(x==0)
if(x==0)
{{ {{ f();
f(); }}
cout
cout <<
<< “Constructor“
“Constructor“ <<
<< endl;
endl; cout
cout <<<< "END“
"END“ <<
<< endl;
endl;
}} }}
~Demo()
~Demo() {{ cout
cout <<
<< “Destructor“
“Destructor“ <<
<< endl;
endl; }}
};};
Output
void
void f()
f()
{{ static
static Demo
Demo obj;
obj; }} Constructor
END
Destructor

15
Static member variables in a class – Ex1
#include<iostream>
#include<iostream> int
int main()
main()
using
using namespace
namespace std;
std; {{
Demo
Demo obj1;
obj1;
class
class Demo
Demo Demo
Demo obj2;
obj2;
{{ obj1.i
obj1.i =2;
=2;
public:
public: obj2.i
obj2.i == 3;
3;
static
static int
int i;i;
cout
cout <<
<< obj1.i<<"
obj1.i<<" "<<obj2.i;
"<<obj2.i;
Demo()
Demo() }}
{{ };};
};}; Output
int
int Demo::i
Demo::i == 1;
1; 33

16
Static member variables in a class – Ex2
#include
#include <iostream>
<iostream> AA B::a;
B::a; //
// aa must
must be
be defined
defined outside
outside the
the class
class
using
using namespace
namespace std;
std;
void
void main()
main()
class
class AA {{
{{ BB b1,
b1, b2,
b2, b3;
b3;
public:
public: AA aa == b1.getA();
b1.getA();
A()
A() {{ cout
cout <<
<< "A's
"A's constructor
constructor called
called "" <<
<< endl;
endl; }} }}
};};
class
class BB Output
{{
static
static AA a;
a; A's constructor called
public:
public: B's constructor called
B()
B() {{ cout
cout <<
<< "B's
"B's constructor
constructor called
called "" <<
<< endl;
endl; }} B's constructor called
static
static AA getA()
getA() {{ return
return a;
a; }} B's constructor called
};};
17
Static methods in a class
#include<iostream>
#include<iostream> int
int main()
main()
using
using namespace
namespace std;
std; {{
//
// invoking
invoking aa static
static member
member function
function
class
class Demo
Demo Demo::sayHello();
Demo::sayHello();
{{
public:
public: Demo
Demo d;d;
d.sayHello();
d.sayHello();
//
// static
static member
member function
function return
return 0;
0;
static
static void
void sayHello()
sayHello() }}
{{
cout
cout <<
<< "Hello
"Hello from
from Static
Static method!“
method!“ <<endl;
<<endl; Output
}}
};}; Hello from Static method!
Hello from Static method!

3 November 2019 [CS213] Abstract Classes and Interfaces 18


Static methods in a class
#include<iostream>
#include<iostream> int
int main()
main()
using
using namespace
namespace std;
std; {{
//
// invoking
invoking aa static
static member
member function
function
class
class Demo
Demo Demo::sayHello();
Demo::sayHello();
{{
public:
public: Demo
Demo d;d;
d.sayHello();
d.sayHello();
//
// static
static member
member function
function return
return 0;
0;
static
static void
void sayHello()
sayHello() }}
{{
cout
cout <<
<< "Hello
"Hello from
from Static
Static method!“
method!“ <<endl;
<<endl; By declaring a function member as static, you
}} make it independent of any particular object of
};}; the class. A static member function can be called
even if no objects of the class exist and
the static functions are accessed using only the
class name and the scope resolution operator ::.
3 November 2019 [CS213] Abstract Classes and Interfaces 19
3 November 2019 [CS213] Abstract Classes and Interfaces 20

You might also like