Search code examples
flutterdartflutter-getx

Dart error: Not a valid override, don't override fields


In my Flutter app I have a lot of different controllers doing similar or the same things. So I figured I could create a main-controller and extend all the other controllers to this one, which would save me a ton of duplicate code. Something like this:

abstract class Vehicle {
  final int seats;
  const Vehicle({required this.seats});
}

class Car extends Vehicle {
  final Color color;
  Car({required int seats, required this.color}) : super(seats: seats);
}

class Bus extends Vehicle {
  Bus({required int seats}) : super(seats: seats);
}

/*-------*/

abstract class VehicleController extends GetxController {
  Rx<Vehicle> vehicle = Bus(seats: 0).obs;

  void loadVehicle(Vehicle newVehicle) {}

  void printSeats() => print(vehicle.value.seats.toString());
}

class CarController extends VehicleController {
  @override
  Rx<Car> vehicle = Car(seats: 4, color: Colors.red).obs; // Error: not a valid override, Error: don't override fields.

  @override
  void loadVehicle(Car newVehicle) { // Error: not a valid override
    print(newVehicle.color);
  }

  void doSomeThingThatVehicleControllerCantDo() {
    print(vehicle.value.color);
  }
}

class BusController extends VehicleController {
  @override
  Rx<Bus> vehicle = Bus(seats: 50).obs; // Error: not a valid override, Error: don't override fields.
}

/*-------*/

void main() {
  CarController().printSeats();
  BusController().printSeats();
  CarController().doSomeThingThatVehicleControllerCantDo();
}

But Dart doesn't allow me to override a field and doesn't allow me to override with a different object - even if it extends the object it wants. Is there a way of doing this? (Sorry, I'm not an experienced programmer)


Solution

  • First, use the constructor to init the field rather than overriding. Second, use a generic template like the bellow for simplifying the code.

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    abstract class Vehicle {
      final int seats;
    
      const Vehicle({required this.seats});
    }
    
    class Car extends Vehicle {
      final Color color;
    
      Car({required int seats, required this.color}) : super(seats: seats);
    }
    
    class Bus extends Vehicle {
      Bus({required int seats}) : super(seats: seats);
    }
    
    /*-------*/
    
    abstract class VehicleController<T extends Vehicle> extends GetxController {
      Rx<Vehicle> _vehicle;
    
      Rx<T> get vehicle => _vehicle as Rx<T>;
    
      VehicleController({Rx<Vehicle>? vehicle}) : _vehicle = vehicle ?? Bus(seats: 0).obs;
    
      void loadVehicle(Vehicle newVehicle) {}
    
      void printSeats() => print(vehicle.value.seats.toString());
    }
    
    class CarController extends VehicleController<Car> {
      CarController() : super(vehicle: Car(seats: 4, color: Colors.red).obs);
      
      @override
      void loadVehicle(Vehicle newVehicle) {
        if (newVehicle is Car) {
          print(newVehicle.color);
        }
      }
    
      void doSomeThingThatVehicleControllerCantDo() {
        print(vehicle.value.color);
      }
    }
    
    class BusController extends VehicleController<Bus> {
      BusController() : super(vehicle: Bus(seats: 50).obs);
    }
    
    /*-------*/
    
    void main() {
      CarController().printSeats();
      BusController().printSeats();
      CarController().doSomeThingThatVehicleControllerCantDo();
    }