简体   繁体   中英

Dart 2.0.0 Access to the variable of a class that extends another

I have these classes (as @KevinMoore showed here ):

import 'dart:math';

class Photo {
  final double area;

  // This constructor is library-private. So no other code can extend
  // from this class.
  Photo._(this.area);

  // These factories aren't needed – but might be nice
  factory Photo.rect(double width, double height) => new RectPhoto(width, height);
  factory Photo.circle(double radius) => new CirclePhoto(radius);
}

class CirclePhoto extends Photo {
  final double radius;

  CirclePhoto(this.radius) : super._(pi * pow(radius, 2));
}

class RectPhoto extends Photo {
  final double width, height;

  RectPhoto(this.width, this.height): super._(width * height);
}

My question is: if I create a Photo object in this way: Photo photo = new CirclePhoto(15.0, 10.0); , how can I get the radius from photo object? Can I make the radius variable private and get it with a getter?

Thank you.

You need a get method :

class Rectangle {
  num left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // Define two calculated properties: right and bottom.
  num get right => left + width;
  set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}

void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

Doc: https://www.dartlang.org/guides/language/language-tour

You just need to cast the value to a CirclePhoto to access the radius value. A Photo does not have a radius, so if you do:

Photo photo = new CirclePhoto(15.0);
print(photo.radius); // Compile-time error, Photo has no "radius"

you get an error, but if you do:

Photo photo = new CirclePhoto(15.0);
print((photo as CirclePhoto).radius);

it works.

This performs a down-cast from Photo to CirclePhoto . The static type system cannot tell that this is safe (some photos are not circle-photos), so it checks at run-time. If the photo isn't actually a CirclePhoto , you get a run-time error.

Another option is to use type-check-based type promotion:

Photo photo = new CirclePhoto(15.0);
if (photo is CirclePhoto) print(photo.radius);

This promotes the photo variable to be a CirclePhoto in the code guarded by the is -check. (Type promotion is fairly primitive, it basically needs to be a local variable that you are not assigning to, and the type you check must be a sub-type of the current type of the variable).

Making radius private and adding a getter makes no difference . You already have a getter names radius on CirclePhoto , the one introduced by your final field. There is no advantage in renaming the field to be private and adding another getter, it's pure overhead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM