• 締切済み

メソッドの作成方法

メソッドの作成方法に関して不明な点がありますので教えてください。 次の例はExcel VBAで作成したものです。 ---- Class Point ---- Public x As Integer, y As Integer ---- Class Line ---- Public FromPoint As Point, ToPoint As Point Sub Clear() Set FromPoint = New Point ToPoint.x = 0 ToPoint.y = 0 End Sub ---- テスト用プログラム ---- Sub test() Dim a As New Point, b As New Point, c As New Line a.x = 1 a.y = 2 b.x = 3 b.y = 4 Set c.FromPoint = a Set c.ToPoint = b c.Clear End Sub -------- 以上のプログラムにおいて test を実行すると c.Clear を実行したとき a の内容は変化しませんが b の内容は変化してしまいます。 これは Clearメソッドにおいて FromPoint のように新しいオブジェクトで設定するか、ToPoint のようにオブジェクトはそのままで内容を変更するかの違いです。 メソッドの作り方としてはどちらの方法を採用すべきでしょうか。 Class を使う側からすれば、各Classごとに副作用が異なるのは困るので同じ基準でメソッドを作りたいのですが。 一般的にはメソッドを実行するたびに新しいオブジェクトを作るわけではないので(上記の例でいえば Clearメソッドで新しい Lineオブジェクトを作成するわけではない)下位レベルのオブジェクトについても新たにオブジェクトを作らないほうが考え方が統一されてよいとは思いますが。 しかし、下位レベルのオブジェクトを Nothing にする場合などはどうしても動作が異なってしまうので、どうすべきか混乱しています。

みんなの回答

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.2

目的が違うなら両方作ればいいじゃない。

a_green_wind
質問者

補足

回答していただき、ありがとうございます。 > 目的が違うなら両方作ればいいじゃない。 Classを作る人と使う人が同じであれば、好きなように作ればいいと思いますが。 目的が違うというより、副作用が異なることが問題だと思っています。 使う人から見れば、副作用は目的ではないので、どちらでもいいのですが、ただ統一されていないと困るのではないでしょうか。

  • ap_2
  • ベストアンサー率64% (70/109)
回答No.1

> メソッドの作り方としてはどちらの方法を採用すべきでしょうか。 新しいオブジェクトの方で。 メソッドの処理対象は、指定がなければ、基本的に自分自身です。 Line.Clearなら、Lineを完全にClearなのだろうと予想します。なので、xyだけ0クリアなんてセコイことせず、Pointオブジェクトを根こそぎ(toPoint = nothing か = New Point)イッちゃってください。 あるいはメソッド名で明示。Line.ClearXYなら、xyだけと分かります。 ただ、そもそも「ClearされたLine」ってのがイメージできません。  ・両端の点がNothing状態の線  → そんな状態の線が存在してよいのか?  ・(0,0)(0,0)の線  → 初期値は線の種類によって違うのでは? よく分からない状態に戻すのはどうなんでしょう・・・ .Init(x1, y1, x2, y2)のようなメソッドをオススメしたいです。 オブジェクトの姿や動きは直感的に分かるのが理想です。 細かい部分はユーザ側(標準Module)で関数を実装してもいいんですから、クラス側は「どうあるべきか」重視で、シンプルに作るのがいいと思います。

a_green_wind
質問者

補足

回答して頂きありがとうございます。 Line.Clear は単なる例なので、実用上のことであまり突っ込まないでください(笑) > オブジェクトの姿や動きは直感的に分かるのが理想です。 全くその通りなのですが、そこで迷ってしまうのです。 例えば、オブジェクトの一部に画像を含む場合、その画像に直線を付け加えるメソッドの時は、新たな画像オブジェクトを作成せず、画像を直接変更したほうが自然に思えます。 しかし、その画像全体を変更してしまう場合、例えば画像を2値化するメソッドは、新たな画像オブジェクトを作成したほうが自然に思えるのです。 ただ、そうすると画像を変更するメソッドの種類によって副作用が異なってしまうので、それも問題かなと思うわけです。

