0% found this document useful (0 votes)
2 views22 pages

Understanding Inheritance in OOP

Chapter 2 covers Object-Oriented Design, focusing on inheritance, overriding functions, templates, and exceptions in C++. It explains how subclasses inherit attributes and methods from parent classes, the benefits of using inheritance, and provides examples of function and class templates. Additionally, it discusses how to handle exceptions in C++ using try, throw, and catch keywords, along with the importance of defining error classes.

Uploaded by

hbn3142
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views22 pages

Understanding Inheritance in OOP

Chapter 2 covers Object-Oriented Design, focusing on inheritance, overriding functions, templates, and exceptions in C++. It explains how subclasses inherit attributes and methods from parent classes, the benefits of using inheritance, and provides examples of function and class templates. Additionally, it discusses how to handle exceptions in C++ using try, throw, and catch keywords, along with the importance of defining error classes.

Uploaded by

hbn3142
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

CHAPTER 2:

OBJECT-ORIENTED DESIGN
1

Dr. Mohamad Kassab


2
INHERITANCE
INHERITANCE
▪ It is when a class “inherits” attributes and methods from another class.
o Parent / Superclass / base class - the class being inherited from
o Child / Subclass/derived class - the class inheriting from another
▪ A subclass cannot access the private members of its parent, but it can
access members that are public or members that are protected.
Example:
//Parent class // The class “Programmer” is a child class
class Employee { that inherits the members of “Employee”
public: class Programmer: public Employee {
int getSalary() { return salary; } public:
protected: / string programming_language;
/*Protected members are public to void setSalary(int s) { salary = s; }
classes derived from Employee, and /* see how method can access salary
private to all other classes */ because it is a protected member! */
int salary; };
}; 3
CODE DEMONSTRATION

▪ 1. Access file “Inheritence”


▪ 2. write subclass
“Programmer” which is a
subclass of “Employee”.
▪ De-comment the lines in the
main function and execute the
code

4
OVERRIDING INHERITED FUNCTIONS
▪ You can override an inherited method by redefining it in the child class.
Example:
class Animal {// parent class
public:
void animalSound() {
cout << "The animal makes a sound \n";
}
};

class Dog: public Animal { // Now, class “Dog” inherits “Animal”


public:
void animalSound() {
cout << "The dog says: woof woof \n";
}
};
5
Why do we need inheritance?
Suppose you want to define two classes:
class Faculty { class Student {
private: private:
string name; string name;
string idNum;
some parts are string idNum;
string rank; repeated!! string major;
public: public:
Faculty( string n, string i, string r) Student( string n, string i, string r)
void print(); void print();
string getName(); string getName();
string getRank(); void changeMajor(string m);
} }
Faculty::Faculty( string n, string i, string r) Student::Student( string n, string i, string m)
: name(n), idNum(i), rank(r) { : name(n), idNum(i), major(m) {
} }
void Faculty::print( ) { void Student::print( ) {
cout << name; cout << name;
cout << idNum; cout << idNum;
cout << rank; cout << major;
} }
string Faculty::getName( ) { return name; } string Student::getName( ) { return name; }
void Faculty::getRank( ) { return rank; } void Student::changeMajor( string m ) {
major = m; 6
}
Benefits of using inheritance
Create a base class containing the common members, and two derived classes

class Person { Person::Person( string n, string i)


private: : name(n), idNum(i) {
string name; }
string idNum; void Person::print( ) {
public: cout << name;
Person(string n, string i) cout << idNum;
void print(); }
string getName(); string Person::getName( ) { return name; }
}
We called the constructor of
A faculty A student Person in the initializer list of
is a person is a person the constructor of Student

Student::Student(string n, string i, string m)


class Faculty : public Person{ class Student : public Person{ : Person(n,i), major(m) {
private: private: }
string rank; string major; void Student::print( ) {
public: public: Person::print();
Faculty(string n, string i, string r); Student(string n, string i, string m); cout << major;
void print(); void print(); }
void getRank(); void changeMajor(string m); void Student::changeMajor( string m ) {
} } major = newMajor ;
} 7
CODE DEMONSTRATION
▪ 1. Access file “overriding”
▪ 2. write subclass “student”
which is a subclass of “Person”
with the following:
▪ Private attribute major
▪ Constructor method
▪ Pint method
▪ Change major method
▪ De-comment the lines in the
main function and execute the
code
8
9
TEMPLATES
FUNCTION TEMPLATE
How do we avoid repeat the same code over and over for different types?

