Juan Antonio Tubío
Juan Antonio Tubío

Reputation: 1191

Is there an alternative way of implementing inheritance of static methods in Dart?

I'm very new with dart.

I have some enums like HairType, some Classes that simulates enums with a random() method like: SkinColors and ShortHair.

The class SkinColors have also a values property to simulate a List so I can use both: SkinColors.colors or SkinColors.values.

Everything was working fine:

import 'dart:math';
import 'package:flutter/painting.dart';

void main(){
  print(SkinColors.tanned);
  print(SkinColors.values);
  print(SkinColors.colors);
  print(SkinColors.random());
  print(ShortHair.dreads01);
  print(ShortHair.values);
  print(ShortHair.random());
}

class SkinColors {
  // This class is not meant to be instantiated or extended; this constructor
  // prevents instantiation and extension.
  // ignore: unused_element
  SkinColors._();

  static const Color tanned = Color(0xFFFD9841);
  static const Color pale = Color(0xFFFFDBB4);
  static const Color brown = Color(0xFFD08B5B);

  static const List<Color> colors = <Color>[
    tanned,
    pale,
    brown,
  ];

  static List<Color> get values => colors;

  static random() => values[Random().nextInt(values.length)];
}

enum HairType {
  bigHair,
  bob,
  bun,
  dreads01,
  dreads02,
  frizzle,
}


class ShortHair {
  // This class is not meant to be instantiated or extended; this constructor
  // prevents instantiation and extension.
  // ignore: unused_element
  ShortHair._();

  static const HairType dreads01 = HairType.dreads01;
  static const HairType dreads02 = HairType.dreads02;
  static const HairType frizzle = HairType.frizzle;

  static const List<HairType> values = <HairType>[
    dreads01,
    dreads02,
    frizzle,
  ];

  static random() => values[Random().nextInt(values.length)];
}

Then, I decided to move redundant code (I have more similar classes in my real code) random() and get values to a common place. So, I created two abstract class, BaseEnum with the random() method and ColorsEnum with get values:

import 'dart:math';
import 'package:flutter/painting.dart';

void main(){
  print(SkinColors.tanned);
  print(SkinColors.values);
  print(SkinColors.colors);
  print(SkinColors.random());
  print(ShortHair.dreads01);
  print(ShortHair.values);
  print(ShortHair.random());
}

abstract class BaseEnum {
  static const values = [];

  static random() => values[Random().nextInt(values.length)];
}

abstract class ColorsEnum implements BaseEnum {
  static const List<Color> colors = <Color>[];

  static List<Color> get values => colors;
}

class SkinColors implements ColorsEnum {
  // This class is not meant to be instantiated or extended; this constructor
  // prevents instantiation and extension.
  // ignore: unused_element
  SkinColors._();

  static const Color tanned = Color(0xFFFD9841);
  static const Color pale = Color(0xFFFFDBB4);
  static const Color brown = Color(0xFFD08B5B);

  static const List<Color> colors = <Color>[
    tanned,
    pale,
    brown,
  ];
}

enum HairType {
  bigHair,
  bob,
  bun,
  dreads01,
  dreads02,
  frizzle,
}


class ShortHair {
  // This class is not meant to be instantiated or extended; this constructor
  // prevents instantiation and extension.
  // ignore: unused_element
  ShortHair._();

  static const HairType dreads01 = HairType.dreads01;
  static const HairType dreads02 = HairType.dreads02;
  static const HairType frizzle = HairType.frizzle;

  static const List<HairType> values = <HairType>[
    dreads01,
    dreads02,
    frizzle,
  ];
}

Something is wrong with this implementation because I'm getting this errors:

line 6 • The getter 'values' isn't defined for the type 'SkinColors'. (SkinColors.values)
line 8 • The method 'random' isn't defined for the type 'SkinColors'. (SkinColors.random())
line 11 • The method 'random' isn't defined for the type 'ShortHair'. (ShortHair.random())

It's supposed that both method should be inherited by classes SkinColors and ShortHair.

Edit: @julemand101 give me some light in the comments. So, now that I know that I can't inherit static methods, my new question is: How can I give the same random() method to all my clases without repeating the same code in every class?

Answer: It seems that there's no way to do what I want to do in Dart. But @KirillBubochkin give in his answer a nice way of doing something similar with extensions

Upvotes: 0

Views: 296

Answers (1)

Kirill Bubochkin
Kirill Bubochkin

Reputation: 6343

I would probably go with an extension on a List:

extension RandomElement<T> on List<T> {
  T random() => this[Random().nextInt(length)];
}

And then you can use it like this:

SkinColors.values.random();
ShortHair.values.random();

Upvotes: 1

Related Questions