AIと戦って、あなたの人生のリスク診断 >>

カプセル化をすることによって便利になること、利点を教えてください。
よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

プログラムサイズが小さかったり一人で作っていると利点を実感しにくいですが、大勢で作っている場合や、作った本人にも全体が見通せないほど巨大になった場合、作った本人も詳細を忘れた頃に改造・拡張する必要が出来た場合等には実感できると思います。


・オブジェクト間の結合を弱めクラスの流用・継承・変更がしやすくなります。
・変更による影響範囲を限定、もしくは影響が無い事の確認が容易になります。
・製作意図とは違う場所や違う意図で値の設定・変更を行ってしまうミスを防げます。
    • good
    • 0

変数をカプセル化する最も簡単と思われる例を上げてみます。


以下のコードは、身長を保持(設定/取得)するためのクラスです。

public class Tall() {

  private double tall; //カプセルかされた変数
  
  public Tall() {
  }
  
  public getCentimeters() {
    return tall / 10;
  }
  public getMillimeters() {
    return tall;
  }
  public getFeets() {
    return tall / 304.8;
  }
  
  public setCentimeters( double tall ) {
    this.tall = tall * 10;
  }
  public setMillimeters( double tall ) {
    this.tall = tall;
  }
  public setFeets( double tall ) {
    this.tall = tall * 304.8;
  }
}

内部的には、身長はミリメートル単位で保持されていますが
内部状態を全く意識することなく、フィートで設定して、
センチメートルで取り出すといったことが可能になります。
これが、ひとつの利点です。

また、身長が負の値になったりすることはありえませんが、
tallの double型変数がパブリックで宣言されていると、
tall = -170 といった非現実的な値も設定できてしまいます。

しかし、前記のコードのsetCentimeter()メソッドを
  public setCentimeters( double tall ) {
    if( tall < 0 ) throw new Error();
    this.tall = tall * 10;
  }
という風に適当なエラーを送出するように設定することで
不自然な値自体を設定できないようにすることが可能になります。
これが、ふたつめの利点です。
    • good
    • 0

ウルトラセブンのカプセル怪獣は、弱いが時間を稼げ、


やられそうになるとカプセルに戻せます。
    • good
    • 3

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QSub ***( ) と Private Sub ***( ) の違い

初歩的な質問で申し訳ありませんが・・・

自分でコードを書いていても、イベントが発生したりした時の処理で、コードのウィンドウで上のドロップダウンリストで選択できる時の処理などは自動的に[Private Sub Command1_Click( )]などと出てくるのでそのまま使っています。自分で別途プロシージャーを作成する時は[Sub ****( )]としています。
ですがその違いを理解しないまま、自分で作成する時は[Private Sub]ではなくて[Sub]を使っています。

Sub ***( ) と Private Sub ***( ) の違いは何なんでしょうか?
どなたか説明頂けませんか?
よろしくお願いします。

Aベストアンサー

「Sub」の部分にカーソルを置いて[F1]を押せばヘルプが起動します。
「指定項目」のところに「Public」と「Private」の説明がありますよ。
省略して「Sub hogehoge()」とした場合は「Public」とみなされます。

Publicは「すべてのモジュールから呼び出せるプロシージャ」ということになります。
Privateとすると「同じモジュールの中からしか呼び出せないプロシージャ」となります。

もしExcelをお持ちでしたらExcelのVBEで標準モジュールを追加し、「Sub Test1()」と「Private Sub Test2()」を作成してみてください。
そしてExcelの[ツール]-[マクロ]-[マクロ(Alt+F8)]でマクロ実行のダイアログを表示させてみるとわかります。
ここには実行できるプロシージャの一覧が表示されますが、Test1は表示されているけれどTest2は表示されません。
Test1はPublicで、Test2はPrivateだからです。

QArrayListを使った多次元配列の作成について

ArrayListで可変長配列を扱っているのですが、
2次元可変長配列を用いる必要が出てきたので、
下記のように変更したのですがうまくいきません。
何が悪いのか教えていただけませんでしょうか?