void function_1 ( int x, int y ){ void function_2 ( double x, double y ){ void function_3 ( float x, float y ){
// code goes here… /* The same code goes here, but /* The same code goes here, but
} for “double” instead of “int” */ for “float” instead of “int” */
} }

Solution: Instead of writing the above three versions, just write a single template:

template <typename T> void myFunction( T x, T y ){


// code goes here…
}

You can have more than one typename: template <typename T, typename V, …>
T and V can be used as if they were datatypes.
Let’s see an example… 10
FUNCTION TEMPLATE
void min_1(int x, int y){ void min_2(double x, double y){ void min_3(float x, float y){
if (x<y) cout << x; if (x<y) cout << x; if (x<y) cout << x;
else cout << y; else cout << y; else cout << y;
} } }

Instead of writing the above three versions, write a single template:


template <typename T> void minimum(T x, T y){
if (x<y) cout << x;
else cout << y;
}

Now, calling the function is straight forward, for example, you may write:
int i = 5; int j = 7; minimum(i,j); // this will print 5
double x = 3.67; double y = 9.7881; minimum(x,y); // this will print 3.67
float a = 1.5; float b = 2.5; minimum(a,b); // this will print 1.5 11
CLASS TEMPLATE
▪ Similar to a function template declaration, it starts with
the keyword template followed by < > for the types
Syntax:
template <typename T, typename V, ...>
class MyClass
{ private:
V var; /* You can treat V like
any regular type */
public:
T functionName(V arg);
/* You can treat T and V like
any regular type */
};

Let’s see a detailed example… 12


CLASS TEMPLATE
▪ An example of a class template…

template <typename T> int main() {


class Calculator {
private: Calculator<int> x(2, 1);
T num1, num2; cout << “The integer numbers are:";
public: [Link]();
Calculator(T n1, T n2){
num1 = n1; Calculator<double> y(2.498, 1.2775);
num2 = n2; cout << “The double numbers are:";
} [Link]();
void displayNumbers(){
cout << num1 << " and " << num2; return EXIT_SUCCESS;
} }
};

13
CODE DEMONSTRATION

▪ 1. Access file “templates”


▪ 2. Run the code.

14
15
EXCEPTIONS
EXCEPTIONS
• When executing C++ code, different errors can occur, e.g., coding errors made by
the programmer, or user errors such as providing a wrong input
• To specify what happens when certain errors are made, use “exceptions”. For this,
you need 3 keywords: try, throw, and catch.
• Here is a syntax example (we’ll explain in more detail in the next slides):
try {
// some code can go here...
if( error_happens )
throw( exception_object );
// some code can go here...
}
catch ( exception_object ) {
// write here what you want to happen when error occurs
}
• We need to create an object that will be “thrown” when there is an error! 16
EXCEPTIONS
• First, we need to define a class for each type of error. Then, we will be
able to throw an object of that class if an error occurs!
• Suppose we define a generic class called MathException that we will use
whenever there is a math-related error. A possible definition could be:
class MathException {
private:
string errMsg; // The error message that is stored in the object
public:
/* A constructor. Remember, “: errMsg(err)” is an initializer list
that sets: errMsg = err; */
MathException(const string& err) : errMsg(err) { }

// A method used to retrieve the error message stored in the object


string getError() { return errMsg; }
}; 17
EXCEPTIONS
• Now we can throw an object of MathException if we detect a math-related error

try {

// some code can go here...

if( z == 0 ){
throw( MathException( “Can’t divide by zero!” ) ); /* Notice how, inside the “throw”
statement, we created an object by calling the constructor of “MathException” */
}else
x = y/z;

// some code can go here...

}
catch ( MathException& obj ) {
cout << [Link](); /* This line will print the error message stored in the
object called “obj” */
}
18
CODE
DEMONSTRATION -4

19
EXCEPTIONS
• A function may specify the exceptions it throws. Here is an example:
void calculator() throw(ZeroDivide, NegativeRoot) {
// function body goes here ...
}

