site-www icon indicating copy to clipboard operation
site-www copied to clipboard

Documentation for abstract instance variables

Open olof-dev opened this issue 1 year ago • 2 comments

I only learned from https://github.com/dart-lang/linter/issues/230#issuecomment-1210410944 that one can declare an abstract instance variables of an abstract class via something like abstract String name;. It'd be great if this could be documented in the language tour, under either Abstract classes or Abstract methods.

Here is some suggested text from @eernstg:

An instance variable can be declared abstract by adding the keyword abstract. This has the same effect as declaring an abstract getter and an abstract setter with the same return type respectively parameter type.

Under 'abstract classes', the example could be updated to something like:

// This class is declared abstract and thus
// can't be instantiated.
abstract class AbstractContainer {
  // Define constructors, fields, methods...

  abstract List<Object> children; // Abstract instance variable

  void updateChildren(); // Abstract method.
}

Maybe a simpler type than List<Object> would be better, to avoid thinking about generics and the like.

It'd also be nice if something about the interplay between abstract and final could be mentioned. For example, there seems to be nothing wrong with the following:

abstract class Animal {
  abstract final String name;
}

class Cat implements Animal {
  @override
  String name;
  
  Cat({required this.name});
}

void main() {
  Cat cat = Cat(name: 'Bob');
  cat.name = 'Aisha';
  print(cat.name); // Aisha
}

olof-dev avatar Aug 12 '22 12:08 olof-dev

FYI @mit-mit

domesticmouse avatar Aug 13 '22 14:08 domesticmouse

@leafpetersen WDYT?

mit-mit avatar Aug 15 '22 08:08 mit-mit

@leafpetersen : Ping for visibility.

atsansone avatar May 01 '23 16:05 atsansone

Seems good to me to document this. I'm not sure what is intended by this part though:

It'd also be nice if something about the interplay between abstract and final could be mentioned

leafpetersen avatar May 01 '23 22:05 leafpetersen

Seems good to me to document this. I'm not sure what is intended by this part though:

It'd also be nice if something about the interplay between abstract and final could be mentioned

What does it mean, if anything, to declare an instance variable as abstract final? Does it have any implications for a class implementing the abstract one? The example at the end of https://github.com/dart-lang/site-www/issues/4170#issue-1337163675 suggests 'no'.

olof-dev avatar May 02 '23 06:05 olof-dev

An abstract final T v; declaration has the same effect as T get v;, that is, it's just an abstract getter. You may prefer the variable declaration (even though it's longer) if you wish to emphasize that it is a good fit to implement it using a concrete instance variable (and maybe you want to avoid using a concrete instance variable declaration because some subclasses will implement it as a getter, to avoid allocating unused space). You may also wish to avoid duplicates of T if you are declaring several such getters (abstract final T v1, ... vk;).

The Animal/Cat example here illustrates that there is no problem in overriding an abstract final instance variable with a concrete mutable one: This just means that the getter can be used when the receiver is Animal, but in order to use the setter the receiver type must be at least Cat.

eernstg avatar May 02 '23 07:05 eernstg

Thanks. Something like that summary is precisely what I think would be useful to have in the docs regarding abstract final.

olof-dev avatar May 13 '23 00:05 olof-dev