-----------------------------------------
ArrayList cars=new ArrayList();
cars.add("フェラーリ");
cars.add("ポルシェ");
cars.add("メルセデスベンツ");
for(int i=0;i<cars.size();i++){
 String str=(String)cars.get(i);
 System.out.println(str);}
-----------------------------------------
上記から下記のように変更しました。
-----------------------------------------
ArrayList[] cars=new ArrayList[3];
cars[0].add("フェラーリ");
cars[0].add("ポルシェ");
cars[0].add("メルセデスベンツ");
for(int i=0;i<cars[0].size();i++){
 String str=(String)cars[0].get(i);
 System.out.println(str);}
-----------------------------------------
エラーは「Exception in thread "main" java.lang.NullPointerException」です。
どうやら初期配列が10ではなく3となってしまっているようです。

ArrayListで可変長配列を扱っているのですが、
2次元可変長配列を用いる必要が出てきたので、
下記のように変更したのですがうまくいきません。
何が悪いのか教えていただけませんでしょうか?

-----------------------------------------
ArrayList cars=new ArrayList();
cars.add("フェラーリ");
cars.add("ポルシェ");
cars.add("メルセデスベンツ");
for(int i=0;i<cars.size();i++){
 String str=(String)cars.get(i);
 System.out.println(str);}
---------------------------------------...続きを読む

Aベストアンサー

こんにちは。

>ArrayList[] cars=new ArrayList[3];
はArrayList型のオブジェクトのインスタンス
を格納する箱を3個作成しただけなので、
この時点では、
cars[0] = null
cars[1] = null
cars[2] = null
となっています。ですから、当然
cars[0].add("フェラーリ");
などとやると、NullPointerExceptionが
発生します。これをさけるには、
cars[0] = new ArrayList();
cars[1] = new ArrayList();
cars[2] = new ArrayList();
とする必要があります。

Qオブジェクト指向プログラミングの多態性のメリット、目的は?

オブジェクト指向プログラミングを学んでいます。
基本概念の多態性がどうも理解できません。

メリット、目的はなんなのでしょうか?

上位クラスを継承し、
その継承されたクラスのメソッドを上書きするということと何が違うのでしょうか?

学習の参考にしている書籍の中には
”多態性を使ったオブジェクト指向プログラミングの典型例”として、
異種リスト(=上位型に下位型を代入し、一族のオブジェクトを一括管理する)を紹介しています。
多態性はこのような使用のみを目的としているのでしょうか?

Aベストアンサー

 異種リストを多態性を用いて実現するのは、一つの例ですね。#2の方の方針も基本的には同じ応用例だと思います。

 じつは、多態性には、もっと重要な応用例があります。そして、これは現在のWindowsMFCプログラミングで多用されています。
 Windowsはイベントドリブン型の実行方式であることは、ご存知でしょうか?ここに大きなポイントがあるのです。

 いまクラス(CView)があるとしましょう。

class CView{
public:
  virtual void OnDraw(CDC* pDC);
};

 いま、このCViewクラスには仮想関数OnDrawがあったとします。これは、描画が必要になったときに、Windowsプロシージャから呼び出される関数です。

さらにここで、CViewからクラスCMyViewを派生させましょう。

class CMyView : public CView{
public:
  virtual void OnDraw(CDC* pDC);
};

 ここで、OnDrawの実体部に具体的な描画操作を書いておくとします。

 さて、いままでの話は準備でした。
ここからが本題です。

いま、アプリケーションのビューを登録するのに、
void Add(CView* pView);
となる関数が与えられているとしましょう。
この関数によってCViewが登録されると、描画が必要な際に、
  pView->OnDraw(pDC);
を自動で呼び出すようになっています。

もしここで、
  Add(new CMyView());
