Overriding and Dynamic Dispatch

Overriding and Dynamic Dispatch

About

  • Method Overriding: Subclass redefinition
  • Dynamic Dispatch: Runtime method selection
  • @override: Explicit annotation
  • Performance: Virtual call overhead

Main Topics

  1. Basic Overriding

    • Definition: Subclass implementation

    • Example:

      class Vehicle {
        void move() => print('Moving');
      }
      
      class Car extends Vehicle {
        @override
        void move() => print('Driving');
      }
  2. Virtual Methods

    • Definition: Default in Dart
    • Example:
      Vehicle v = Car();
      v.move(); // "Driving" (virtual call)
  3. @override Annotation

    • Definition: Explicit intent
    • Example:
      @override
      void dispose() {
        // Cleanup
        super.dispose();
      }
  4. Super Calls

    • Definition: Parent implementation
    • Example:
      @override
      void initState() {
        super.initState();
        // Additional setup
      }
  5. Performance Considerations

    • Definition: Virtual call costs
    • Example:
      // Final methods can be optimized
      // Small overhead per virtual call

How to Use

  • Extension: Customize parent behavior
  • Annotation: Always use @override
  • Super: Call parent when appropriate
  • Design: Limit deep hierarchies

How It Works

  1. VTable: Method lookup table
  2. Dispatch: Runtime type check
  3. Optimization: JIT specialization
  4. Inlining: Possible for final

Example:

abstract class Logger {
  void log(String message);
}

class ConsoleLogger extends Logger {
  @override
  void log(String message) {
    print('[Console] $message');
  }
}

class FileLogger extends Logger {
  @override
  void log(String message) {
    // Write to file
  }
}

void logMessage(Logger logger, String msg) {
  logger.log(msg); // Dynamic dispatch
}

Conclusion

Method overriding and dynamic dispatch form the foundation of runtime polymorphism in Dart, enabling flexible and extensible class hierarchies. The explicit @override annotation and clear super call syntax help maintain robust code while the runtime system efficiently handles virtual method calls.