関連するQ&A

  • スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラム

    スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラムでつまずいています。 Aを継承したB、Cクラスのインスタンスを作成し、スーパークラスであるA型の配列asにまとめます。 それからループでas[i]にはいっている各インスタンスのメソッドを使いたいのですが、 スーパークラスAにmethod()がないためコンパイルできません、Aにmethod()を作るとA.method()が実行されます。 BとCを同じ配列に保存し、かつそれぞれのmethod()を実行したい場合どのようにしたら良いのでしょうか。 ご教授ください、どうぞよろしくお願いします。 class Main{ private B b; private C c; private A[] as = new A[2]; void mainMethod(){ as[0] = b = new B(); as[1] = c = new C(); for(int i=0; i<3; i++){ as[i].method(); } } } class A{} class B extends A{ void method(){ System.out.print("It is B"); } } class C extends A{ void method(){ System.out.print("It is C"); } }

  • メソッド

    public class Point{ public int x; public int y; public void swap(int s){ int x = s * y; y = s * x; this.x = x; } public void swap2(int s){ int x = s * y; y = s * this.x; this.x = x; } public static void main(String[] args){ Point pt = new Point(); pt.x = 3; pt.y = 4; pt.swap(2); System.out.println(pt.x + " " + pt.y); pt.swap2(3); System.out.println(pt.x + " " + pt.y); } } このプログラムでswapメソッドとswap2メソッドってどう違うんですか?

    • ベストアンサー
    • Java
  • グラフィックDrawLineメソッドについて

    グラフィックDrawLineメソッドについて教えてください。 下記のコードでは、開いた線になります。OK mypoints(0)=New Point(10,10) ,mypoints(1)=New Point(40,70) mypoints(2)=New Point(60,30) mypoints(3)=New Point(90,90) Dim g As Graphics = PictureBox3.CreateGraphics() g.DrawLines(New Pen(Color.Blue, 1), mypoints) ところが、下記のコードで、グラフが最後閉じられてしまいます。NG どうしてでしょうか? For i = 0 To 48 mypoints(i) = New Point((i * 0.35), (PdaOneData(N_OneDtNo).PicData(i) * 0.05)) Debug.WriteLine(mypoints(i)) Next Dim g As Graphics = PictureBox3.CreateGraphics() g.DrawLines(New Pen(Color.Blue, 1), mypoints) 上記のmypoints(i) のイミディエイトウィンドウ表示は下記のとおりです。 X=0,Y=40}{X=0,Y=40}{X=1,Y=39}{X=1,Y=39}{X=1,Y=39}{X=2,Y=38}{X=2,Y=38}{X=2,Y=37}{X=3,Y=37}   ・・・中省略・・・ {X=14,Y=43}{X=14,Y=43}{X=15,Y=43}{X=15,Y=43}{X=15,Y=44}{X=16,Y=44}{X=16,Y=43}{X=16,Y=42}

  • コンストラクタの中でメンバクラスをnewしてはだめなのですか?

    C#2008EXPRESS EDITIONです。 以下のようなソースで、★1ではT.aがちゃんと生成されてるのに、★2のようにすると、Tの各メンバがNULLになってしまいます。 こういうやり方は、だめなのでしょうか?デバッガでは、引数無しのコンストラクタの内容を実行しているようなのですが・・・ なお、当方はCは理解していますが、C++を随分前に落伍した程度の者で、今回C#に挑戦してみようとしています。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Program { public class point { public double x; public double y; public point(double a, double b) { x = a; y = b; } } public class Triangle { public point a; public point b; public point c; public Triangle() { point a = new point(0,0); point b = new point(0,0); point c = new point(0,0); } public Triangle(point a,point b,point c){ this.a = a; this.b = b; this.c = c; } } static void Main(string[] args) { ★1 Triangle T = new Triangle(new point(1,2),new point(3,4),new point(5,6)); ★2 Triangle T = new Triangle(); Console.WriteLine("T.a.x={0} T.a.y={1}",T.a.x,T.a.y); } } } すみません、インデントを付ける方法がわからなくて、見にくいソースになってしまって。

  • C#でオブジェクトが生成されるたびに加算される変数

    タイトルの通りなのですがどうも上手く行かなくて・・・ まず、これが今作ってる、立方体の定義のためのクラスです class cube { public point a = new point(); public point b = new point(); public point c = new point(); public point d = new point(); public point A = new point(); public point B = new point(); public point C = new point(); public point D = new point(); } (point は x,y,zの値を持つ別のクラスです) ここで、それぞれのpoint(頂点)を生成した分だけ、それぞれのオブジェクトに、その通し番号を持たせることは出来ないでしょうか、つまり、最終的にそれぞれのオブジェクトが それぞれのクラスのメンバ変数 ”通し番号” を定義したとして a.通し番号 が 1 b.通し番号 が 2 c. 通し番号 が 3 という感じになるようにしたいんですが出来ません・・・ 外部にstaticな変数をおいてどうにかしようと思いましたが、staticなので、最後の通し番号に上書きされてしまって個別のオブジェクト内に保持できません むしろstatic変数ののある時点での実態コピーが出来るならそれも教えて下さい、それでもこの問題は解決します よろしくお願いします

  • VBA 実行時エラーで、"プロパティまたはメソッド

    ・Sheet1(コード) Private Sub CommandButton1_Click() Call aaa End Sub ・Module1(コード) Sub aaa() Dim wb As Workbook Dim ws As Worksheet Workbooks.Open ("c:\test.xls") Set wb = Workbooks("test.xls") Set ws = wb.Worksheets("Sheet1") wb.ws.Range("A2").Value = "CCC" End Sub wb.ws.Range("A2").Value = "CCC"の部分で 以下の実行エラーが出ます。 ------------------------------------------------------------------------ 実行時エラー'438': オブジェクトは、このプロパティまたはメソッドをサポートしていません。 ------------------------------------------------------------------------ Set wb = Workbooks("test.xls") Set ws = wb.Worksheets("Sheet1") の部分で特にエラーも出ないので、オブジェクトの取得は成功していると 思うのですが、WorkSheetオブジェクトのwsからRangeメソッドを呼ぶことが できません。 動かない原因と対策を教えてください!!

  • クラスメソッドのみのクラスのオブジェクト生成は不可??

    あるテキストのjavaの問題です。 public class Draw{   static void pixel(int x,int y){     /*座標(x、y)に点を描画*/   }   static void line(int x1,int y1,int x2,int y2){     /*座標(x1、y1)~(x2、y2)に線を引く*/   } } で、これを実行するための以下のようなクラス public class TestDraw{ <ここに入力> } という問題なのですが2つまでは絞れたのですが、 (1) public static void main(String args[]){   Draw d = new Draw().line(10,10,20,30); } ↑× (2) public static void main(String args[]){   Draw.line(10,10,20,30); } ↑○ (2)はlineメソッドがstaticメソッドだからオブジェクト生成しなくても良い、ということなんですが (1)も正解のような気がするのですが・・・ 解説によると「lineはvoidなのでnew Draw().line(10,10,20,30);とすれば正解、とあります。 どうもいまいち理解できません。 クラスメソッドはオブジェクト生成しなくとも良い→オブジェクト生成できない ということなのでしょうか? それからちなみに、public classって2つ記述できないんではありませんでしたか?

    • ベストアンサー
    • Java
  • 継承後のメソッドでコントロールにアクセスする方法

    よろしくお願い致します。 継承の動作を勉強しております。動作自体は確認出来ました。 継承後のメソッドでフォーム上のコントロールにアクセスする方法はありますか? 例えば「label1.text = "~"」の様に動作させたいです。 現在、2つのファイルに3つのクラス(そもそもここが間違ってる?)を書いてあります。 ----- 1つめのファイル(Formのクラス) ----- Public Class Form8  Private Sub Button1_Click(~) Handles Button1.Click   Dim c As New check1   c.test()  End Sub End Class Public Class check1  Inherits Class1  Public Overrides Sub test()   Trace.WriteLine("Overrides")   'label1.text = "動作OK"   ←こんな感じに実装したい  End Sub End Class ----- 2つめのファイル(クラス) ----- Public MustInherit Class Class1  Public MustOverride Sub test() End Class フォームクラスの外で「label1.text = ""」のように書いてもアクセス出来ないのはわかります。 フォームクラスのファイル中にもうひとつクラスを書いてしまっているのが悪いのもわかります。 この辺りをどのように実装したらよいでしょうか。 わかりづらくて申し訳ありません。 ご指導よろしくお願い致します。

  • 【C++】メソッドやプロパティの隠蔽

    基底クラスAで、Public でメソッドXと、メソッドYが定義されているとき、 それを継承したクラスBで、何らかの方法でメソッドXと、メソッドYを隠蔽させ、 クラスBを継承したクラスCでは、メソッドXと、メソッドYが使えないようにさせることはできますか? ※Visual Studioで、クラスCの入力サポート(メンバーや、メソッドの入力候補を出してくれる機能)で、 メソッドXや、メソッドYが出ないようにしたいです。 ※同様に、メンバーに対しても、隠蔽化をしたいです。

  • javaで、オブジェクトを生成しないとメソッドは使えないんですか?

    javaで、オブジェクトを生成しないとメソッドは使えないんですか? そのように習ったのですが、サブクラスのメソッド定義の中で、オブジェクトを生成せずにスーパークラスのメソッドを使える例(下に簡単に書きました)をみて、分からなくなってしまいました。 おしえてください、よろしくおねがいします。 ------------------------------- class superclass { method_a(){ ~~~~ } } --------------------------- class subclass { method_b(){ super.method_a(); }

    • ベストアンサー
    • Java

専門家に質問してみよう