1.接口
- 是一种数据类型(引用数据类型)
- 由interface定义
- 只能包含常量和抽象方法
- 接口不能被实例化
- 接口是需要被实现/继承的,实现类/派生类:必须重写所有抽象方法
- 一个类可以实现多个接口,用逗号分隔,若又继承又实现时,应先继承后实现
- 接口可以继承接口
/*
演示接口的语法:
1)接口中的数据,默认都是常量。接口中的方法,默认都是抽象的。
2)接口中的所有内容的访问权限都一定是public的
*/
interface Inter{
public static final int NUM = 5;
public abstract void show();
int COUNT = 5; //默认public static final
void test(); //默认public abstract
//int number; //编译错误,常量必须声明同时初始化
//void show(){} //编译错误,抽象方法不能有方法体
}
//演示接口的实现:
interface Inter1{
void show();
void test();
}
class Aoo implements Inter1{
public void show(){} //重写接口中的抽象方法时,权限必须是public的
public void test(){}
}
//演示接口的多实现:
interface Inter2{
void show();
}
interface Inter3{
void test();
}
abstract class Boo{
abstract void say();
}
class Coo extends Boo implements Inter2,Inter3{
public void show(){}
public void test(){}
void say(){}
}
//演示接口继承接口:
interface Inter4{
void test();
}
interface Inter5 extends Inter4{ //自己的show()+继承过来的test()
void show();
}
class Doo implements Inter5{
public void show(){}
public void test(){}
}
public class InterfaceDemo {
public static void main(String[] args) {
//Inter5 o1 = new Inter5(); //编译错误,接口不能被实例化
Inter5 o2 = new Doo(); //向上造型
Inter4 o3 = new Doo(); //向上造型
}
}
2.潜艇游戏第八天:
1. 炸弹入场:
- 炸弹是由战舰发射出来的,所以在Battleship中设计shootBomb()生成炸弹对象
- 炸弹入场为事件触发的,所以在侦听器中重写keyReleased()按键抬起事件/keyPressed()按键按下事件,判断若按下的是空格键:
获取炸弹对象obj,bombs扩容,将obj添加到bombs最后一个元素上
2. 战舰移动:
- 战舰移动为战舰的行为,所以在Battleship中设计moveLeft()左移、moveRight()右移
- 战舰移动为事件触发的,所以在侦听器的重写keyReleased()中:
判断若抬起的是左键头,则战舰左移
判断若抬起的是右键头,则战舰右移
3. 删除越界的海洋对象:
- 在SeaObject中设计isOutOfBounds()检测潜艇是否越界,在Bomb和Mine中重写isOutOfBounds()检测炸弹和水雷是否越界
- 删除越界的海洋对象为定时发生的,所以在run()中调用outOfBoundsAction()实现删除越界的海洋对象
在outOfBoundsAction()中:
遍历潜艇数组,判断若越界了则:将越界的替换为最后一个元素,缩容
遍历水雷数组,判断若越界了则:将越界的替换为最后一个元素,缩容
遍历炸弹数组,判断若越界了则:将越界的替换为最后一个元素,缩容
4. 设计EnemyScore得分接口,ObserveSubmarine和TorpedoSubmarine实现得分接口
设计EnemyLife得分接口,MineSubmarine实现得命接口
2.1目录展示

