アルゴリズムとプログラミング (Algorithms and Programming)

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

オブジェクト指向 言語 論 第八回 知能情報学部 新田直也. 多相性(最も単純な例) class A { void m() { System.out.println( “ this is class A ” ); } } class A1 extends A { void m() { System.out.println(
独習JAVA Chapter 6 6.6 クラスの修飾子 6.7 変数の修飾子 結城 隆. 6.6 クラスの修飾 abstract インスタンス化できないクラス。1つまたは複数のサブクラスで 実装してはじめてインスタンス化できる。 final 継承されたくないことを明示する。これ以上機能拡張 / 変更でき.
復習ー I (General Review I) クラスとオブジェクトの概念 Concepts of class and object クラスの宣言とオブジェクトの生成 Definition of a class and creation of an object コンストラクタとメソッドのオーバーロー.
ソフトウェア工学 知能情報学部 新田直也. オブジェクト指向パラダイムと は  オブジェクト指向言語の発展に伴って形成され てきたソフトウェア開発上の概念.オブジェク ト指向分析,オブジェクト指向設計など,プロ グラミング以外の工程でも用いられる.  ソフトウェアを処理や関数ではなくオブジェク.
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
アルゴリズムとプログラミング (Algorithms and Programming)
Applet 岡部 祐典 鈴木 敬幸.
~手続き指向からオブジェクト指向へ(Ⅰ)~
第4回 iPhoneアプリ開発勉強会 Objective-C 基礎講座 -クラス- 鷲見政明.
プログラミング基礎I(再) 山元進.
アルゴリズムとデータ構造1 2007年6月12日
アルゴリズムとプログラミング (Algorithms and Programming)
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
繰り返し プログラミング 第4回 繰り返し プログラミング第4回.
社会人学習講座 「Javaプログラミング概論」
第2章 Eclipseと簡単なオブジェクト 指向プログラミング
オブジェクト指向入門.
計算機プログラミングI 第8回 2002年12月5日(木) メソッドとクラス (教科書6章) クイズ インスタンスメソッド インスタンス変数
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
~手続き指向からオブジェクト指向へ[Ⅱ]~
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
JAVA入門後期⑩ 情報処理試験例題解説.
アルゴリズムとプログラミング (Algorithms and Programming)
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十一回 知能情報学部 新田直也.
第7回独習Javaゼミ セクション 1~4 発表者 直江 宗紀.
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
コンパイラの解析 (3) クラスとインスタンスの初期化.
第11週:super/subクラス、継承性、メソッド再定義
Nakano School of Business 経営情報ビジネス科 【 Java概論(Test5)】
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
もっと詳しくArrayクラスについて調べるには → キーワード検索
オブジェクト指向 プログラミング 第十ニ回 知能情報学部 新田直也.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
第8回放送授業.
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向 プログラミング 第九回 知能情報学部 新田直也.
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
C#プログラミング実習 第3回.
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
アルゴリズムとプログラミング (Algorithms and Programming)
サブゼミ第7回 実装編① オブジェクト型とキャスト.
Chapter 5 5.5 thisキーワード 5.6 インスタンス変数とインスタンスメソッド 結城 隆
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第十回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

アルゴリズムとプログラミング (Algorithms and Programming) 第10回:インスタンス変数、クラス変数 インスタンス変数とクラス変数 インスタンスメソッドとクラスメソッド ローカル変数とスコープ 変数の寿命、ガーベージコレクション 講義資料等: http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html

インスタンス変数 インスタンス変数 これまで出てきた変数は、インスタンスごとにメモリ領域が個別に割り当てられ、別々に読み書きができた class Point { // 点クラス double x; // x座標 double y; // y座標 } これまで出てきた変数は、インスタンスごとにメモリ領域が個別に割り当てられ、別々に読み書きができた Point p1 = new Point(); Point p2 = new Point(); インスタンス変数 p1とp2はクラスは同じだが、別のインスタンスであり、それぞれ個別に変数double x, double yを持つ Point: p1 Point: p2 x: 1.5 x: 0.2 y: 2.0 y: 0.0 お互い無関係に 読み書き可能

クラス変数 クラス変数 同じクラスのどのインスタンスからでも、共通の1つの変数(=メモリ領域)を読み書きしたい場合がある クラス全体で p1からクラス変数の値を 変更すると、p2から見ても 値が変更されている!! Point: p1 Point: p2 x: 1.5 x: 0.2 y: 2.0 y: 0.0 count : count : 実体は1つ クラス全体で 共有する変数 count : 2.0 クラス変数

クラス変数の宣言 static修飾子 クラス変数へのアクセス方法: オブジェクト変数名.クラス変数名 クラス名.クラス変数名 class Point { // 点クラス double x; // x座標 double y; // y座標 public static int count; } static修飾子 クラス変数へのアクセス方法: オブジェクト変数名.クラス変数名 クラス名.クラス変数名

クラス変数の宣言と利用の例 class Point { // 点クラス double x; // x座標 double y; // y座標 //クラス変数の定義と初期化(static修飾子の有無で出力結果を比較せよ) public static int count = 0; Point( double a, double b ){ x = a; y = b; count++; } class SampleAP0801 { public static void main(String[] args){ // インスタンスが生成される前からクラス変数は存在する! System.out.println("count=" + Point.count); Point p1 = new Point(1.0,2.0); System.out.println("count=" + p1.count); Point p2 = new Point(3.0,4.0); System.out.println("count=" + p2.count); コンストラクタ count=0 count=1 count=2

クラスメソッド クラス単位で共有されるメソッド インスタンス変数にアクセス不可 インスタンスメソッドの呼び出し不可

クラスメソッドは、クラス内で定義されているのでクラスのメンバーといえるが、実体はインスタンスの外に存在する オブジェクト(実体) インスタンス1 インスタンス変数 インスタンスメソッド クラス定義 インスタンス2 クラス変数 クラスメソッド static static インスタンス3 アクセス クラスで共有 static static

public static int count = 0; public static void printValue(){ class Point { // 点クラス double x; // x座標 double y; // y座標 //クラス変数、クラスメソッドの定義 public static int count = 0; public static void printValue(){ System.out.println( "value:" + count ); } public static void printValue(int i){ System.out.println( "value:" + i ); class SampleAP0802 { public static void main(String[] args){ // インスタンスが生成される前からクラス変数、クラスメソッドは存在する! Point.count = 5 ; Point.printValue(); Point.printValue(6); Point o = new Point(); o.printValue(7); インスタンス変数 クラス変数 クラスメソッド クラスメソッド クラスメソッドの中からインスタンス変数であるx,yを参照することはできない! value:5 value:6 value:7

main()はクラスメソッドだった! main()メソッドが実行される約束になっている class ユーザ定義 { public static void main(String[] args){ 処理; } main()メソッドが実行される約束になっている

どこで宣言された変数か? 変数の3つの分類 宣言される場所 インスタンス変数 クラス変数 ローカル変数 クラス内 メソッド内

ローカル変数が見える 範囲(スコープ)と寿命 中カッコ{}で囲まれたブロックがスコープの目印 class SampleAP0803 { public static void main(String[] args){ int x = 0; for( int i = 1; i <= 10; i++) { x = x + i; } System.out.println("total = " + x ); 変数iの値をこのforブロックの外から参照することはできない 変数xの値はforブロック内からでも参照可能

変数の寿命 使い終わった変数は破棄され、使用していたメモリが解放される (ガベージコレクション) ローカル変数の寿命:ブロックの最初にメモリが確保され、ブロックの終わりで破棄される インスタンス変数の寿命:newで生成されてから、最後に参照された後、Java VM が判断したタイミング クラス変数の寿命:プログラムの開始から終了まで

バッティングしても有効 ローカル変数 class X { static int i = 100; int j = 200; SampleAP0804.java class X { static int i = 100; int j = 200; void printValue(){ System.out.println("i= " + i ); System.out.println("j= " + j ); int i = 123; int j = 456; } クラス変数 インスタンス変数 ローカル変数

変数名がバッティングした場合は ローカル変数が優先される class SampleAP0804 { SampleAP0804.java続き class SampleAP0804 { public static void main(String[] args){ X o = new X(); o.printValue(); } 実行結果 i= 100 j= 200 i= 123 j= 456 ローカル変数 クラス変数・インスタンス変数 変数名がバッティングした場合は ローカル変数が優先される バッティングしないように名前を付けるのが望ましい

値を変更しない変数(定数)の宣言 final修飾子 class X { static final int MAX = 100; final static int MIN = -100; final int DEFAULT = 10; } class SampleAP0805 { public static void main(String[] args){ System.out.println("value= " + X.MAX); System.out.println("value= " + X.MIN); X o = new X(); System.out.println( "value= " + o.DEFAULT); 値を変更しないのなら、インスタンスごとにこの定数のためにメモリを確保するのは無駄といえる→普通はクラス変数にする(static)

まとめ インスタンス変数とクラス変数 インスタンスメソッドとクラスメソッド ローカル変数とスコープ 変数の寿命、ガーベージコレクション final修飾子

アルゴリズムとプログラミング (Algorithms and Programming) 第11回:継承の実装 継承の実装: extends キーワード           コンストラクタ 継承とメソッドのオーバーライド,可視性 抽象クラス (abstractキーワード) 講義資料等: http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html

継承の実装 Vehicle(乗り物) Plane サブクラスは、スーパークラスの全てのフィールドとメソッドを含んでいる。 - speed: double # changeSpeed(s:double) # getSpeed(): double サブクラスは、スーパークラスの全てのフィールドとメソッドを含んでいる。 (実際にアクセスできるかは、アクセス修飾子に従う) サブクラス Plane - altitude: double # takeOff () # land ()

継承の実装:extendsキーワード Vehicle(乗り物) Plane スーパークラス - speed: double # changeSpeed(s:double) # getSpeed(): double class Plane extends Vehicle { private double altitude; protected void takeOff() { 処理(スーパークラスのメソッドも呼べる); } protected void land() { 処理; サブクラス Plane - altitude: double # takeOff () # land ()

スーパークラスへのアクセス Vehicle(乗り物) Plane スーパークラス - speed: double # changeSpeed(s:double) # getSpeed(): double public static void main(略) { Plane o = new Plane(); o.changeSpeed(0.0); for(int i=0;i<=300;i+=50){ o.changeSpeed(i); o.takeOff(); } System.out.println("離陸!"); サブクラス Plane - altitude: double # takeOff () # land ()

全てのクラスのスーパークラス Objectクラス extendsキーワードが無い全てのクラスは、自動的にObjectクラスのサブクラスとなる。従って、全てのクラスはObjectクラスのフィールドとメソッドを暗黙的に継承している。 Vehicle(乗り物) - speed: double # changeSpeed(s:double) # getSpeed(): double Plane - altitude: double # takeOff () # land ()

継承とコンストラクタ サブクラスのコンストラクタを呼び出すと.. まずスーパクラスのコンストラクタが実行される (何も指定しなければデフォルトコンストラクタが呼ばれる.引数は無し) 次にサブクラスのコンストラクタが実行される

サブクラスのコンストラクタ(例) ここにsuper();が省略 されていると考える class X { int x; X() { SampleAP0901.java class X { int x; X() { x = 100; } class Y extends X { int y; Y() { y = 200; ここにsuper();が省略 されていると考える

サンプルプログラム(続き) x= 100 y= 200 class SampleAP0901 { SampleAP0901.java続き class SampleAP0901 { public static void main(String[] args) { Y o = new Y(); System.out.println("x= " + o.x ); System.out.println("y= " + o.y ); } 実行結果 x= 100 y= 200

親のコンストラクタを指定する場合 Superキーワード (thisキーワードとの併用は不可) SampleAP0902.java class X { int x; X(int a) { x = a; } class Y extends X { int y; Y(int a, int b) { super(a);    y = b; コンストラクタでsuperを使うときは 最初の行でしか使えない!

SampleAP0902.java続き class SampleAP0902 { public static void main(String[] args) { Y o = new Y( 1, 2 ); System.out.println("x= " + o.x ); System.out.println("y= " + o.y ); } 実行結果 x= 1 y= 2

暗黙の親コンストラクタ呼び出し ここにsuper();が省略 されていると考える class X { int x; X() { SampleAP0901.java(再) class X { int x; X() { x = 100; } class Y extends X { int y; Y() { y = 200; ここにsuper();が省略 されていると考える

継承を禁止するfinalキーワード サブクラスの宣言を禁止! コンパイルエラー! final宣言したクラスは、extendsで final class X { int x; } class Y extends X { int y; サブクラスの宣言を禁止! コンパイルエラー! final宣言したクラスは、extendsで サブクラスを作ることが禁止される

メソッドのオーバーライド オーバーライド(override) オーバーロード (overload) 親クラスと子クラスのそれぞれに、 メソッド名、引数、戻り値が全て同一で内容が異なるメソッドを定義すること 既出 混同注意! オーバーロード (overload) ひとつのクラス内に、メソッド名が同じで、引数の型及び数が異なるメソッドを定義すること

オーバーライドの目的 オーバーライドの必要性 Vehicle(エンジン付き乗り物) もともと、サブクラスにはスーパークラスのフィールドとメソッドが全て自動的に引き継がれている。 - speed: double # getSpeed(): double # startEngine () しかし、引き継がれているメソッドの処理内容を、サブクラスで再定義(変更)したい場合がある 。 Plane - altitude: double # takeOff () # startEngine () オーバーライドの必要性

オーバーライドと可視性 子クラスでオーバーライドするメソッドの可視性は、親クラスのメソッドの可視性により制限される public オーバーライドされるスーパークラスのメソッドに指定されている修飾子 オーバーライドするサブクラスのメソッド public public指定が必要 protected protectedかpublicが必要 private アクセス不可につき、オーバーライド不可 無指定 private指定は不可 親クラスでprotectedが指定されているメソッドを子クラスでオーバーライドするにはprotectedかpublic指定が必要

親・子クラスにおける オブジェクト参照型変数の互換性 Javaのきまり: 型の違いに厳しいJavaですが.. 子クラスのインスタンスを指すオブジェクト参照型変数を、親クラスの参照変数に代入することができる。 代入後も、インスタンスの出身が子クラスであることを忘れずに記憶しておく仕組みになっている。 1つのオブジェクトが、あたかも複数の型を持つかのように見せることができる。

オブジェクト指向3原則:ポリモーフィズム (再) (メソッドのオーバーライドと参照型変数の 互換性によって実現される) 乗り物 ジェット機クラスのインスタンスを、乗り物オブジェクトとして扱うことができる。 飛行機 自動車 ジェット機クラスのインスタンスに対する操作を、乗り物に対する操作として記述できる ジェット機 プロペラ機 このような記述の仕方にどんなメリットがあるの? ジェット機は飛行機でもあり、乗り物でもある

操作名は同じだが、実際の操作内容はそれぞれ異なる ジェット機 プロペラ機 乗り物 #動力を始動する() 飛行機 自動車 #動力を始動する() #動力を始動する() 操作名は同じだが、実際の操作内容はそれぞれ異なる ジェット機 プロペラ機 #動力を始動する() #動力を始動する() メソッドのオーバーライド

ジェット機クラスのインスタンスを生成する :ジェット機 new ジェット機(); このインスタンスを乗り物オブジェクトと見なす (乗り物オブジェクト変数 v1 に格納する) 乗り物 v1 = new ジェット機(); 乗り物クラス ジェット機クラスのインスタンスへの参照 動力を始動する()メッセージを送る この記法は、ジェット機に限らず、プロペラ機にも自動車にも、将来的に追加される乗り物にもそのまま変更なく使える。 v1.動力を始動する() 乗り物オブジェクトの操作が呼び出されるように記述されているが、自動的にジェット機オブジェクトに対する操作が呼び出される 上位概念(スーパークラス)オブジェクトに対する操作として記述しておくと、サブクラスの細かい修正や追加などに対して強いプログラムになる(保守性が高い)

ジェット機クラスのインスタンスを生成する :ジェット機 new ジェット機(); このインスタンスをジェット機オブジェクト変数 j1 に格納する ジェット機 j1 = new ジェット機(); ジェット機クラス ジェット機クラスのインスタンスへの参照 動力を始動する()メッセージを送る j1.動力を始動する() この記法では、プロペラ機や自動車に変更したり、さらには将来的に追加される乗り物に対しては、そのままでは使えない。プログラムの記述を変更する必要がある!

オブジェクト指向プログラミングの有効性! ポリモーフィズムの意味と効果 ポリモーフィズム(polymorphism)の意味:   1つのオブジェクトが複数の型を持つ ← 継承により実現 ポリモーフィズムの活用の仕方:   上位概念(スーパークラス)への操作としてプログラムを記述する その効果:   サブクラスの細かい修正や追加などに対して強い(保守性が高い)プログラムになる オブジェクト指向プログラミングの有効性!

参照型変数への代入 (例) class X { // スーパー(親)クラス int x; } SampleAP1001.java class X { // スーパー(親)クラス int x; } class Y extends X { // サブ(子)クラス int y; class SampleAP1001 { public static void main(String[] args){ X o = new Y();//サブクラスYのインスタンスを親クラスX } //の参照型変数へ代入できる!

メソッドのオーバーライド(例) class Shape { //2次元図形の面積を表現するクラス SampleAP1002.java class Shape { //2次元図形の面積を表現するクラス double a; //一般に、面積を計算するには、縦×横や底辺×高さ/2など、 double b; //2つの辺の長さを与える必要があると考え、変数を2つ用意する Shape(double x, double y) { a = x; b = y; } double getArea() { //ここでは具体的な定義を与えないことにする。 return 0.0; //具体的な定義はサブクラスで与える。

オーバーライド オーバーライド class Triangle extends Shape { //三角形 SampleAP1002.java続き class Triangle extends Shape { //三角形 Triangle(double x, double y); super(x,y); // x,yとしては底辺と高さを与える } double getArea() { return ( a * b / 2 ); class Rectangle extends Shape { //四角形 Rectangle (double x, double y){ super(x,y); //x,yとしては各辺の長さを与える return ( a * b ); オーバーライド オーバーライド

public static void main(String[] args) { SampleAP1002.java続き class SampleAP1002 { public static void main(String[] args) { Shape o1 = new Shape( 10.0, 10.0 ); Shape o2 = new Triangle( 10.0, 10.0 ); Shape o3 = new Rectangle( 10.0, 10.0 ); System.out.println("o1の面積は" + o1.getArea() ); System.out.println("o2の面積は" + o2.getArea() ); System.out.println("o3の面積は" + o3.getArea() ); }

引数に与えた数値はo1~o2まで全て同じだが、それぞれオーバーライドされたgetArea()メソッドが、異なる処理を実行している。 実行結果 o1の面積は0.0 o2の面積は50.0 o3の面積は100.0 引数に与えた数値はo1~o2まで全て同じだが、それぞれオーバーライドされたgetArea()メソッドが、異なる処理を実行している。

抽象クラス: 抽象メソッドを持つためオブジェクト生成できないクラス 抽象クラス: 抽象メソッドを持つためオブジェクト生成できないクラス 乗り物 クラス名をイタリックにすると 抽象クラス -スピード #スピードを変える() #スピードを表示する() 乗り物クラスのインスタンスは 存在しないことが保証される 飛行機 飛行機クラスでは、依然として スピードを表示する()操作は必須 であり、乗り物クラスは使われる。 -高度 #離陸する() #着陸する() #高度を表示する()

抽象メソッド: abstractキーワード 抽象クラスの実装 親クラスではメソッド名だけ定義して、子クラスにおいて、オーバーライドにより具体的な処理内容を記述する 抽象メソッド: abstractキーワード 具体的な処理内容が与えられていないため、インスタンスの作成は不可

抽象クラスの使用例 abstract class Shape { //抽象クラス double a; double b; SampleAP1003.java abstract class Shape { //抽象クラス double a; double b; Shape(double x, double y) { a = x; b = y; } //抽象メソッドとして定義(この方が自然) abstract double getArea(); 抽象メソッドが1つでもあるとそのクラスは抽象クラス →サブクラスで具体的な処理内容を与えて使用する 抽象クラスだからといって、全てが抽象クラスである必要は無い

class Triangle extends Shape { //三角形 Triangle(double x, double y); SampleAP1003.java続き この部分はSampleAP1002.javaと同じ class Triangle extends Shape { //三角形 Triangle(double x, double y); super(x,y); // x,yとしては底辺と高さを与える } double getArea() { return ( a * b / 2 ); class Rectangle extends Shape { //四角形 Rectangle (double x, double y){ super(x,y); //x,yとしては各辺の長さを与える return ( a * b );

抽象クラスのインスタンス化を削除 class SampleAP1003 { SampleAP1003.java続き class SampleAP1003 { public static void main(String[] args) { Shape o2 = new Triangle( 10.0, 10.0 ); Shape o3 = new Rectangle( 10.0, 10.0 ); System.out.println("o2の面積は" + o2.getArea() ); System.out.println("o3の面積は" + o3.getArea() ); } 抽象クラスのインスタンス化を削除

まとめ 継承の実装: extends キーワード 継承とコンストラクタ: superキーワード 継承の禁止: finalキーワード 継承とメソッドのオーバーライド 抽象メソッド、抽象クラス より保守性の高いプログラムの実現 世の中で既に作成され公開されている各種のJavaクラスライブラリはこのような考え方で作成されている。適当なクラスを継承してカスタマイズすることにより、極めて簡単に自分独自の問題を解決することができる。