• You will see many examples in the book where a class has a function (i.e., a method)
that specifies the exception it throws, without worrying about the details of what
will happen when that exception is caught!

• This is mainly meant to emphasize that you should look out for, and “catch”, any
errors that may happen, but the book never provides additional details about the
exception object itself, since this is not important for understanding data structures!

• Let us consider an example taken from Chapter 3 of the textbook…


20
21
REMINDER!
PLAGIARISM IN LABS & ASSIGNMENTS
• Please do NOT copy code from each other. f you do so, you
WILL be caught!
• If you copy, but change the variable names, or remove comments,
or try to modify the copied code; you’ll still be caught! We easily
catch such attempts all the time!!

• The penalty for plagiarism (in assignments, quizzes, homework,


or exams) is one of the following (whichever is higher):
• 10% of the full course grade
• The full grade of assignment/quiz/homework/exam.
22

Common questions

Powered by AI

Class templates and function templates both provide a way to create generic components, but they differ in their usage. Class templates allow for the creation of template classes that can handle data of any type, meaning attributes and methods within the class can operate on various data types. Function templates, on the other hand, are used solely to create generic functions that execute operations on various data types without duplicating code for each type. A class template can encapsulate multiple functions and members that operate on generic types, whereas a function template is limited to the operations defined within a particular function .

Method overriding allows a subclass to provide a specific implementation for a method that is already defined in its superclass. This is useful when the behavior of a method in a subclass needs to be different from the behavior in the superclass. It improves software design by offering polymorphic behaviors which facilitate code that is flexible and easy to extend and maintain .

The choice between private, protected, and public inheritance has significant implications on class accessibility. Public inheritance signifies a "is-a" relationship where the public and protected members of the base class become part of the interface of the derived class. Protected inheritance makes the public and protected base members protected in derived classes, limiting use outside the class hierarchy. Private inheritance restricts access further, making inherited members private. The choice affects encapsulation, flexibility, and the potential misuse of class internals, impacting ease of maintenance and scalability .

Exceptions can enhance robustness by providing structured error handling that separates normal code execution from error handling code, which mitigates the risk of unexpected behavior during execution. They enable precise control over error responses and recovery, allowing a program to maintain stability through error isolation and customized error messages. This leads to reliable applications that respond predictably to errors, reducing the chance of crashes or data corruption .

Function templates contribute to abstraction by allowing programmers to define algorithms that operate across different types without specifying the exact types involved, thereby abstracting away the type-specific details. This leads to code that is more general and reusable, focusing on the logic of the function rather than the specifics of each type. It allows the developer to apply the same logic to a wide range of types, enhancing the code's flexibility and maintainability .

Exceptions should be used to handle errors that occur during program execution that are not part of regular program flow. They are particularly useful for managing unexpected situations, like input errors from users or calculating errors such as division by zero. Using exceptions allows a separation between error handling and the main program logic, ensuring that code is cleaner and easier to read .

Inheritance is beneficial because it allows for code reuse, reducing redundancy by enabling new classes to inherit attributes and methods from existing ones. This means that common functionality does not need to be repeated across different classes, making the codebase simpler and more maintainable .

Protected members in a class allow access to them by that class and its subclasses, but not by other classes. This ensures that while the subclass can use and extend the functionality of a superclass by accessing these members, they remain hidden from the outside world, which encapsulates the internal implementation. This capability allows for more controlled and secure subclassing .

Incorrect implementation of inheritance can lead to several challenges. If inheritance hierarchies are poorly designed, it can cause issues such as code bloat, where subclasses unnecessarily inherit methods they do not use, leading to inefficiencies. Over-reliance on inheritance can make code difficult to modify or extend if the parent class changes, as changes can cascade to all children. Misusing inheritance for code reuse—as opposed to establishing true is-a relationships—can lead to fragile designs that are hard to understand and maintain .

Templates allow the creation of generic functions and classes that can work with any data type. This means that instead of writing similar code for different data types (such as int, float, and double), a single template can be defined to handle all of them, thus preventing code repetition and reducing redundancy in the codebase. For instance, a single template function can handle different types of minimum calculations without separate implementations .

You might also like