4 『ポリモーフィズム』
4.1 ポリモーフィズムを理解するためのサンプルプログラム
4.1.1 Sample1クラス図
4.1.2 サンプルプログラム(1)
リスト 4.1.2.1 Example1.java
1:
7: public class Example1 {
8:
9: public static void main(String[] args) {
10: Example1 example = new Example1();
11: example.main();
12: }
13:
14: void main() {
15: A a1 = new A();
16: a1.display();
17:
18: A a2 = new B();
19: a2.display();
20:
21: A a3 = new C();
22: a3.display();
23: }
24:
25: class A {
26: public void display() {
27: System.out.println("A#display()");
28: }
29: }
30:
31: class B extends A {
32: public void display() {
33: System.out.println("B#display()");
34: }
35: }
36:
37: class C extends A {
38: public void display() {
39: System.out.println("C#display()");
40: }
41: }
42: }
43:
44:
4.1.3 Sample2クラス図
4.1.4 サンプルプログラム(2)(配列)
リスト 4.1.4.1 Example2.java
1:
7: public class Example2 {
8:
9: public static void main(String[] args) {
10: Example2 example = new Example2();
11: example.main();
12: }
13:
14: void main() {
15: A[] aList = new A[5];
16: aList[0] = new B();
17: aList[1] = new A();
18: aList[2] = new C();
19: aList[3] = new B();
20: aList[4] = new C();
21:
22: for (int i = 0; i < aList.length; i++) {
23: aList[i].display();
24: }
25: }
26:
27: class A {
28: public void display() {
29: System.out.println("A#display()");
30: }
31: }
32:
33: class B extends A {
34: public void display() {
35: System.out.println("B#display()");
36: }
37: }
38:
39: class C extends A {
40: public void display() {
41: System.out.println("C#display()");
42: }
43: }
44: }
45:
46:
4.1.5 サンプルプログラム(3)(エラー)
リスト 4.1.5.1 Example3.java.error
1:
7: public class Example3 {
8:
9: public static void main(String[] args) {
10: Example3 example = new Example3();
11: example.main();
12: }
13:
14: void main() {
15: A a = new B();
16: a.display2();
17:
18: B b = new A();
19: b.display();
20: }
21:
22: class A {
23: public void display() {
24: System.out.println("A#display()");
25: }
26: }
27:
28: class B extends A {
29: public void display() {
30: System.out.println("B#display()");
31: }
32: public void display2() {
33: System.out.println("B#display2()");
34: }
35: }
36:
37: class C extends A {
38: public void display() {
39: System.out.println("C#display()");
40: }
41: }
42: }
43:
44:
4.1.6 サンプルプログラム(4)(ダウンキャスト)
リスト 4.1.6.1 Example4.java
1:
7: public class Example4 {
8:
9: public static void main(String[] args) {
10: Example4 example = new Example4();
11: example.main();
12: }
13:
14: void main() {
15: A a = new B();
16: B b = (B) a;
17:
18: a.display();
19: b.display();
20: b.display2();
21: }
22:
23: class A {
24: public void display() {
25: System.out.println("A#display()");
26: }
27: }
28:
29: class B extends A {
30: public void display() {
31: System.out.println("B#display()");
32: }
33: public void display2() {
34: System.out.println("B#display2()");
35: }
36: }
37:
38: class C extends A {
39: public void display() {
40: System.out.println("C#display()");
41: }
42: }
43: }
44:
45:
4.1.7 サンプルプログラム(5)(instanceof演算子)
リスト 4.1.7.1 Example5.java
1:
7: public class Example5 {
8:
9: public static void main(String[] args) {
10: Example5 example = new Example5();
11: example.main();
12: }
13:
14: void main() {
15: A[] aList = new A[3];
16: aList[0] = new B();
17: aList[1] = new A();
18: aList[2] = new C();
19:
20: for (int i = 0; i < aList.length; i++) {
21: System.out.println("aList[" + i + "] instanceof A = "
22: + (aList[i] instanceof A));
23: System.out.println("aList[" + i + "] instanceof B = "
24: + (aList[i] instanceof B));
25: System.out.println("aList[" + i + "] instanceof C = "
26: + (aList[i] instanceof C));
27: }
28:
29: for (int i = 0; i < aList.length; i++) {
30: if (aList[i] instanceof B) {
31: B b = (B) aList[i];
32: b.display2();
33: }
34: }
35: }
36: class A {
37: public void display() {
38: System.out.println("A#display()");
39: }
40: }
41:
42: class B extends A {
43: public void display() {
44: System.out.println("B#display()");
45: }
46: public void display2() {
47: System.out.println("B#display2()");
48: }
49: }
50:
51: class C extends A {
52: public void display() {
53: System.out.println("C#display()");
54: }
55: }
56:
57: }
58:
59:
64:
4.2 シューティングゲーム
4.2.1 シューティングゲームクラス図,インスタンス図
4.2.2 シューティングゲーム(4)(ポリモーフィズム)
リスト 4.2.2.1 ShootingGame4.java
1: import obpro.gui.BCanvas;
2: import obpro.gui.BWindow;
3: import obpro.sound.BSound;
4:
5:
12: public class ShootingGame4 {
13:
14: public static void main(String[] args) {
15: ShootingGame4 shootingGame = new ShootingGame4();
16: shootingGame.main();
17: }
18:
19:
20: private BWindow window;
21:
22:
23: private AnimationElement[] elements = new AnimationElement[1000];
24: private int elementSize = 0;
25:
26:
27: private Background background;
28: private PlayerAircraft player;
29: private EnemyAircraft[] enemies = new EnemyAircraft[100];
30: private Bullet[] bullets = new Bullet[20];
31:
32:
33: private BSound bgm;
34:
35: private void main() {
36: openWindow();
37: doAnimation();
38: }
39:
40:
41: private void openWindow() {
42: window = new BWindow();
43: window.setLocation(100, 100);
44: window.setSize(640, 480);
45: window.show();
46: }
47:
48:
49: void doAnimation() {
50: BCanvas canvas = window.getCanvas();
51: initializeElements();
52: initializeSounds();
53:
54:
55: bgm.loop();
56: while (true) {
57:
58: processOneStepForGame(canvas);
59: processOneStepForElements(canvas);
60:
61:
62: canvas.clear();
63: draw(canvas);
64: canvas.update();
65:
66:
67: canvas.sleep(0.01);
68: }
69: }
70:
71:
74: private void initializeElements() {
75:
76: background = new Background();
77: addElement(background);
78:
79:
80: player = new PlayerAircraft(50, 50, 100, 50);
81: addElement(player);
82:
83:
84: for (int i = 0; i < enemies.length; i++) {
85: enemies[i] = new EnemyAircraft(-100, -100, 100, 50);
86: addElement(enemies[i]);
87: }
88:
89:
90: for (int i = 0; i < bullets.length; i++) {
91: bullets[i] = new Bullet(-1, -1, 20, 10);
92: addElement(bullets[i]);
93: }
94: }
95:
96:
99: private void initializeSounds() {
100:
101: bgm = new BSound("sound/bgm.mp3");
102:
103:
104: BSound.load("sound/explode_enemy.mp3");
105: BSound.load("sound/explode_player.mp3");
106: BSound.load("sound/fire.mp3");
107: }
108:
109:
112: private void processOneStepForGame(BCanvas canvas) {
113:
114: if (canvas.isKeyPressing(37)) {
115: player.move(-5, 0);
116: }
117: if (canvas.isKeyPressing(38)) {
118: player.move(0, -5);
119: }
120: if (canvas.isKeyPressing(39)) {
121: player.move(5, 0);
122: }
123: if (canvas.isKeyPressing(40)) {
124: player.move(0, 5);
125: }
126:
127:
128: if (canvas.isKeyDown() && player.isAlive()) {
129: int keyCode = canvas.getKeyCode();
130: if (keyCode == 70) {
131:
132: for (int i = 0; i < bullets.length; i++) {
133: if (bullets[i].isAlive() == false) {
134: bullets[i].fire(player);
135: break;
136: }
137: }
138: }
139: }
140:
141:
142: int rnd = (int) (Math.random() * 30);
143: if (rnd == 0) {
144: int i = (int) (Math.random() * 100);
145: int y = (int) (Math.random() * canvas.getCanvasHeight());
146: enemies[i].show(canvas.getCanvasWidth(), y);
147: }
148:
149:
150: for (int i = 0; i < enemies.length; i++) {
151: if (enemies[i].isAlive() && player.intersects(enemies[i])) {
152: player.explode();
153: }
154: }
155:
156:
157: for (int i = 0; i < enemies.length; i++) {
158: for (int j = 0; j < bullets.length; j++) {
159: if (bullets[j].isAlive() && enemies[i].isAlive()
160: && enemies[i].intersects(bullets[j])) {
161: enemies[i].explode();
162: bullets[j].destroy();
163: }
164: }
165: }
166: }
167:
168:
171: private void processOneStepForElements(BCanvas canvas) {
172: for (int i = 0; i < elementSize; i++) {
173: elements[i].processOneStep(canvas);
174: }
175: }
176:
177:
180: private void draw(BCanvas canvas) {
181: for (int i = 0; i < elementSize; i++) {
182: elements[i].draw(canvas);
183: }
184: }
185:
186:
189: private void addElement(AnimationElement element) {
190: elements[elementSize] = element;
191: elementSize++;
192: }
193: }
4.2.3 アニメーションするオブジェクトすべてのスーパークラス
リスト 4.2.3.1 AnimationElement.java
1: import obpro.gui.BCanvas;
2:
3:
6: public class AnimationElement {
7:
8:
11: public void processOneStep(BCanvas canvas) {
12: }
13:
14:
17: public void draw(BCanvas canvas) {
18: }
19:
20: }
4.2.4 背景を表現するクラス
リスト 4.2.4.1 Background.java
1: import obpro.gui.BCanvas;
2:
3:
6: public class Background extends AnimationElement {
7:
8: private int x;
9:
10:
13: public void processOneStep(BCanvas canvas) {
14: x--;
15: }
16:
17:
20: public void draw(BCanvas canvas) {
21: canvas.drawImage("img/background.jpg", x, 0);
22: }
23:
24: }
4.2.5 シューティングゲームのキャラクターを表現するクラス
リスト 4.2.5.1 ShootingCharacter.java
1:
4: public class ShootingCharacter extends AnimationElement {
5:
6:
7: private int x = 0;
8: private int y = 0;
9: private int width = 0;
10: private int height = 0;
11:
12:
15: public ShootingCharacter(int x, int y, int width, int height) {
16: this.x = x;
17: this.y = y;
18: this.width = width;
19: this.height = height;
20: }
21:
22:
25: public int getHeight() {
26: return this.height;
27: }
28:
29:
32: public int getWidth() {
33: return this.width;
34: }
35:
36:
39: public int getX() {
40: return this.x;
41: }
42:
43:
46: public int getY() {
47: return this.y;
48: }
49:
50:
53: public void setLocation(int newX, int newY) {
54: x = newX;
55: y = newY;
56: }
57:
58:
61: public void move(int moveX, int moveY) {
62: x = x + moveX;
63: y = y + moveY;
64: }
65:
66:
69: public boolean intersects(ShootingCharacter another) {
70: int self_leftX = this.getX();
71: int self_rightX = this.getX() + this.getWidth();
72: int another_leftX = another.getX();
73: int another_rightX = another.getX() + another.getWidth();
74: int self_topY = this.getY();
75: int self_bottomY = this.getY() + this.getHeight();
76: int another_topY = another.getY();
77: int another_bottomY = another.getY() + another.getHeight();
78:
79: return (another_leftX < self_rightX && another_rightX > self_leftX
80: && another_topY < self_bottomY && another_bottomY > self_topY);
81: }
82: }
4.2.6 自機を表現するクラス
リスト 4.2.6.1 PlayerAircraft.java
1: import obpro.gui.BCanvas;
2: import obpro.sound.BSound;
3:
4:
7: public class PlayerAircraft extends ShootingCharacter {
8:
9:
10: private final int ALIVE = 1;
11: private final int EXPLODING = 2;
12: private final int DEAD = 3;
13:
14: private final int EXPLODING_ANIMATION_SIZE = 11;
15:
16:
17: private int liveState = ALIVE;
18: private int explodingCount = 0;
19:
20:
23: public PlayerAircraft(int x, int y, int width, int height) {
24: super(x, y, width, height);
25: }
26:
27:
30: public void processOneStep(BCanvas canvas) {
31: if (liveState == EXPLODING) {
32: processExplode();
33: }
34: }
35:
36:
39: public boolean isAlive() {
40: return liveState == ALIVE;
41: }
42:
43:
46: private void processExplode() {
47: explodingCount++;
48: if (explodingCount >= EXPLODING_ANIMATION_SIZE) {
49: liveState = DEAD;
50: }
51: }
52:
53:
56: public void explode() {
57: if (liveState == ALIVE) {
58: liveState = EXPLODING;
59: explodingCount = 0;
60: BSound.play("sound/explode_player.mp3");
61: }
62: }
63:
64:
67: public void draw(BCanvas canvas) {
68: if (liveState == ALIVE) {
69: drawAircraft(canvas);
70: } else if (liveState == EXPLODING) {
71: drawExplosion(canvas);
72: }
73: }
74:
75:
78: private void drawAircraft(BCanvas canvas) {
79: canvas.drawImage("img/player.png", getX(), getY(), getWidth(),
80: getHeight());
81: }
82:
83:
86: private void drawExplosion(BCanvas canvas) {
87: canvas.drawImage("img/explode" + (explodingCount + 1) + ".gif",
88: getX(), getY(), getWidth(), getHeight());
89: }
90: }
4.2.7 敵機を表現するクラス
リスト 4.2.7.1 EnemyAircraft.java
1: import obpro.gui.BCanvas;
2: import obpro.sound.BSound;
3:
4:
7: public class EnemyAircraft extends ShootingCharacter {
8:
9:
10: private final int ALIVE = 1;
11: private final int EXPLODING = 2;
12: private final int DEAD = 3;
13:
14: private final int EXPLODING_ANIMATION_SIZE = 11;
15:
16:
17: private int liveState = DEAD;
18: private int explodingCount = 0;
19:
20:
23: public EnemyAircraft(int x, int y, int width, int height) {
24: super(x, y, width, height);
25: }
26:
27:
30: public void processOneStep(BCanvas canvas) {
31: if (liveState == ALIVE) {
32: move(-5, 0);
33: } else if (liveState == EXPLODING) {
34: processExplode();
35: }
36: }
37:
38:
41: public boolean isAlive() {
42: return liveState == ALIVE;
43: }
44:
45:
48: public void show(int x, int y) {
49: if (liveState == DEAD) {
50: setLocation(x, y);
51: liveState = ALIVE;
52: }
53: }
54:
55:
58: private void processExplode() {
59: explodingCount++;
60: if (explodingCount >= EXPLODING_ANIMATION_SIZE) {
61: liveState = DEAD;
62: }
63: }
64:
65:
68: public void explode() {
69: if (liveState == ALIVE) {
70: liveState = EXPLODING;
71: explodingCount = 0;
72: BSound.play("sound/explode_enemy.mp3");
73: }
74: }
75:
76:
79: public void draw(BCanvas canvas) {
80: if (liveState == ALIVE) {
81: drawAircraft(canvas);
82: } else if (liveState == EXPLODING) {
83: drawExplosion(canvas);
84: }
85: }
86:
87:
90: private void drawAircraft(BCanvas canvas) {
91: canvas.drawImage("img/enemy.png", getX(), getY(), getWidth(),
92: getHeight());
93: }
94:
95:
98: private void drawExplosion(BCanvas canvas) {
99: canvas.drawImage("img/explode" + (explodingCount + 1) + ".gif", getX(),
100: getY(), getWidth(), getHeight());
101: }
102:
103: }
4.2.8 弾を表現するクラス
リスト 4.2.8.1 Bullet.java
1: import java.awt.Color;
2:
3: import obpro.gui.BCanvas;
4: import obpro.sound.BSound;
5:
6:
9: public class Bullet extends ShootingCharacter {
10:
11:
12: private final int ALIVE = 1;
13: private final int DEAD = 2;
14:
15:
16: private int liveState = DEAD;
17:
18:
19: private Color color = new Color(0, 0, 255);
20:
21:
24: public Bullet(int x, int y, int width, int height) {
25: super(x, y, width, height);
26: }
27:
28:
31: public void processOneStep(BCanvas canvas) {
32: if (liveState == ALIVE) {
33:
34: move(15, 0);
35:
36:
37: if (getX() > canvas.getCanvasWidth()) {
38: destroy();
39: }
40: }
41: }
42:
43:
46: public void fire(PlayerAircraft player) {
47: if (liveState == DEAD) {
48: int x = player.getX() + player.getWidth() / 2 - getWidth() / 2;
49: int y = player.getY() + player.getHeight() / 2 - getHeight() / 2;
50: setLocation(x, y);
51: liveState = ALIVE;
52: BSound.play("sound/fire.mp3");
53: }
54: }
55:
56:
59: public void destroy() {
60: if (liveState == ALIVE) {
61: liveState = DEAD;
62: }
63: }
64:
65:
68: public boolean isAlive() {
69: return liveState == ALIVE;
70: }
71:
72:
75: public void draw(BCanvas canvas) {
76: if (liveState == ALIVE) {
77: canvas.drawFillTriangle(color, getX(), getY(), getX() + getWidth(),
78: getY(), getX(), getY() + getHeight());
79: canvas.drawFillTriangle(color, getX(), getY() + getHeight(), getX()
80: + getWidth(), getY() + getHeight(), getX() + getWidth(),
81: getY());
82: }
83: }
84:
85: }