Marcelo Glasberg
Marcelo Glasberg

Reputation: 30879

In Dart, how can a subclass extend a superclass, having a generic type of the subclass extend a type of the superclass?

This is a Dart Generics question. This question is simpler then it seems, please keep reading.

I have:

The below code doesn't work:

import 'package:flutter/material.dart';

class SomeValue {}

class ExtendedValue extends SomeValue {}

abstract class SomeController<T extends SomeValue> extends ValueNotifier<T> {
  SomeController(T value) : super(value);

  factory SomeController.create() {
    return ExtendedController();
  }
}

class ExtendedController extends SomeController<ExtendedValue> {
  ExtendedController() : super(ExtendedValue());
}

I get the error :

The return type 'ExtendedController' isn't a 'SomeController<T>', as defined by the method 'create'.

in the return ExtendedController(); line.

I then changed it to this:

import 'package:flutter/material.dart';

class SomeValue {}

class ExtendedValue extends SomeValue {}

abstract class SomeController<T extends SomeValue> extends ValueNotifier<T> {
  SomeController(T value) : super(value);

  factory SomeController.create() {
    return ExtendedController();
  }
}

class ExtendedController<S extends ExtendedValue> extends SomeController<S> {
  ExtendedController() : super(ExtendedValue());
}

Still doesn't work, but now I get another error: The constructor returns type 'ExtendedValue' that isn't of expected type 'S'.

this time in the super(ExtendedValue()); line.

Upvotes: 7

Views: 4773

Answers (2)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657228

An explicit cast fixes it:

  factory SomeController.create() {
    return ExtendedController() as SomeController<T>;
  }

https://groups.google.com/a/dartlang.org/forum/#!topic/misc/bVRHdagR8Tw

alternatively you can use

  static create() {
    return ExtendedController() as SomeController<T>;
  }

With optional new there isn't a difference anymore.

Upvotes: 3

Dinesh Balasubramanian
Dinesh Balasubramanian

Reputation: 21728

Let's take the first error: The return type 'ExtendedController' isn't a 'SomeController<T>', as defined by the method 'create'.

It is telling ExtendedController is not an expected return type from create method as per definition.

create is a factory method here it and expects the return type to be SomeController

factory SomeController.create() {
  return SomeController();
}

We cannot change like this also as SomeController is an abstract class. So, I moved the factory method to ExtendedController.

class SomeValue {}

class ExtendedValue extends SomeValue {}

abstract class SomeController<T extends SomeValue> extends ValueNotifier<T> {
  SomeController(T value) : super(value);
}

class ExtendedController extends SomeController {
  ExtendedController(ExtendedValue value) : super(value);

  factory ExtendedController.create() {
    return ExtendedController(ExtendedValue());
  }
}

Hope my explanation helps up to some extent.

Upvotes: 1

Related Questions