Warning: foreach() argument must be of type array|object, bool given in /var/www/html/web/app/themes/studypress-core-theme/template-parts/header/mobile-offcanvas.php on line 20

Many programs written with inheritance could be written with composition instead, and vice versa. Rewrite class BasePlusCommissionEmployee of the CommissionEmployeeBasePlusCommissionEmployee hierarchy to use composition rather than inheritance. After you do this, assess the relative merits of the two approaches for designing classes commissionEmployee and BasePlusCommissionEmployee, as well as for object-oriented programs in general. Which approach is more natural? Why?

Short Answer

Expert verified
Composition provides flexibility and simplicity in class design, making it a preferred approach in many cases over inheritance.

Step by step solution

01

Understand Inheritance

In inheritance, a class (child class) is derived from another class (parent class). The `BasePlusCommissionEmployee` class inherits properties from the `CommissionEmployee` class. It adds a base salary feature on top of commission calculations.
02

Problem with Inheritance

Using inheritance can lead to issues if `BasePlusCommissionEmployee` is considered to logically not a 'kind of' `CommissionEmployee`. Inheritance results in a tightly coupled relationship that makes code difficult to modify or test.
03

Understanding Composition

Composition involves including an instance of one class (part class) within another (whole class). For `BasePlusCommissionEmployee`, instead of inheriting from `CommissionEmployee`, it includes a `CommissionEmployee` object as an attribute.
04

Rewriting with Composition

Modify `BasePlusCommissionEmployee` to contain a private `CommissionEmployee` object. Provide methods within `BasePlusCommissionEmployee` to access `CommissionEmployee`'s functionalities and add its own logic for handling the base salary.
05

Create Composition Structure

```python class CommissionEmployee: # existing implementation class BasePlusCommissionEmployee: def __init__(self, commission_employee, base_salary): self.commission_employee = commission_employee self.base_salary = base_salary def earnings(self): return self.base_salary + self.commission_employee.earnings() # additional methods as required ``` In this structure, `BasePlusCommissionEmployee` uses an instance of `CommissionEmployee` and separate logic for base salary.
06

Assessing Relative Merits of Both Approaches

Inheritance promotes a hierarchy where `BasePlusCommissionEmployee` is viewed as a type of `CommissionEmployee`, suitable when there is a true 'is a' relationship. However, composition is more flexible and better suited for cases where `BasePlusCommissionEmployee` 'has a' `CommissionEmployee`, providing easier maintenance and scalability.
07

Conclusion on Preferred Approach

Composition is often a more natural approach in scenarios where components of a program need to be reusable and not strongly hierarchically related. It allows for greater flexibility and adaptability in design, reducing dependencies.

Unlock Step-by-Step Solutions & Ace Your Exams!

  • Full Textbook Solutions

    Get detailed explanations and key concepts

  • Unlimited Al creation

    Al flashcards, explanations, exams and more...

  • Ads-free access

    To over 500 millions flashcards

  • Money-back guarantee

    We refund you if you fail your exam.

Over 30 million students worldwide already upgrade their learning with Vaia!

Key Concepts

These are the key concepts you need to understand to accurately answer the question.

inheritance in C++
Imagine you have a family tree, where characteristics are passed down from one generation to the next. In the world of programming, inheritance works similarly. This concept allows a new class, called a derived or child class, to acquire properties and behavior from an existing class, known as the base or parent class. In C++, inheritance is a cornerstone of object-oriented programming (OOP), enabling classes to build on one another.

The purpose of inheritance is to promote code reusability and establish a logical hierarchy between classes. For example, in a payroll system, a `BasePlusCommissionEmployee` could inherit from a `CommissionEmployee`. This means `BasePlusCommissionEmployee` will automatically have the characteristics of a `CommissionEmployee`, such as calculating commissions. However, inheritance suggests a strong "is a" relationship, implying that a `BasePlusCommissionEmployee` is a type of `CommissionEmployee`, which may not always be logical or appropriate.
  • Pros: Simplifies the code by reducing redundancy, easy to understand relationships between objects.
  • Cons: Can introduce rigidity due to tight coupling, which makes future changes and testing difficult.
In essence, while inheritance offers simplicity and elegance in some situations, it should be used judiciously to avoid complications in code maintenance and extension.
composition in C++
Consider composition like putting together a puzzle to form a complete picture. In C++, composition involves creating classes that contain instances of other classes as members. This design principle focuses on the "has a" relationship rather than "is a".

For instance, instead of a `BasePlusCommissionEmployee` inheriting from `CommissionEmployee`, it can include a `CommissionEmployee` as a member object. This means that `BasePlusCommissionEmployee` uses the services of `CommissionEmployee` to perform its calculations but retains its own identity and can add new functionalities independently. With this approach, the two classes are not tightly bound, allowing changes in one without affecting the other significantly.
  • Pros: Greater flexibility, easier to maintain and extend, components are more reusable.
  • Cons: Can lead to more verbose code as interactions between class members need explicit handling.
By utilizing composition, programmers can build robust and scalable systems where components can be easily modified or replaced, fostering more adaptable code structures.
class design concepts
Designing classes is akin to constructing a building plan, where every element has a specific role and purpose. In object-oriented programming, classes serve as blueprints for creating objects, encapsulating data and functionalities.

