normidar
normidar

Reputation: 579

Dart how can i override a method that in the extension

what I did:

extension BigDate on DateTime {
  String get locatedWeekDay {
    switch (weekday) {
      case DateTime.sunday:
        return "Sun";
      case DateTime.monday:
        return "Mon";
      case DateTime.tuesday:
        return "Tue";
      ......
      default:
        throw Exception();
    }
  }
}
class JapanDate extends DateTime {
  @override
  String get locatedWeekDay {
    switch (weekday) {
      case DateTime.sunday:
        return "日";
      case DateTime.monday:
        return "月";
      ......
      default:
        throw Exception();
    }
  }
}

now I just run this:

DateTime d = JapanDate(2022, 3, 2);
print(d.locatedWeekDay);

it returns me "Wed" oh, can you help me to fix it?

I tried: to add @override to the get method, add the import to the first line.

Upvotes: 0

Views: 4000

Answers (3)

jamesdlin
jamesdlin

Reputation: 90175

Extension methods are static; they are compile-time syntactic sugar for an equivalent freestanding function. As such, they are wholly dependent on the static type of the variable (whether explicitly declared or inferred), which in your case is DateTime. They cannot be overridden since overrides involve runtime polymorphism.

What you could do instead is:

  1. Create a base class (or mixin) that provides the locatedWeekDay interface.
  2. Make JapanDate derive from that interface.
  3. Make your extension method check if this implements that interface, falling back to a default implementation if it's an ordinary DateTime object.
abstract class HasLocatedWeekDay {
  String get locatedWeekDay;
}

extension BigDate on DateTime {
  String get locatedWeekDay {
    // Type-promotion for `this` is not yet supported.
    // See: <https://github.com/dart-lang/language/issues/1397>
    final self = this;
    if (self is HasLocatedWeekDay) {
      return self.locatedWeekDay;
    }

    switch (weekday) {
      case DateTime.sunday:
        return "Sun";
      case DateTime.monday:
        return "Mon";
      case DateTime.tuesday:
        return "Tue";
      ......
      default:
        throw Exception();
    }
  }
}

class JapanDate extends DateTime implements HasLocatedWeekDay {
  @override
  String get locatedWeekDay {
    switch (weekday) {
      case DateTime.sunday:
        return "日";
      case DateTime.monday:
        return "月";
      ......
      default:
        throw Exception();
    }
  }
}

Upvotes: 2

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63809

There is no locatedWeekDay method on DateTime. Therefore, it can't be overridden, but you can create a custom class extending this or use an extension as you did for BigDate.

To create a custom class, you need to pass data to super class.

class JapanDate extends DateTime {
  JapanDate(int year,
      [int month = 1,
      int day = 1,
      int hour = 0,
      int minute = 0,
      int second = 0,
      int millisecond = 0,
      int microsecond = 0])
      : super(
            year,
            month = month,
            day = day,
            hour = hour,
            minute = minute,
            second = second,
            millisecond = millisecond,
            microsecond = microsecond);

  String get locatedWeekDay {
    switch (this.weekday) {
      case DateTime.sunday:
        return "日";
      case DateTime.monday:
        return "月";
      //....
      default:
        return "N";
    }
  }
}

Now you can use JapanDate class with locatedWeekDay.

  JapanDate d = JapanDate(2022, 3, 7);

  print(d.locatedWeekDay); ///月

About .weekday on DateTime. It is defined as

 external int get weekday;

External Functions An external function is a function whose body is provided separately from its declaration. An external function may be a top-level function (17), a method

You can follow this What does external mean in Dart?

Upvotes: 0

Ante Bule
Ante Bule

Reputation: 2136

Just don't cast it to DateTime leave it as JapanDate and the code above should work as you expect it to.

JapanDate d = JapanDate(2022, 3, 2);
print(d.locatedWeekDay); 

Upvotes: 0

Related Questions