codestory

Methoden in Dart

  1. Was ist Methode?
  2. Reguläre Methode
  3. Statische Methode
  4. Abstrakte Methode
  5. Optionaler Parameter
  6. Optionale benannte Parameter
  7. Eine Methode überschreiben
  8. Final method?

1. Was ist Methode?

In der Programmiersprache Dart ist eine Methode ein Codeblock, der innerhalb einer Klasse definiert ist und nur ausgeführt wird, wenn er aufgerufen wird. Methoden unterteilen eine große Aufgabe in kleine Teile und führen eine bestimmte Programmoperation durch. Dieser Prozess erhöht die Wiederverwendbarkeit des Codes und verbessert den modularen Ansatz des Programms.
Grundsätzlich werden Methoden in 3 Typen unterteilt:
  • Reguläre Methode (nicht statisch und nicht abstrakt).
  • statische Methode
  • Abstrakte Methode.

2. Reguläre Methode

Die Syntax zum Definieren einer regulären Methode:
return_type method_name(arguments)    {  
     // statement(s)  
}
  • return_type: Der Rückgabedatentyp der Methode. Verwenden Sie das Schlüsselwort void als Rückgabetyp, wenn die Methode nichts zurückgibt.
  • method_name: Der Methodenname. Im Gegensatz zu anderen Sprachen wie Java erlaubt Dart keine zwei Methoden mit demselben Namen, auch wenn sie unterschiedliche Parameter haben. Dies ist erforderlich, um Dart-Code in JavaScript umwandeln zu können.
  • arguments: Die Parameter der Methode..
Beispiel: Klasse Cat und ihre Methode sayHello(..). Um sayHello(..) aufzurufen, müssen Sie ein Cat-Objekt erstellen und die Methode in Punktnotation aufrufen.
method_ex1.dart
class Cat {
  void sayHello(String name) {
    print("Hello $name");
  }
}
void main() {
  Cat tom = new Cat(); // Create a Cat object.  
  tom.sayHello("Jerry"); // Call the method through the object.
}
Output:
Hello Jerry
Eine Methode kann 0, 1 oder mehr Parameter enthalten, die durch Kommas getrennt sind.
method_ex2.dart
class Rectangle {
  int width;
  int height;
  Rectangle(this.width, this.height); // Constructor

  int getArea() {
    return width * height;
  }
  void changeWidthHeight(int newWidth, int newHeight)  {
      width = newWidth;
      height = newHeight;
  }
  void showMe()  {
     print('I am a rectangle, width: $width, height: $height');
  }
}
void main() {
   Rectangle rec = Rectangle(5, 10); // Create an object.
   
   rec.showMe();  // Call the method.
   var area = rec.getArea();  // Call the method.
   print('Area: $area');
   print(' --- Change width and height --- ');
   rec.changeWidthHeight(25, 15); // Set newWidth, newHeight
   rec.showMe(); // Call the method.  
   area = rec.getArea(); // Call the method.
   print('Area: $area');
}
Output:
I am a rectangle, width: 5, height: 10
Area: 50
--- Change width and height ---
I am a rectangle, width: 25, height: 15
Area: 375

3. Statische Methode

Dart verwendet das Schlüsselwort static und die reguläre Methodendefinitionssyntax, um eine statische Methode zu definieren.
Die Syntax zum Definieren einer statischen Methode:
static return_type method_name(arguments)    {  
     // statement(s)  
}
Die Merkmale der statischen Methode:
  • Statische Methode wird über den Klassennamen und die Punktnotation aufgerufen. Zum Beispiel MyUtility.sum(100, 50). Der Klassenname und die Punktnotation können weggelassen werden, wenn Sie die statische Methode intern aufrufen.
  • Nicht statische Mitglied einer Klasse können nicht in einer statischen Methode erscheinen, es sei denn, auf sie wird über das Objekt zugegriffen (sehen Sie Beispiel unten).
method_static_ex1.dart
class MyUtility {
  static int sum(int a, int b)  {
    return a + b;
  }
  static int minus(int a, int b)  {
    return a - b;
  }
}
void main() {
   var result = MyUtility.sum(100, 50);
   print('Sum Result: $result');
   result = MyUtility.minus(100, 50);
   print('Minus Result: $result');
}
Output:
Sum Result: 150
Minus Result: 50
Betrachten Sie als Nächstes das folgende Beispiel:
  • side1, side2 und side3 sind nicht statische Felder der Klasse Triangle, die in der statischen Methode nicht vorkommen können.
  • Das Aufrufen einer statischen Methode innerhalb der Klasse, die sie definiert hat, erfordert möglicherweise nicht den Klassennamen und die Punktnotation
method_static_ex2.dart
class Triangle {
  late double side1;
  late double side2;
  late double side3;
  static const String DEFAULT_COLOR  = 'blue'; // Static field

