オブジェクト指向プログラミング
クラス
我々はあなたがすでに前にいくつかのオブジェクト指向プログラミングを行ってきた場合に馴染みのある可能性があるクラスの構造を簡単に紹介します。
package my.pack; /* this will define the class my.pack.MyClass */ class MyClass { // .... }
クラスは、いくつかの変数とメソッドを持つことができます。
package my.pack; class MyClass { var id : Int; static var name : String = "MyString"; function foo() : Void { } static function bar( s : String, v : Bool ) : Void { } }
変数とメソッドは、次のフラグを持つことができます。
- static : フィールドは、このクラスのインスタンスではなく、クラス自体に属しています。静的識別子は、クラス自体内で直接使用することができます。クラスの外で、それはクラス名(my.pack.MyClass.nameなど)を使用する必要があります。
- dynamic: フィールドは、動的に rebound することができます。
- override: フィールドには、サブクラスでオーバーライドされています。
- public : フィールドは、クラスの外からアクセスすることができます。
- private : フィールドへのアクセスは、クラス自体もしくは継承したクラスに制限されています。これはクラスの内部状態にアクセスできないことが保証されます。
デフォルトでは、すべてのフィールドはプライベートです。これは、Java、PHPなど他のほとんどの言語の proceted キーワードに対応しています。
すべてのクラス変数は、型(使用する型がわからない場合は、Dynamic を使用できます)で宣言する必要があります。関数の引数と戻り値の型はオプションですが、型推論を説明する際に我々が見るように、厳密にチェックされます。
All class variables must be declared with a type (you can use Dynamic if you don't know which type to use). Function arguments and return types are optional but are still strictly checked as we will see when introducing type inference.
非静的変数は初期値を指定していない場合があります。これは必須ではありませんが、静的変数は、初期値を持つことができます。
コンストラクタ
クラスは、"new" と呼ばれる static でない唯一のコンストラクタを持つことができます。これはクラス関数に名前を付けることにも使用できるキーワードでもあります。
class Point { public var x : Int; public var y : Int; public function new() { this.x = 0; this.y = 0; } }
コンストラクタのパラメータ化&オーバーロード:
public function new( x : Int, ?y : Int ) { this.x = x; this.y = (y == null) ? 0 : y; // "y" is optional }
クラス継承
When declared, it's possible that a class extends one class and implements several classes or interfaces. This means the class will inherit several types at the same time, and can be treated as such. For example :
class D extends A, implements B, implements C { }
Every instance of D will have the type D but you will also be able to use it where an instance of type A, B or C is required. This means that every instance of D also has the types A , B and C.
Extends
When extending a class, your class inherits from all public and private non-static fields. You can then use them in your class as if they where declared here. You can also override a method by redefining it with the same number of arguments and types as its superclass. Your class can not inherit static fields.
When a method is overridden, then you can still access the superclass method using super :
class B extends A { override function foo() : Int { return super.foo() + 1; } }
In your class constructor you can call the superclass constructor using also super :
class B extends A { function new() { super(36,""); } }
実装
When implementing a class or an interface, your class is required to implement all the fields declared or inherited by the class it implements, with the same type and name. However the field might already be inherited from a superclass.
インターフェイス
An Interface is an abstract type. It is declared using the interface keyword. By default, all interface fields are public. Interfaces cannot be instantiated.
interface PointProto { var x : Int; var y : Int; function length() : Int; }
An interface can also implement one or several interfaces :
interface PointMore implements PointProto { function distanceTo( p : PointProto ) : Float; }
ヘルパークラス
In Haxe, it is possible to have more than one class definition per class file:
// both definitions in Foo.hx class Foo { ... } class FooHelper { ... }
This is fairly common in many object oriented languages such as Java. However, unlike other such languages, Haxe also allows for these internal helper classes to be publicly available outside of the main class. By importing the main class, the helper class becomes available:
// in Bar.hx import Foo; class Bar{ var b:FooHelper; }
The helper class can also be made accessible via an extended package declaration:
// in Bar.hx class Bar{ var b:Foo.FooHelper; }
The use of public internal helper classes is typically not a recommended practice in most languages. Since helper class names do not correspond with their .hx file names, they can be harder to find in source trees.
HaXe lets you mark an internal helper class with the private keyword, in the same way that fields are marked:
// both definitions in Foo.hx class Foo { ... } private class FooHelper { ... }
This prevents the internal helper class from being accessed outside of the main class.
Unless there is a good reason for their use, consider placing each public class definition in its own .hx file, or make the internal class private, to prevent its definitions being included (and possibly causing a name conflict) when the main class is imported.
«« 型推論 - Type Parameters »»