と登録すれば、描画が必要な際には自動的に、
CMyView::OnDraw(CDC* pDC)を呼び出してくれるわけです。
 これは通常の関数によるオーバーライドでは実現できません。オーバーライドしていたのでは、CView::OnDraw(CDC* pDC);が呼び出されてしまいます。

 もしかしたら、Add(CView* pView)について疑問が残るかもしれません。
 Add(CMyView* pMyView);という関数を作って、pMyView->OnDrawを呼び出せば、確かに同じ動作をしてくれるでしょう。
 しかし、Add(CView* pView);はライブラリで規定されている関数なのです。つまり、C言語でのprintfのようなもの。Add(CMyView* pMyView);という関数をつくるということは、ライブラリを有効利用しないということなのです。


 そのような観点から言えば、先ほどの異種リストも同じことが言えます。抽象度が高い「動作」の部分をライブラリにしておきさえすれば、具体的なものを考えたときに、すばやく目的の動作を実現できる。
 この概念はWindowsプログラミングのようにプログラム規模がとても大きくなる場合は、どうしても利用しなくてはならないでしょう。

 確かに多態性はわかりにくい概念ではあります。
しかし、抽象度の高いプログラムがあらかじめ作成されていて、それを具体的な目的で利用するといった場合、有効な方法なのです。

 異種リストを多態性を用いて実現するのは、一つの例ですね。#2の方の方針も基本的には同じ応用例だと思います。

 じつは、多態性には、もっと重要な応用例があります。そして、これは現在のWindowsMFCプログラミングで多用されています。
 Windowsはイベントドリブン型の実行方式であることは、ご存知でしょうか?ここに大きなポイントがあるのです。

 いまクラス(CView)があるとしましょう。

class CView{
public:
  virtual void OnDraw(CDC* pDC);
};

 いま、このCViewクラスには仮...続きを読む

QIOException ってどういうときに起こるのでしょうか?

IOException ってどういうときに起こるのでしょうか?

http://www.atmarkit.co.jp/fjava/rensai2/javaent12/javaent12.html
を見て勉強しています。

  catch ( IOException e) {
    System.out.println( "キーボードが故障しているのかもしれません" );
  }

と書いてあります。
ハード(キーボード)が故障しているのを Java のプログラムのレベル(ソフトウェア)で感知できるというのがよくわかりません。「

NumberFormatException の方はわかるのですが・・・

Aベストアンサー

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接続だったりするわけですけど、
InputStreamは、その入力元の情報を持っていないので、
データを読み取る際は常に
IOExceptionをキャッチするコードを書かなくてはいけません。
たとえ、絶対にIOエラーが発生しないストリームだとしても。

さらに付け加えるなら、
そもそも「標準入力=キーボード」であるとは限りません。
(一般的にはキーボードであることが多いですが。)
Javaでは、
System.setIn(InputStream)
を呼び出して、標準入力を変えてしまうことができますし、
標準入力を指定してプログラムを実行することができるOSもあります。

追伸1:
例外をキャッチしたときは、
スタックトレースをプリントすることをおすすめします。
catch (IOException e) {
e.printStackTrace();
}

追伸2:
そのプログラムでIOExceptionを発生させる最も簡単な方法は、
readLine()を呼び出す前に
標準入力(System.in)を閉じてしまうことです。
System.in.close();

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接...続きを読む

Q以降、以前はその値を含む?含まない?

以降、以前というのはその値そのものをふくむのでしょうか?
より後、より前は含まないと言うのはわかります。
たとえば
「4月13日以降の最初の日曜日」
とあったときに、4月13日が日曜日だった場合は4月13日が該当の日となるのでしょうか?それとも4月20日が該当の日でしょうか?

Aベストアンサー

「4月13日以降の最初の日曜日」
4月13日が日曜であった時、4月13日が「4月13日以降の最初の日曜日」となります。

「以降」、「以前」という言葉は「~を以って」と言うように、
前の言葉を条件に含みます。

Qpublic static void main (String args[])

基本すぎて申し訳ありませんが、
public static void main (String args[])とはどういう意味を持っていますか?
教えてください。。

Aベストアンサー

staticとかの意味はNo1の方の説明以外にありません。

