Let's Re⇒move -39ページ目

Javaの授業 19 [ 抽象クラスと多態性 ]

今日のポイント
・抽象クラス
・多態性(ポリモルフィズム)とオーバーライド


抽象(abstract)メソッド
メソッドの本体のないメソッド。
public abstract void play(); ←{}がない。


抽象クラス
抽象メソッドを含むクラス

→サブクラスでのメソッドの実装を強要する
※抽象クラスはインスタンス化できない。



多態性(ポリモルフィズム) 】

[B] extends [A]の時
         
       [A]       [B]
  
フィールド int a     int b

メソッド void test1() void test2()

-----------------------------------------------
B obj = new B(); の時

objの持つフィールド:int a ,int b
メソッド :void test1(),void test2()
-----------------------------------------------
多態性
A obj1 = new B(); →[A]型の変数として[B]型のインスタンス作成が可能。
このとき
objの持つフィールド:int a
メソッド :void test1()
(※メソッドがオーバーライドされていた場合は[B]の上書きされたものを適用)

但しその後
B obj2 = (B)obj1
とすれば、obj2は[B]型の持つフィールド、メソッドも全て使用可。



サンプル
------------------------
Cook.java *抽象クラス
------------------------------------------------
abstract public class Cook {
String[] items; //調理器具一覧
String[] foods; //食材一覧

abstract public void itemPrepare(); //調理器具の準備
abstract public void foodPrepare(); //食材の準備
abstract public void create(); //調理

//料理をする
public void cook() {
itemPrepare();
foodPrepare();
create();
}
}
-------------------------------------------------
Cook1.java
-------------------------------------------------
//調理器具の準備
public void itemPrepare() {
items[0] = "ボウル";
items[1] = "フライパン";
}
//食材の準備
public void foodPrepare() {
foods[0] = "ミンチ";
foods[1] = "卵";
foods[2] = "たまねぎ";
}
//調理
public void create() {
System.out.println("ハンバーグを作ります");
System.out.println("必要な調理器具は");
for(int i = 0 ; i < items.length ; i++ ) {
System.out.println(items[i]);
}
System.out.println("必要な食材は");
for(int j = 0 ; j < foods.length ; j++ ) {
System.out.println(foods[j]);
}
System.out.println("以上の材料でハンバーグを作ります。");
}
}
-------------------------------------------------
Execute.java
-------------------------------------------------
public class Execute {
public static void main(String[] args) {
Cook hanburg = new Cook1();
hanburg.cook();
}
}
-------------------------------------------------

Javaの授業 18 [ スーパークラスとサブクラス② ]

スーパークラスとサブクラス②


コンストラクタの動きを見る

【シンプル継承サンプル4】(コンストラクタの動作)
-------------------------------------------------
Super.java * インスタンスが生成されるタイミングを見る
-------------------------------------------------
public class Super {
// Superクラスのデフォルトコンストラクタを明示的に記述する
public Super(){
System.out.println("Superクラスのコンストラクタ");
}
}
-------------------------------------------------

Sub.java

継承時のコンストラクタの呼び出しとインスタンスの生成タイミングを見る

※ スーパークラスのコンストラクタは継承されていないことに注意
-------------------------------------------------
public class Sub extends Super {
// Subクラスのデフォルトコンストラクタを明示的に記述する
public Sub(){
//Superクラスのコンストラクタ実行( Super();)が省略されている
System.out.println("Subクラスのコンストラクタ");
}
}
-------------------------------------------------

Expand.java * 実行ファイル
----------------------------------------
public class Execute {
public static void main(String[] args){
// Superクラスをインスタンス化した場合
System.out.println("Superのインスタンス化");
Super s = new Super();

// 改行
System.out.println();

// Subクラスをインスタンス化した場合
System.out.println("Subのインスタンス化");
Sub sub = new Sub();
}
}
-------------------------------------------------
※実行結果を見るとSubクラスのコンストラクタ実行直前に
 スーパークラスのコンストラクタが実行されることがわかる。



【シンプル継承サンプル5】(コンストラクタの動作)
-------------------------------------------------
Super.java
------------------------------
public class Super {
// フィールドの宣言
int x;

// デフォルトコンストラクタの記述
public Super(){
System.out.println("Superのデフォルトコンストラクタ");
x = 10;
}
// 引数のあるコンストラクタの記述
public Super(int x){
System.out.println("Superの引数ありのコンストラクタ");
this.x = x;
}
// xを出力するメソッド
public void printX(){
System.out.println("x = " + x);
}
}
-----------------------------------------------

Sub.java
コンストラクタにてインスタンス生成の処理が実行される際、
まず、継承元のスーパークラスのインスタンスが生成され、
その後継承を行ったサブクラスのインスタンスが生成される
土台・ベース部分をまず作り、そこに拡張した部分を追加生成するようなイメージ

明示的にスーパークラスのコンストラクタを呼び出す際は
「super」という記述を利用しsuper()のようにしてコンストラクタを呼び出す。
引数ありのコンストラクタを呼び出す際には
super()のカッコ中に引数に渡したいデータを記述する

※ ただし、このsuper()のようなスーパークラスのコンストラクタを呼び出す記述は
必ずサブクラスのコンストラクタの中で記述し、さらに処理の先頭に記述しなければならない
-------------------------------------------------
public class Sub extends Super {
public Sub(){
// スーパークラスのデフォルトコンストラクタを明示的に呼び出す
// この記述は省略可能
super();
System.out.println("Subクラスのデフォルトコンストラクタ");
}
public Sub(int x){
// スーパークラスの引数ありのコンストラクタを指定して呼び出す
// この記述を省略するとデフォルトコンストラクタが呼び出されてしまう
super(x);
System.out.println("Subクラスの引数ありコンストラクタ");
}
}
-------------------------------------------------