2.1.1Battleship类
package cn.tedu.submarine;
import javax.swing.*;
import java.util.Objects;
/**
* 战舰
*/
public class Battleship extends SeaObject{
/**
* 命
*/
private int life;
public Battleship() {
super(66,26,270,124,5);
this.life = 5;
}
/**
* 战舰移动
*/
@Override
public void move() {
}
/**
* 战舰想左边移动
*/
public void moveLeft(){
if (this.x>0){
this.x-=speed;
}
}
/**
* 战舰想右边移动
*/
public void moveRight(){
if (this.x<World.WIDTH-this.width){
this.x+=speed;
}
}
@Override
public ImageIcon getImage() {
return Images.battleship;
}
/**
* 发射炸弹的方法
*/
public Bomb shootBomb(){
return new Bomb(this.x,this.y);
}
}
2.1.2Bomb类
package cn.tedu.submarine;
import javax.swing.*;
import java.util.Objects;
/**
* 炸弹
*/
public class Bomb extends SeaObject{
public Bomb(int x , int y) {
super(9,12,x,y,3);
}
/**
* 炸弹移动的方法
*/
@Override
public void move() {
y += speed;
}
@Override
public ImageIcon getImage() {
return Images.bomb;
}
}
2.1.3EnemyLife接口(今日新增)
package cn.tedu.submarine;
public interface EnemyLife {
/**
* 得命
*/
int getLife();
}
2.1.4EnemyScore接口(今日新增)
package cn.tedu.submarine;
public interface EnemyScore {
int getScore();
}
2.1.3Images类
package cn.tedu.submarine;
import javax.swing.ImageIcon;
public class Images {
/**
* 背景图
*/
public static ImageIcon sea;
/**
* 战舰图
*/
public static ImageIcon battleship;
/**
* 炸弹图片
*/
public static ImageIcon bomb;
/**
* 游戏结束
*/
public static ImageIcon gameover;
/**
* 水雷图片
*/
public static ImageIcon mine;
/**
* 水雷潜艇
*/
public static ImageIcon minesubm;
/**
* 侦察潜艇
*/
public static ImageIcon obsersubm;
/**
* 鱼类潜艇
*/
public static ImageIcon torpesubm;
/**
* 初始化图片
*/
static {
battleship = new ImageIcon("img/battleship.png");
sea = new ImageIcon("img/sea.png");
bomb = new ImageIcon("img/bomb.png");
gameover = new ImageIcon("img/gameover.png");
mine = new ImageIcon("img/mine.png");
minesubm = new ImageIcon("img/minesubm.png");
obsersubm = new ImageIcon("img/obsersubm.png");
torpesubm = new ImageIcon("img/torpesubm.png");
}
// /**
// * 测试图片
// * @param args
// */
// public static void main(String[] args) {
// //返回8表示成功了
// System.out.println(battleship.getImageLoadStatus());
// }
}
2.1.4Mine类
package cn.tedu.submarine;
import javax.swing.*;
import java.util.Objects;
/**
* 水雷
*/
public class Mine extends SeaObject{
public Mine(int x , int y) {
super(11,11,x,y,1);
}
/**
* 水雷移动的方法
*/
@Override
public void move() {
y-=speed;
}
@Override
public ImageIcon getImage() {
return Images.mine;
}
}
2.1.5MineSubMarine类
package cn.tedu.submarine;
import javax.swing.*;
import java.util.Objects;
import java.util.Random;
/**
* 水雷潜艇
*/
public class MineSubmarine extends SeaObject implements EnemyLife{
public MineSubmarine() {
super(63,19);
}
/**
* 水雷潜艇移动
*/
@Override
public void move() {
x+=speed;
}
@Override
public ImageIcon getImage() {
return Images.minesubm;
}
/**
* 发射水雷---生成水雷对象
* @return
*/
public Mine shootMine(){
return new Mine(this.x+this.width,this.y-11);
}
@Override
public int getLife() {
return 1;
}
}
2.1.6ObserverSubMarine类
package cn.tedu.submarine;
import javax.swing.*;
import java.util.Objects;
import java.util.Random;
/**
* 侦察潜艇
*/
public class ObserverSubmarine extends SeaObject implements EnemyScore{
public ObserverSubmarine() {
super(63,19);
}
/**
* 侦察潜艇移动
*/
@Override
public void move() {
x+=speed;
}
@Override
public ImageIcon getImage() {
return Images.obsersubm;
}
@Override
public int getScore() {
return 10;
}
}
2.1.7SeaObject类
package cn.tedu.submarine;
import javax.swing.*;
import java.awt.*;
import java.util.Random;
/**
* 海洋对象
*/
public abstract class SeaObject {
public static final int LIVE = 0;//或者的
public static final int DEAL = 1;//死了的
protected int state = LIVE;//当前状态(默认是活着的)
/**
* 成员变量一般都要private的
* 此处设计为protected
* 因为还没有讲到getter/setter
*/
/**
* 宽
*/
protected int width;
/**
* 高
*/
protected int height;
/**
* x轴
*/
protected int x;
/**
* y轴
*/
protected int y;
/**
* 速度
*/
protected int speed;
public SeaObject(int width,int height,int x , int y,int speed){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.speed = speed;
}
public SeaObject(int width,int height){
this.width = width;
this.height = height;
Random rand = new Random();
x = -width;
y = rand.nextInt(World.HEIGHT-height-150+1 ) +150;
this.speed = rand.nextInt(3)+1;
}
/**
* 移动的方法
*/
public abstract void move();
/**
* 获取对象的图片
*/
public abstract ImageIcon getImage();
/**
* 判断是活着的
* @return
*/
public boolean isLive(){
return state == LIVE;
}
/**
* 判断是死的吗
* @return
*/
public boolean isDeal(){
return state == DEAL;
}
/**
* 画图片
* @param g
*/
public void paintImage(Graphics g){
if (isLive()){//若或者的
//不要求掌握
this.getImage().paintIcon(null,g,this.x,this.y);
}
}
}
2.1.8TorpedoSubmarine类
package cn.tedu.submarine;
import javax.swing.*;
import java.util.Objects;
import java.util.Random;
/**
* 鱼类潜艇
*/
public class TorpedoSubmarine extends SeaObject implements EnemyScore{
public TorpedoSubmarine() {
super(64,20);
}
/**
* 鱼类潜艇移动的方法
*/
@Override
public void move() {
x+=speed;
}
@Override
public ImageIcon getImage() {
return Images.torpesubm;
}
@Override
public int getScore() {
return 40;
}
}
2.1.9World
package cn.tedu.submarine;
import javax.swing.*;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/**
* 整个游戏世界
*/
public class World extends JPanel {
public static final int WIDTH = 641;//窗口的宽
public static final int HEIGHT = 479;//窗口的高
private Battleship ship = new Battleship();//战舰
private SeaObject[] submarines = {};//潜艇数组(侦察潜艇,鱼雷潜艇,水雷潜艇)
private Mine[] mines = {
new Mine(200, 300)
};//水雷数组
private Bomb[] bombs = {
new Bomb(180, 130)
};//炸弹数组
public void action() {
KeyAdapter k = new KeyAdapter() {
/**
* 按键按下事件
* @param e
*/
@Override
public void keyPressed(KeyEvent e) {
//判断按的是不是空格键
if (e.getKeyCode() == KeyEvent.VK_LEFT){
ship.moveLeft();
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
ship.moveRight();
}
}
/**
* 重写keyReleased()按键抬起事件
* @param e
*/
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_SPACE){
Bomb bomb = ship.shootBomb();
bombs = Arrays.copyOf(bombs,bombs.length+1);
bombs[bombs.length-1] = bomb;
}
}
};
this.addKeyListener(k);//添加键盘的侦听器
Timer timer = new Timer();
int interval = 10;
timer.schedule(new TimerTask() {
@Override
public void run() {
submarineEnterAction();//敌人入场
minesEnterAction();//水雷入场
submarineMove();//潜艇移动
imageChuJie();//判断图片出界删除
repaint();//重新画一下
}
}, interval, interval);
}
/**
* 图片出界删除方法
*/
public void imageChuJie() {
for (int i = 0; i < submarines.length; i++) {
if (submarines[i].x>WIDTH){
submarines[i] = submarines[submarines.length-1];
submarines = Arrays.copyOf(submarines,submarines.length-1);
}
}
for (int i = 0; i < bombs.length; i++) {
if (bombs[i].y>HEIGHT){
bombs[i] = bombs[bombs.length-1];
bombs = Arrays.copyOf(bombs,bombs.length-1);
}
}
for (int i = 0; i < mines.length; i++) {
if (mines[i].y<150){
mines[i] = mines[mines.length-1];
mines = Arrays.copyOf(mines,mines.length-1);
}
}
}
/**
* 潜艇移动
*/
public void submarineMove() {
for (int i = 0; i < submarines.length; i++) {
submarines[i].move();
}
for (int i = 0; i < bombs.length; i++) {
bombs[i].move();
}
for (int i = 0; i < mines.length; i++) {
mines[i].move();
}
}
private int mineEnterIndex = 0;//水雷入场计数
/**
* 水雷入场
*/
public void minesEnterAction() {//没10个毫秒走一次
mineEnterIndex++;//没10毫秒增1
if (mineEnterIndex % 100 == 0){
}
}
private int subEnterIndex = 0;
/**
* 敌人入场
*/
public void submarineEnterAction() {
subEnterIndex++;
if (subEnterIndex%40 == 0){
SeaObject obj = nextSubmarine();
submarines = Arrays.copyOf(submarines,submarines.length+1);
submarines[submarines.length-1]=obj;
}
}
/**
* 生成潜艇对象
*/
public SeaObject nextSubmarine() {
Random random = new Random();
int type = random.nextInt(20);
if (type < 10) {
return new ObserverSubmarine();
} else if (type < 15) {
return new TorpedoSubmarine();
} else {
return new MineSubmarine();
}
}
/**
* 重写JPanel中的paint()画 g 画笔
*
* @param g
*/
@Override
public void paint(Graphics g) {
Images.sea.paintIcon(null, g, 0, 0);//海洋图片
ship.paintImage(g);
//画敌人
for (int i = 0; i < submarines.length; i++) {
submarines[i].paintImage(g);
}
//画水雷
for (int i = 0; i < mines.length; i++) {
mines[i].paintImage(g);
}
//画炸弹
for (int i = 0; i < bombs.length; i++) {
bombs[i].paintImage(g);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
World world = new World();
world.setFocusable(true);
frame.add(world);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH + 16, HEIGHT + 39);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
world.action();
}
}
3.补充
3.1类型间的关系:
- 类和类----------------------------继承extends
- 接口和接口----------------------继承extends
- 类和接口-------------------------实现implements
3.2对象可以向上造型为:
超类+所实现的接口
3.3设计规则:
- 将所有派生类所共有的属性和行为,抽到超类中------------------抽共性
- 若对象的行为都一样,设计为普通方法
若对象的行为都不一样,设计为抽象方法
- 将部分派生类所共有的属性和行为,抽到接口中
接口是对继承单根性的扩展------------------实现多继承
接口相当于制定了一个标准、规范---------随着后面课程的深入才能理解得更好
3.4如何调错:
- 快速锁定问题方法:
- 将所有方法的调用代码都注释掉
- 然后一个一个的放开,放开哪个出错了,说明问题就在哪个方法中
- 打桩:System.out.println(数据);-----------需要慢慢来,调得多了就有经验了
3.5明日单词:
1)hit:撞
2)other:另一个
3)instanceof:实例
4)cut:剪
5)cast:类型
6)go:去
7)draw:画
这篇博客介绍了Java中接口的概念及其在潜艇游戏中如何使用。主要内容包括接口的定义、潜艇游戏的更新,如炸弹入场、战舰移动以及删除越界对象的逻辑。同时,讲解了新添加的EnemyLife和EnemyScore接口,以及各对象之间的类型关系和设计原则。
568

被折叠的 条评论
为什么被折叠?