mainは最初に実行されるメソッドという説明がされますので、「クラスを実行する時の引数とは?」と引っかかっているのかもしれませんね。
これはコマンドライン引数と呼ばれます。

たとえば、次のプログラム

public class ArgsTest{
  public static void main(String[] args){
    System.out.println(args.length);
    for(int i = 0 ; i < args.length ; i++){
      System.out.println(args[i]);
    }
  }
}

これを
>java ArgsTest abcde fghij(エンター)
として実行するとabcdeとfghijが引数となります。

ちなみに、mainはpublicでstaticなメソッドなので、
public class ArgsTest2{
  public static void main(String args[]){
    tamesi();
  }
  void tamesi(){
    String[] test = {"abcde","fghij"};
    ArgsTest.main(test);
  }
}
のように、外部のクラスからクラス名.mainで呼び出せます。(この2つのプログラムは、私が悩んだ時に試しにつくったものです)

ちなみにargsはarguments(=引数)の略で、mainの引数として、よく使われます。
argvのほうはargument valueの略です。C言語を使っていた人の中にはargvを使う人がいるかもしれません。

staticとかの意味はNo1の方の説明以外にありません。

mainは最初に実行されるメソッドという説明がされますので、「クラスを実行する時の引数とは?」と引っかかっているのかもしれませんね。
これはコマンドライン引数と呼ばれます。

たとえば、次のプログラム

public class ArgsTest{
  public static void main(String[] args){
    System.out.println(args.length);
    for(int i = 0 ; i < args.length ; i++){
      System.out.println(args[i]);
    }
  }
}

...続きを読む

QC#にて別クラスの関数を使いたい

C#にて、別クラスの関数を使用する方法を教えてほしいです。

下記のような、構造体を受け取るメソッドを作りました。

*****************************
private struct MyPoint
{
public int x;
public int y;
}

private void proc1(MyPoint pt)
{
MessageBox.Show("座標:" ; pt.x + "," + pt.y + "実行結果");
}

private void button1_Click(object sender ,System.EventArgs e)
{

MyPoint pt;
pt.x = 10;
pt.y = 20;
proc(pt);
}
*****************************

別のフォームのクラスから、proc1を呼び出したいのですが、やり方がわかりません。
どうか、教えてください。

Aベストアンサー

同じ定義をしたとしても別の名前空間に書いた構造体は同一とはみなされません。

呼び出し先クラスでの構造体を private では無く、public で宣言して下さい。

呼び出し元では、

MyClass.MyPoint pt;

のようにして実体を作ります。

Qdefine で 配列

#defineで配列を定義したいのですがこのようなことは可能でしょうか?

ヘッダファイル(test.h)で
#define MAX (2)
int A[MAX]={20,30};

ソースファイルで
#include <stdio.h>
#include "test.h"
int main(){
int i;
for(i=0;i<MAX;i++){
printf("A[%d]=%d\n",i,A[i]);
}
return 0;
}

とやれば出来るのですが、このヘッダファイルを複数のソースで参照すると
多重定義であるとおこられてしまいます。

#defineで
#define A[MAX] {20,30}
のように配列を定義する方法は存在するのでしょうか?

どなたか良い方法を御存じの方、ご教授お願いします。

Aベストアンサー

#define でではなく、共通して使う配列(なり変数)をただひとつのヘッダファイルで定義する方法でしょうか。

既に回答がありますが、同じ実体を持つ変数を複数の箇所(同じヘッダファイルを include する複数の箇所である場合も)で宣言する場合、
・実体を宣言する部分には単純な宣言が
・それ以外の部分には(実体が他にあるということを明示するために) extern が必要です。

これを解決するテクニックのひとつに以下のようなものがあります。

test.h 内で

#if defined(_GLOBAL_HERE)
#defien GLOBAL
#define DEF(x) = x
#else
#defien GLOBAL extern
#define DEF(x)
#endif

#define MAX 2
GLOBAL int A[MAX] DEF({2, 3});