  Triangle(double s1, double s2, double s3) {
    bool valid = isValidSides(s1, s2, s3); // Check if all sides are valid.
    if(!valid) {
      throw ArgumentError('Invalid Sides!'); // Throw an Error.
    }
     side1 = s1;
     side2 = s2;
     side3 = s3;
  }
  static bool isValidSides(double s1, double s2, double s3)  {
     if(s1 < 0 || s2 < 0 || s3 < 0)  {
       return false;
     }
     return s1 + s2 > s3 && s1 + s3 > s2 && s2 + s3 > s1;
  }
  bool isEquilateralTriangle() {
      return side1 == side2 && side2 == side3;
  }
}
void main() {
   bool valid = Triangle.isValidSides(6, 8, 10);
   print('Are sides 6, 8 and 10 valid to make a triangle? $valid');
   var triangle = Triangle(3.0, 4.0, 5.0);
   // Check if the triangle is equilateral triangle.
   var check = triangle.isEquilateralTriangle();
   print('Is Equilateral Triangle? $check');
}
Output:
Are sides 6, 8 and 10 valid to make a triangle? true
Is Equilateral Triangle? false

4. Abstrakte Methode

In der Dart-Sprache ist die abstrakte Methode eine nicht statische Methode und hat keinen Körper.
abstract return_type method_name(arguments);
Eine Klasse mit mindestens einer abstrakten Methode muss als abstrakt deklariert werden. Eine ihrer Unterklassen überschreibt abstrakte Methoden und schreibt Inhalte für sie.
Beispiel: Die folgende Klasse Person muss als abstrakte Klasse deklariert werden, da sie mindestens eine abstrakte Methode besitzt.
method_abstract_ex1.dart
abstract class Person {
  void sayHello(); // An abstract method.
}
class EnglishPerson extends Person {
  void sayHello() {
    print("Hello");
  }
}
class RussianPerson extends Person {
   void sayHello() {
      print("Привет");
   }
}
void main() {
    Person enPerson = EnglishPerson();
    enPerson.sayHello();
    Person ruPerson = RussianPerson();
    ruPerson.sayHello();
}
Output:
Hello
Привет
  • Dart Classes

5. Optionaler Parameter

Wie oben erwähnt, unterstützen Klassen in Dart und JavaScript keine Methoden mit demselben Namen, aber eine Methode kann optionale Parameter enthalten.
Die Syntax:
// Non-static method with optional arguments:
return_type method_name(typeM argM, typeN argN,[typeP? argP, typeQ? argQ]){  
     // statement(s)  
}
// Static method with optional arguments:
static return_type method_name(typeM argM, typeN argN,[typeP? argP, typeQ? argQ]){   
     // statement(s)  
}
// Abstract method with optional arguments:
return_type method_name(typeM argM, typeN argN,[typeP? argP, typeQ? argQ]);
Oder Syntax - Optionale Parameter mit Standardwerten:
// Non-static method with optional arguments:
return_type method_name(typeM argM, typeN argN,
                        [typeP? argP = defaultValueP, typeQ? argQ]){  
     // statement(s)  
}
// Static method with optional arguments:
static return_type method_name(typeM argM, typeN argN,
                        [typeP? argP = defaultValueP, typeQ? argQ]){   
     // statement(s)  
}
// Abstract method with optional arguments:
return_type method_name(typeM argM, typeN argN,
                        [typeP? argP = defaultValueP, typeQ? argQ]);
Zum Beispiel:
method_optional_args_ex1.dart
class MyUtility {
  static String concat(String s1, String s2, [String? s3]) {
    if (s3 != null) {
      return s1 + s2 + s3;
    }
    return s1 + s2;
  }
  static double sum(double v1, double v2, [double? v3, double? v4]) {
    return v1 + v2 + (v3 ?? 0) + (v4 ?? 0);
  }
}
void main() {
  String result1 = MyUtility.concat('One', 'Two');
  print('result1: $result1');
  String result2 = MyUtility.concat('One', 'Two', 'Three');
  print('result2: $result2');
  double value1 = MyUtility.sum(1, 2, 3, 4);
  print('value1: $value1');
  double value2 = MyUtility.sum(1, 2, 3);
  print('value2: $value2');
  double value3 = MyUtility.sum(1, 2);
  print('value3: $value3');
}
Output:
result1: OneTwo
result2: OneTwoThree
value1: 10.0
value2: 6.0
value3: 3.0
Zum Beispiel:
method_optional_args_ex2.dart
class Team {
   List<String> members = [];

   void addMembers(String member1, [String? member2, String? member3]) {
      members.add(member1);
      if(member2!= null) {
         members.add(member2);
      }
      if(member3!= null) {
         members.add(member3);
      }
   }
   void printAllMembers()  {
      print(' --- All members: --- ');
      for(var member in members) {
          print(member);
      }
   }
}  
void main() {
  var team = Team(); // Create Team object.
  team.addMembers('Tom', 'Jerry');
  team.printAllMembers();
}
Output:
--- All members: ---
Tom
Jerry

6. Optionale benannte Parameter