Execute.java
-------------------------------------------------
public class Execute {
public static void main(String[] args){
// 引数なしのコンストラクタでSubクラスのインスタンスを生成
Sub sub1 = new Sub();
// 引数ありのコンストラクタでSubクラスのインスタンスを生成
Sub sub2 = new Sub(20);

// スーパークラスで用意されているメソッドを使用しそれぞれのxの値を出力する
sub1.printX();
sub2.printX();
}
}
-------------------------------------------------
※今回はまず実行してから内容を追ってみて下さい。



☆オーバーライド(定義の上書き)

サンプル
-----------
Super2.java
---------------------------
class Super2 {
void method2() {
System.out.println("Super2");
}
}
---------------------------
Sub2.java
---------------------------
class Sub2 extends Super2 {
void method2() {
System.out.println("Sub2");
}
}
---------------------------
Execute.java
---------------------------------
class Execute {
public static void main(String[] args) {
Super2 super2 = new Super2();
Sub2 sub2 = new Sub2();

super2.method2();
sub2.method2();
}
}
---------------------------------
※実行してみる。


Javaの授業 17 [ スーパークラスとサブクラス① ]

スーパークラスとサブクラス


教科書[Java言語プログラミングレッスン 下]第12章


記述

------------------------------
public class Sub extends Super {
}

------------------------------
→SubクラスはSuperクラスを継承。

継承とは
フィールドやメソッドをそのまま使用することができる。



【シンプル継承サンプル1】
------------------------------------------------
Super.java * 継承を行うためのサンプル用スーパークラス
------------------------------------------------
public class Super {
}
// 中身がないので意味はないがクラスの継承を解説するため、
// 前節で解説したクラスの作成の必要最低限の記述のみされたクラス
------------------------------------------------

Sub.java * 継承を行うためのサンプル用サブクラス
------------------------------------------------
public class Sub extends Super {
}
// 通常のクラスの記述に加えて extends Super と記述することで
// Superというクラスを継承している

// 今回は例として継承のみを行っており中身の記述を行っていないので継承を行っている意味はないが
// これが継承を行うために記述する上での必要最低限の記述となる

// 名前がまぎらわしいが Superという名前のクラスをスーパークラスとし、
// そのサブクラスとしてSubという名前のクラスを宣言している

------------------------------------

Execute.java * 実行クラス
------------------------------------
public class Execute {
public static void main(String[] args){
// Superクラスのインスタンス化
// ※小文字で「super」と記述するとそれ単体で特別な意味を持つため変数名には使えない(色が変わるはず)

Super s = new Super();
// Subクラスのインスタンス化
Sub sub = new Sub();

// それぞれの番地情報を出力
System.out.println("s = " + s);
System.out.println("sub = " + sub);
}
}
// SuperクラスとSuperクラスを継承したSubクラスをそれぞれインスタンス化する。
// 今回はそれぞれのクラスに中身を記述していないので何も操作は出来ないが、
// インスタンスのアドレスを出力している

------------------------------------------------


【シンプル継承サンプル2】
------------------------------------------------
Super.java * フィールドとメソッドを持ったクラス
------------------------------------------------
public class Super {
int i;
String str;

void printName(){
System.out.println("Super!");
}
void printData(){
System.out.println("i = " + i);
System.out.println("str = " + str);
}
}
------------------------------------------------

Sub.java * Superクラスを継承しただけのSubクラスの宣言
------------------------------------------------
public class Sub extends Super {
}
// 今回もSubクラスを作っている意味はないがフィールドやメソッドを
// 継承するとはどういうことかを捉えて欲しい

------------------------------------------------

Execute.java *実行ファイル
-----------------------------
public class Execute {
public static void main(String[] args){
// Superクラスを継承しているSubクラスをインスタンス化
Sub sub = new Sub();

// Subクラスのインスタンスであるsubを通じてフィールドを操作
sub.i = 10;
sub.str = "test";

// subを通じてメソッドを操作
sub.printName();
sub.printData();

// インスタンスのアドレスを出力
System.out.println(sub);
}
}
------------------------------------------------


【シンプル継承サンプル3】
-----------------------------------------
Super.java * フィールドとメソッドを持ったクラス
-----------------------------------------
public class Super {
int i;
String str;

void printName(){
System.out.println("Super!");
}
void printData(){
System.out.println("i = " + i);
System.out.println("str = " + str);
}
}
------------------------------------------------

Sub.java * Superというクラスを継承し、処理を追加して拡張したクラス
------------------------------------------------
public class Sub extends Super {
// double型のフィールドを追加
double d;

// Sub!というメッセージとフィールドの値を出力するメソッドを追加
void subMethod(){
System.out.println("Sub!");
System.out.println("i + d = " + (i+d));
System.out.println("d = " + d);
}
}
------------------------------------------------

Execute.java * 実行ファイル
-----------------------------------------------
public class Execute {
public static void main(String[] args){
// Superというクラスをインスタンス化
Super s = new Super();
// Subというクラスをインスタンス化
Sub sub = new Sub();

System.out.println("Subのインスタンスに対する操作");
// Subのインスタンスに対する操作
sub.i = 100;
sub.str = "test";
sub.printName();
sub.printData();
// Subクラス独自の処理
sub.d = 15.3;
sub.subMethod();

System.out.println(); // 改行
System.out.println("Superのインスタンスに対する操作");
// Superのインスタンスに対する操作
s.i = 12;
s.str = "sample";
s.printName();
s.printData();

// Subというサブクラスで記述されている内容を呼ぼうとした場合
// コメントをはずすとエラー
// s.d = 10.0;
// s.subMethod();
}
}
------------------------------------------------
*今いきなり追いきれなくても仕方ないので後で確認すること。