Katkat

Implement a Shape interface using OOP

Walmart LabsSoftware Engineer · Technical Screen

Last updated

This problem tests your ability to design a robust object-oriented structure using interfaces and concrete class implementations, focusing on polymorphism and data encapsulation.

Problem Statement

Design a system that represents geometric shapes using Object-Oriented Programming principles. You are required to define a common interface Shape and implement two concrete classes: Circle and Rectangle.

Requirements

  1. Define a Shape interface (or abstract base class) with the following methods:

    • area(): returns the area of the shape as a float.
    • perimeter(): returns the perimeter of the shape as a float.
    • getInfo(): returns a string description of the shape.
  2. Implement Circle:

    • Constructor takes radius (float).
    • Ensure radius is non-negative. Throw an exception if it is invalid.
    • Implement the Shape interface.
  3. Implement Rectangle:

    • Constructor takes width and height (floats).
    • Ensure width and height are non-negative. Throw an exception if invalid.
    • Implement the Shape interface.

Example Usage

# Example of expected behavior
shapes = [Circle(5.0), Rectangle(4.0, 6.0)]

for s in shapes:
    print(f"{s.getInfo()}: Area={s.area():.2f}, Perimeter={s.perimeter():.2f}")

# Expected Output:
# Circle (radius: 5.00): Area=78.54, Perimeter=31.42
# Rectangle (width: 4.00, height: 6.00): Area=24.00, Perimeter=20.00

Constraints

  • Use encapsulation by making properties private.
  • Ensure the classes are immutable (properties should not be changeable after initialization).
  • Handle edge cases like zero or negative values in the constructor.

Hints

Hint 1

Define your interface using an Abstract Base Class (ABC) in Python or an interface structure in your preferred language to enforce contract compliance.

Hint 2

Use property decorators or private attributes with getters to ensure the immutability of the shape dimensions.

Hint 3

Validate the input in the constructor before assigning values to ensure your objects are always in a valid state.

Follow-up questions

  • How would you add a `Square` class? Can you reuse the existing `Rectangle` logic to avoid code duplication?
  • If we needed to calculate the total area of a list containing thousands of mixed shapes, how would you optimize that process?
  • What changes would be required to support 3D shapes like a `Sphere` or `Cube`?