Optionale benannte Parameter sind Parameter in geschweiften Klammern { } und sind die letzten Parameter in der Parameterliste. Alle diese Parameter haben Standardwerte.
Die Syntax:
// Non-static method with optional named parameters:
return_type method_name(typeM argM, typeN argN,
                  {typeP paramP = defaultValueP, typeQ paramQ = defaultValueQ}){  
     // statement(s)  
}
// Static method with optional arguments:
static return_type method_name(typeM argM, typeN argN,
                  {typeP paramP = defaultValueP, typeQ paramQ = defaultValueQ}){  
     // statement(s)  
}
// Abstract method with optional arguments:
return_type method_name(typeM argM, typeN argN,
                  {typeP paramP = defaultValueP, typeQ paramQ = defaultValueQ});
Zum Beispiel:
method_optional_named_args_ex1.dart
class StringUtility {
  static String concatAndTrim(String s1, String s2, {bool trimLeft = true, bool trimRight = true}) {
    var s = s1 + s2;
    if (trimLeft && trimRight) {
      return s.trim();
    } else if (trimLeft) {
      return s.trimLeft();
    } else if (trimRight) {
      return s.trimRight();
    }
    return s;
  }
}
void main() {
  var s1 = '  One  ';
  var s2 = '  Two  ';
  var result1 = StringUtility.concatAndTrim(s1, s2); // trim left and right
  print('result1: -->$result1<-- (Trim left and right)');

  var result2 = StringUtility.concatAndTrim(s1, s2, trimLeft: false); // trim right only
  print('result2: -->$result2<-- (Trim right only)');

  var result3 = StringUtility.concatAndTrim(s1, s2, trimRight: false); // trim left only
  print('result3: -->$result3<-- (Trim left only)' );

  var result4 = StringUtility.concatAndTrim(s1, s2, trimLeft: false, trimRight: false); // no trim
  print('result4: -->$result4<!-- (No Trim)');
}
Output:
result1: -->One    Two<-- (Trim left and right)
result2: -->  One    Two<-- (Trim right only)
result3: -->One    Two  <-- (Trim left only)
result4: -->  One    Two  <!-- (No Trim)

7. Eine Methode überschreiben

Eine Unterklasse kann eine Methode der Elternklasse überschreiben, wenn die folgenden Bedingungen erfüllt sind:
  • Die beiden Methoden müssen denselben Namen und dieselben Parameter haben.
  • Der Rückgabetyp der beiden Methoden muss gleich sein oder der Rückgabetyp der Methode in der Unterklasse muss ein Untertyp des Rückgabetyps der Methode in der Elternklasse sein.
Zum Beispiel:
  • Die Klasse Cat überschreibt die Methode sayAnything() der Klasse Animal.
  • @override ist eine optionale Annotation, die vor der überschriebenen Methode (in der Unterklasse) platziert wird. Wenn Sie diese Methode versehentlich in der übergeordneten Klasse umbenennen, gibt der Compiler Dart eine Fehlermeldung aus.
method_override_ex1.dart
class Animal {
  void sayAnything() {
    print('<Nothing>');
  }
}
class Cat extends Animal {
  @override
  void sayAnything() { // Override method from parent class.
    print('Meow');
  }
}
void main() {
  Animal animal = Cat();
  animal.sayAnything();
}
Output:
Meow
Beispiel: Verwenden Sie das Schlüsselwort super, um eine Methode der Elternklasse aufzurufen.
method_override_ex2.dart
class BoldFormatter {
  String formatText(String text) {
    return '<b>' + text + '</b>';
  }
}
class BoldItalicFormatter extends BoldFormatter {
  @override
  String formatText(String text) { // Override method from parent class.
    var boldText = super.formatText(text); // Call super method.
    return '<i>' + boldText + '</i>';
  }
}
void main() {
  var formatter = BoldItalicFormatter();
  var formattedText = formatter.formatText('Hello');
  print(formattedText);
}
Output:
<i><b>Hello</b></i>

8. Final method?

In der Sprache Java können Sie das Schlüsselwort final für eine Methode verwenden, um sicherzustellen, dass Unterklassen diese Methode nicht überschreiben können. Gibt es etwas Ähnliches in Dart?
package:meta gibt Ihnen @nonVirtual, um zu verhindern, dass eine Unterklasse eine Methode der Elternklasse überschreibt. Es hilft Analyzer, einen Fehler zu melden, wenn Sie dagegen verstoßen, aber es werden keine anderen Aktion durchgeführt.
method_final_ex1.dart
import 'package:meta/meta.dart';

class Foo {
   @nonVirtual
   void bar() {
     print("bar from Foo!");
   }
}
class SubFoo extends Foo {
  @override
   void bar()  {
      print("bar from SubFoo");
   }
}
Grundsätzlich erhalten Sie von Analyzer eine Warnung, die wie folgt aussieht:
The member 'bar' is declared non-virtual in 'Foo'
and can't be overridden in subclasses.dart(invalid_override_of_non_virtual_member)
  • Thêm thư viện vào dự án Dart