メインのソースファイル内で
ソースファイルで
#include <stdio.h>
#define _GLOBAL_HERE
#include "test.h"
int main(){
int i;
for(i=0;i<MAX;i++){
printf("A[%d]=%d\n",i,A[i]);
}
return 0;
}

それ以外のソースファイル内で
(メインのソースファイル内以外の場所では、_GLOBAL_HERE を定義しない)
#include <stdio.h>
#include "test.h"
int foo(){
....

こんな感じです。

#define でではなく、共通して使う配列(なり変数)をただひとつのヘッダファイルで定義する方法でしょうか。

既に回答がありますが、同じ実体を持つ変数を複数の箇所(同じヘッダファイルを include する複数の箇所である場合も)で宣言する場合、
・実体を宣言する部分には単純な宣言が
・それ以外の部分には(実体が他にあるということを明示するために) extern が必要です。

これを解決するテクニックのひとつに以下のようなものがあります。

test.h 内で

#if defined(_GLOBAL_HERE)
#defien ...続きを読む

Qエラーで式の開始が不正ですと出ます。

質問内容 課題
・ファイル student.txt に学生データ(学籍番号、氏名、所属学部)が入っている。
・半角文字で学籍番号を入れて、検索ボタンを押すと、氏名と学部が表示される。

・存在しない学籍番号を入れて、検索ボタンを押すと、「該当なし」が表示される。




・ファイル student.txt の内容。
 学籍番号 氏名 学部の間は半角スペースで区切る。 0521201 金城花子 文学部
0533101 守山春子 生活環境学部
0561101 大森夏子 人間科学部
0552130 名城秋子 現代文化学部
0571201 鶴舞冬子 薬学部

プログラムソース↓
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;

class kadai2Frame extends JFrame {
private JTextField tf1,tf2,tf3;
public kadai2Frame() {
setSize(200,100);
addWindowListener(new WindowAdapter() { // ×クリック時の終了処理
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});


Container c=getContentPane();
c.setLayout(new GridLayout(4,2)); // グリッドレイアウト4 行2 列を指定
c.add(new JLabel("学籍番号")); // 最初のラベルを作成して[名前]と表示
c.add(tf1=new JTextField("",8));
c.add(new JLabel("氏名")); // 最初のラベルを作成して[名前]と表示
c.add(tf2=new JTextField("",8));
c.add(new JLabel("学部")); // 次のラベルを作成して[年齢]と表示
c.add(tf3=new JTextField("",8));
JButton bt;
c.add(bt=new JButton("検索")); // ボタンbt を作成して[検索]と表示
bt.addActionListener(new ActionListener() { // ボタンbt のリスナーを登録
public void actionPerformed(ActionEvent e) { // ボタンが押された時

string s6 = tf1.getText();
if(s1.equals(s6)){tf2.setText(str1Ary[1]);

string s6 = tf1.getText();
if(s2.equals(s6)){tf2.setText(str2Ary[1]);



string s6 = tf1.getText();
if(s3.equals(s6)){tf2.setText(str3Ary[1]);




string s6 = tf1.getText();
if(s4.equals(s6)){tf2.setText(str4Ary[1]);



string s6 = tf1.getText();
if(s5.equals(s6)){tf2.setText(str5Ary[1]);


}


public static void main(String[] args) {
JFrame w=new kadai2Frame();
w.setVisible(true);


try{
BufferedReader br =
new BufferedReader(new FileReader("student.txt"));
}
catch (FileNotFoundException e) {


String str1 = br.readLine();
String str2 = br.readLine();
String str3 = br.readLine();
String str4 = br.readLine();
String str5 = br.readLine();

String[] str1Ary = str1.split(" ");
for (int i=0; i<str1Ary.length; i++) {
System.out.println(str1Ary[i]);
}



String[] str2Ary = str2.split(" ");
for (int i=0; i<str2Ary.length; i++) {
System.out.println(str2Ary[i]);
}

String[] str3Ary = str3.split(" ");
for (int i=0; i<str3Ary.length; i++) {
System.out.println(str3Ary[i]);
}

String[] str4Ary = str4.split(" ");
for (int i=0; i<str4Ary.length; i++) {
System.out.println(str4Ary[i]);
}

String[] str5Ary = str5.split(" ");
for (int i=0; i<str5Ary.length; i++) {
System.out.println(str5Ary[i]);
}


String s1 = "str1Ary[0]";
String s6 = "tf1";
String s2 = "str2Ary[0]";
String s3 = "str3Ary[0]";
String s4 = "str4Ary[0]";
String s5 = "str5Ary[0]";

}
}
});
}
}

以上です。誰か教えてください!!(ToT)

質問内容 課題
・ファイル student.txt に学生データ(学籍番号、氏名、所属学部)が入っている。
・半角文字で学籍番号を入れて、検索ボタンを押すと、氏名と学部が表示される。

・存在しない学籍番号を入れて、検索ボタンを押すと、「該当なし」が表示される。




・ファイル student.txt の内容。
 学籍番号 氏名 学部の間は半角スペースで区切る。 0521201 金城花子 文学部
0533101 守山春子 生活環境学部
0561101 大森夏子 人間科学部
0552130 名城秋子 現代文化学部
0571201 鶴舞冬子 薬学...続きを読む

Aベストアンサー

動かないこと前提に。
まず,
if文の構文がおかしいので直します。最後に}をつける

if(s1.equals(s6)){tf2.setText(str1Ary[1]);}
string s6 = tf1.getText();
if(s2.equals(s6)){tf2.setText(str2Ary[1]);}
string s6 = tf1.getText();
if(s3.equals(s6)){tf2.setText(str3Ary[1]);}
string s6 = tf1.getText();
if(s4.equals(s6)){tf2.setText(str4Ary[1]);}
string s6 = tf1.getText();
if(s5.equals(s6)){tf2.setText(str5Ary[1]);}

53行目の閉じ括弧に対応するのは
28行目の括弧です。

つまり public static void mainも
bt.addActionListener(new ActionListener(){ 27行目
}) 111行目
の中に入っているのでしょうが,
おそらくメソッドを二つ入れる形になっているのでエラーがでているんだと思います。

111行目を取り除いて
54行目に
});
を記述します

次に mainの前に
public kadai2Frame() {
を閉じていないことがわかるので
55行目に
}
を補います。
これで応急処置は終わりです。それまでに閉じているはずのものを全然閉じてないからエラーが出ていたんです。

61行目のtry{は64行目
65行目のcatch{はfor文は対応関係が正しいから無視して}109行目。
mainの終了は
110行目。
すると
112行目がクラスの終わりだから
113行目はいらない。

そうすると,シンボルが見つからない云々というエラーだらけになります。

これは,変数の宣言位置とスコープの問題なのでそのエラーとは別に解決してください。

変数宣言をきちんとやれば,コンパイルは通るはずです。
#思い通りには動かないと思うけど。

動かないこと前提に。
まず,
if文の構文がおかしいので直します。最後に}をつける

if(s1.equals(s6)){tf2.setText(str1Ary[1]);}
string s6 = tf1.getText();
if(s2.equals(s6)){tf2.setText(str2Ary[1]);}
string s6 = tf1.getText();
if(s3.equals(s6)){tf2.setText(str3Ary[1]);}
string s6 = tf1.getText();
if(s4.equals(s6)){tf2.setText(str4Ary[1]);}
string s6 = tf1.getText();
if(s5.equals(s6)){tf2.setText(str5Ary[1]);}

53行目の閉じ括弧に対応するのは
28行目の括弧です。

...続きを読む

QCOBOLのイニシャライズとバリュー句について

COBOLの質問です。
01 koumoku pic9 value 4.
INITIALIZE koumoku.
とすると koumokuには何がはいってるんでしょうか。
0? 4?
よろしくお願いします。

Aベストアンサー

正しい答えは・・
INITIALIZEを行う前の状態は、4。
INITIALIZEを行うことで、0(ゼロ)になる。


人気Q&Aランキング