注意:若干長いけどゴミ記事です.
最近Javaの授業のお手伝いをすることがあるので,拙い知識を補うために復習してました.
それで,パラパラと教科書を見てたらインターフェースの継承の項目があって,あんまりやろうと思ったことがなかったのでやってみました.
なんか消すのももったいない(地味にハマりかけたので)けどGitに上げるほどでも当然ないのでここに置いときます.
作るもの:MyVector インターフェース
今回はベクトルっぽいものを実装するためのインターフェースとしてMyVectorインターフェースを作ります.
選んだ理由は,ベクトル自体が何らかの概念に従うものであって,2次元ベクトルなどさらに具体的なものを考える根幹である(と思っている)からです.
とはいえ数学もJavaも詳しくないので,解釈や思想はどこか変であるかもしれないという想定でいてください.その辺の懸念もあって,ベクトルインターフェースにはMyVectorと名付けて,オレオレVectorインターフェースということにしておきます.
MyVectorの定義
確か加法性とか必要だったよね?とか思いつつ,とりあえずWikipedia先生を見に行く.
これを見つつ,インターフェースのためできるだけ一般的なものにしたいので,数学の項にある次の定義を参考にすることにします.
ベクトル空間の元。線形性を持つ、すなわち和とスカラー倍を取る事ができる量。一般の(広い意味での)ベクトル。
つまり,MyVectorインターフェースを実装するオブジェクトは線型性が保証されている必要があるわけですかね.
というところを踏まえて,定義してみます.
MyVectorに関する定義 : 線型性を持つ.
ただし線型性とは,ベクトルと,実数があるとき,
- となるベクトルが(唯一)存在する
- となるベクトルが(唯一)存在する
を満たす性質である.
JavaでMyVectorの実装
ではさっきの定義に従って,線型性を満たすインタフェースであるMyVectorインターフェースを書いてみます.
ちゃんと線型性のインターフェースを先に書いて,MyVectorインターフェースはそれを継承させることにします. また,線型性はすごく一般的な概念なので,Genericsを使うべきかなーと思ってそのようにします.
interface Linearity <T> { T add(T v); T multiply(double c); } interface MyVector <T> extends Linearity<T> { double magnitude(); String toString(); }
うーん中身は簡単ですね.Genericsのところでちょっと引っかかってしまいましたが,こんな感じになりました.
Linearityでは加算とスカラー乗算の抽象メソッドを記述しています.どちらも演算の結果,自身と同型のものを返すので定義に合っていますね(多分).
それを継承するMyVectorですが,一応ベクトルなので大きさを持つだろうということでMyVectorにはmagnitudeメソッドを置いてます.
もっとたくさん持っていて欲しいものはありますが(内積,外積,偏角,etc.),実装するのが面倒なのでこれとtoStringだけにします.
2次元ベクトルのクラス(Vector2)を作る
インターフェースができたので,具象化します.
簡単なやつということで,2次元ベクトルのクラスにします.
class Vector2 implements MyVector<Vector2> { private double x, y; public Vector2() { x = 0.0; y = 0.0; } public Vector2(double x, double y) { this.x = x; this.y = y; } public Vector2 add(Vector2 v) { return new Vector2(this.x+v.x, this.y+v.y); } public Vector2 multiply(double c) { return new Vector2(this.x*c, this.y*c); } public double magnitude() { return Math.sqrt(x*x+y*y); } public String toString() { return "("+x+", "+y+")"; } }
インターフェースができていると何も考えずに実装するだけなので簡単ですね.オブジェクト指向のそういうところ好き.
同様にすれば当然n次元ベクトルも定義できるはず.
余談ですが,前にフィールドをリストにしてコンストラクタの引数も可変長引数にして,そもそもn次元に対応できるオブジェクトを作ろうと企んだこともあったんですが,面倒になってやめました(当時はC++を使っていて,templeteがよく分からず死んだ思い出がある).だってそもそも2次元と3次元さえあれば問題ないですもの.
使ってみる
public class Main { public static void main(String[] args) { Vector2 v = new Vector2(1.0, 2.0); Vector2 w = new Vector2(3.0, -1.0); double c = 3.0; System.out.println(v.add(w)); // (4.0, 1.0) System.out.println(v.multiply(c)); // (3.0, 6.0) System.out.println(v.magnitude()); // 2.23606797749979 } }
使えそうです.以上.