Polymorphic Usage
Part of the Object Oriented Programming section of Coddy's C journey — lesson 47 of 61.
Challenge
EasyLet's prove that polymorphism truly works by writing a function that can process any shape through the base Shape* pointer — whether it's a Circle or a Rectangle.
Building on your existing Circle and Rectangle implementations, you'll add a powerful abstraction: a single function that works with any shape type uniformly.
Your project will include these files:
shape.h: Your baseShapeinterface withDrawFuncandAreaFunctypes.circle.handcircle.c: Your Circle implementation from the previous lesson.rectangle.handrectangle.c: Your Rectangle implementation from the previous lesson.shape.c: Implement a new function calledprocess_shapethat takes aShape*pointer. This function should call the shape'sdrawfunction, then call itsareafunction and print the result with 2 decimal places in the formatArea: X.XX.main.c: Demonstrate polymorphism in action. Read a shape type indicator (cfor circle,rfor rectangle) followed by the necessary dimensions. Create the appropriate shape, then pass a pointer to its embeddedShapemember toprocess_shape. The same function handles both types!
Your program will receive either:
cfollowed by a radius value, orrfollowed by width and height values
Example output when the inputs are c and 5.0:
Drawing Circle with radius: 5.00
Area: 78.54Example output when the inputs are r, 4.0, and 3.0:
Drawing Rectangle with width: 4.00 and height: 3.00
Area: 12.00The magic here is that process_shape has no idea whether it's working with a Circle or Rectangle — it only knows about the Shape interface. By casting your concrete shape's embedded Shape member to a Shape*, you can pass any shape type to this single function. This is polymorphism: one function, multiple behaviors based on the actual object type.
Remember to declare process_shape in shape.h so it can be called from main.c.
Try it yourself
#include <stdio.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: Read a char for shape type ('c' for circle, 'r' for rectangle)
// TODO: If 'c', read radius, create a Circle, and call process_shape with its base
// TODO: If 'r', read width and height, create a Rectangle, and call process_shape with its base
return 0;
}
All lessons in Object Oriented Programming
1Modular Programming Basics
Header FilesInclude GuardsSource FilesStatic FunctionsRecap: Modular Calculator4Encapsulation
Opaque Pointers ConceptDefining Opaque StructsGetters and SettersValidation in SettersRecap: Secret Box2Objects and Methods
Structs as ObjectsThe 'Self' PointerConst CorrectnessPointer vs ValueHelper MethodsRecap: Point Manager5Project: Simple Bank Account
Project SetupImplementation of Account3Object Lifecycle
Constructor PatternDestructor PatternStack InitializationDeep CopyRecap: String Wrapper6Inheritance via Composition
Struct EmbeddingThe First Member RuleAccessing Parent MembersUpcastingRecap: Shape Hierarchy9Project: Shape Drawer
Project OverviewCircle Implementation