An effective class design not only tackles current needs but anticipates future adjustments and extensions. Here are some guiding principles:
  • Encapsulation: Enclosing data and methods within a class, restricting direct access from outside.
  • Single Responsibility: Each class should have a single purpose or responsibility, ensuring clarity and simplicity.
  • Open/Closed Principle: Design classes that are open for extension but closed for modification, enhancing adaptability without altering existing codebase.
  • DRY (Don't Repeat Yourself): Avoid redundancy by ensuring each piece of knowledge has a single, unambiguous place within the system.
Balancing inheritance and composition in class design is crucial. While inheritance provides clarity in "is a" hierarchies, composition offers flexibility in "has a" relationships. Making informed decisions about which to use based on context and requirements leads to more maintainable and scalable code nests.

One App. One Place for Learning.

All the tools & learning materials you need for study success - in one app.

Get started for free

Most popular questions from this chapter

Fill in the blanks in each of the following statements: a. _______ is a form of software reuse in which new classes absorb the data and behaviors of existing classes and embellish these classes with new capabilities. b. A base class's _______ members can be accessed only in the base- class definition or in derived-class definitions. c. \(\ln a(n)\) _______ relationship, an object of a derived class also can be treated as an object of its base class. d. \(\ln a(n)\) _______relationship, a class object has one or more objects of other classes as members. e. In single inheritance, a class exists in a(n) _______ relationship with its derived classes. f. A base class's _______ members are accessible within that base class and anywhere that the program has a handle to an object of that base class or to an object of one of its derived classes. g. \(A\) base class's protected access members have a level of protection between those of public and _______ access. h. \(C++\) provides for _______ which allows a derived class to inherit from many base classes, even if these base classes are unrelated. i. When an object of a derived class is instantiated, the base class's _______ is called implicitly or explicitly to do any necessary initialization of the base-class data members in the derived-class object. J. When deriving a class from a base class with public inheritance, public members of the base class become _______ members of the derived class, and protected members of the base class become _______ members of the derived class. k. When deriving a class from a base class with protected inheritance, public members of the base class become _______ members of the derived class, and protected members of the base class become _______ members of the derived class.

State whether each of the following is true or false. If \(f a / s e,\) explain why. a. Base-class constructors are not inherited by derived classes. b. A has-a relationship is implemented via inheritance. c. \(A\) car class has an \(i s\) -a relationship with the steeringwheel and Brakes classes. d. Inheritance encourages the reuse of proven high-quality software. e. When a derived-class object is destroyed, the destructors are called in the reverse order of the constructors.

(Account Inheritance Hierarchy) Create an inheritance hierarchy that a bank might use to represent customers' bank accounts. All customers at this bank can deposit (i.e., credit) money into their accounts and withdraw (i.e., debit) money from their accounts. More specific types of accounts also exist. Savings accounts, for instance, earn interest on the money they hold. Checking accounts, on the other hand, charge a fee per transaction (i.e.. credit or debit). Create an inheritance hierarchy containing base class account and derived classes savingsAccount and checkingAccount that inherit from class Account. Base class Account should include one data member of type double to represent the account balance. The class should provide a constructor that receives an initial balance and uses it to initialize the data member. The constructor should validate the initial balance to ensure that it is greater than or equal to \(\theta . \theta .\) If not, the balance should be set to \(\theta . \theta\) and the constructor should display an error message, indicating that the initial balance was invalid. The class should provide three member functions. Member function credit should add an amount to the current balance. Member function debit should withdraw money from the account and ensure that the debit amount does not exceed the account's balance. If it does, the balance should be left unchanged and the function should print the message "Debit amount exceeded account balance." Member function getBalance should return the current balance. Derived class savingsAccount should inherit the functionality of an Account, but also include a data member of type double indicating the interest rate (percentage) assigned to the Account. SavingsAccount's constructor should receive the initial balance, as well as an initial value for the SavingsAccount's interest rate. SavingsAccount should provide a public member function calculateInterest that returns a double indicating the amount of interest earned by an account. Member function calculateInterest should determine this amount by multiplying the interest rate by the account balance. [Note: SavingsAccount should inherit member functions credit and debit as is without redefining them.] Derived class checkingAccount should inherit from base class Account and include an additional data member of type double that represents the fee charged per transaction. CheckingAccount's constructor should receive the initial balance, as well as a parameter indicating a fee amount. Class CheckingAccount should redefine member functions credit and debit so that they subtract the fee from the account balance whenever either transaction is performed successfully. CheckingAccount's versions of these functions should invoke the base-class account version to perform the updates to an account balance. CheckingAccount's debit function should charge a fee only if money is actually withdrawn (i.e., the debit amount does not exceed the account balance). [Hint: Define Account's debit function so that it returns a bool indicating whether money was withdrawn. Then use the return value to determine whether a fee should be charged.] After defining the classes in this hierarchy, write a program that creates objects of each class and tests their member functions. Add interest to the SavingsAccount object by first invoking its calculateInterest function, then passing the returned interest amount to the object's credit function.

The world of shapes is much richer than the shapes included in the inheritance hierarchy of Fig, \(12.3 .\) Write down all the shapes you can think ofboth two- dimensional and three-dimensionaland form them into a more complete Shape hierarchy with as many levels as possible. Your hierarchy should have base class shape from which class Two imensionalshape and class ThreeDimensionalshape are derived. [Note: You do not need to write any code for this exercise.] We will use this hierarchy in the exercises of Chapter 13 to process a set of distinct shapes as objects of base-class shape. (This technique, called polymorphism, is the subject of Chapter \(13 .\).

Some programmers prefer not to use protected access because they believe it breaks the encapsulation of the base class. Discuss the relative merits of using protected access vs. using private access in base classes.

See all solutions

Recommended explanations on Computer Science Textbooks

View all explanations

What do you think about this solution?

We value your feedback to improve our textbook solutions.

Study anywhere. Anytime. Across all devices.

Sign-up for free