1. 接口:
- 是一种引用数据类型
- 由interface定义
- 只能包含常量和抽象方法
- 接口不能被实例化(new对象)
- 接口是需要被实现/继承的,实现类/派生类:必须重写所有抽象方法
- 一个类可以实现多个接口,用逗号分隔,若又继承又实现时,应先继承后实现
- 接口可以继承接口
2.
1. 多态:多种形态
- 表现:
- 同一个对象被造型为不同的类型时,有不同的功能-----所有对象都是多态的(周一下午体会)
-----对象的多态:水、我、你......
- 同一类型的引用在指向不同的对象时,有不同的实现-----所有抽象方法都是多态的
-----行为的多态:cut()、getImage()、getScore()......
- 向上造型/自动类型转换:
- 超类型的引用指向派生类的对象
- 能点出来什么,看引用的类型
- 能造型成为的类型有:超类+所实现的接口
- 向下造型/强制类型转换,成功的条件只有如下两种:
- 引用所指向的对象,就是该类型
- 引用所指向的对象,实现了该接口或继承了该类
- 强转时若不符合如上条件,则发生ClassCastException类型转换异常
建议:在强转之前先通过instanceof判断引用指向的对象是否是该类型
> 注意:
>
> 1. instanceof为true的条件就是强转成功的条件
> 2. 何时需要强转:若想访问的变量/方法在超类中没有,则需要转换
补充:
1. 体会接口的好处:
复用性好、扩展性好、维护性好------------------高质量代码
2. 类间关系:
- 类和类-----------------------------继承
- 接口和接口-----------------------继承
- 类和接口--------------------------实现
3. 设计规则:
- 将所有派生类所共有的属性和行为,抽到超类中--------------------抽共性
- 若派生类的行为/代码都一样,设计为普通方法
若派生类的行为/代码不一样,设计为抽象方法
- 将部分派生类所共有的属性和行为,抽到接口中
- 接口是对继承的单根性的扩展------------------------------实现多继承
- 接口相当于制定了个标准、规范,实现了接口,意味着就能干那个事,不实现接口,就干不了那个事----------明天下午才能体会
4. 如何调错:---------------要求:你们在问项目经理之前,一定要先把问题方法锁定好,然后再问项目经理
- 快速锁定问题方法:
- 将调用方法的代码都注释起来,一个一个的放开运行,放开哪个方法出错,说明问题就在那个方法上
- 打桩:
- System.out.println(数据); //-----------------不能着急,得慢慢来,调得多了就有经验了
package cn.tedu.submarine;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
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={};
private Bomb[] bombs={};
//生成潜艇对象
private SeaObject nextSubmarine(){
Random rand=new Random();
int type=rand.nextInt(20);
if (type<10){
return new ObserveSubmarine();
}else if (type<15){
return new MineSubmarine();
}else{
return new TorpedoSubmarine();
}
}
//潜艇入场
private int submarineEnterIndex=0;
private void submarineEnterAction(){//每10毫秒写一次
submarineEnterIndex++;
if(submarineEnterIndex%40==0){//每40*10毫秒走一次
SeaObject obj=nextSubmarine();//生成潜艇
submarines= Arrays.copyOf(submarines,submarines.length+1);//将潜艇数组扩容,用来存放获取的潜艇
submarines[submarines.length-1]=obj;//将obj添加到潜艇数组的最后一个元素里
}
}
private int mineEnterIndex=0;
//水雷入场
private void mineEnterAction(){
mineEnterIndex++;
if(mineEnterIndex%100==0){
for (int i=0;i<submarines.length;i++)
if(submarines[i] instanceof MineSubmarine){
MineSubmarine ms=(MineSubmarine) submarines[i];
Mine obj=ms.shootMine();
mines=Arrays.copyOf(mines,mines.length+1);
mines[mines.length-1]=obj;
}
}
}
//海洋对象移动
private void moveAction(){
for(int i=0;i<submarines.length;i++){
submarines[i].move();
}
for(int i=0;i<mines.length;i++){
mines[i].move();
}
for(int i=0;i<bombs.length;i++){
bombs[i].move();
}
}
//删除越界对象
private void outOfBoundsAction(){
for(int i=0;i<submarines.length;i++){
if(submarines[i].isOutOfBounds() || submarines[i].isDead()) {
submarines[i]=submarines[submarines.length-1];//将越界的元素编程最后一个元素
submarines=Arrays.copyOf(submarines,submarines.length-1);
}
}
for(int i=0;i<mines.length;i++){
if(mines[i].isOutOfBounds() || mines[i].isDead()) {
mines[i]=mines[mines.length-1];//将越界的元素编程最后一个元素
mines=Arrays.copyOf(mines,mines.length-1);
}
}
for(int i=0;i<bombs.length;i++){
if(bombs[i].isOutOfBounds() || bombs[i].isDead()) {
bombs[i]=bombs[bombs.length-1];//将越界的元素编程最后一个元素
bombs=Arrays.copyOf(bombs,bombs.length-1);
}
}
}
private int score=0;//玩家得分
//炸弹和潜艇的碰撞
private void bombBangAction(){
for(int i=0;i<bombs.length;i++){
Bomb b=bombs[i];
for(int j=0;j<submarines.length;j++){
SeaObject s=submarines[j];
if(b.isLive()&&s.isLive() && s.isHit(b)){
s.goDead();
b.goDead();
if(s instanceof EnemyScore){
EnemyScore es=(EnemyScore) s;
score+=es.getScore();
}
if(s instanceof EnemyLife){
EnemyLife el=(EnemyLife) s;
int num=el.getLive();
ship.addLive(num);
}
}
}
}
}
/*启动程序执行*/
private void action(){
//侦听器:
KeyAdapter k=new KeyAdapter() {
@Override//重写案按键抬起事件
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if(e.getKeyCode()==KeyEvent.VK_SPACE){
Bomb obj=ship.shootBomb();
bombs=Arrays.copyOf(bombs,bombs.length+1);
bombs[bombs.length-1]=obj;
}
if(e.getKeyCode()==KeyEvent.VK_LEFT){
ship.moveLeft();
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
ship.moveRight();
}
}
};//侦听器对象
this.addKeyListener(k);//添加侦听器
//定时器
Timer timer=new Timer();//定时器的对象
int interval=10;
timer.schedule(new TimerTask() {//创建一个匿名内部类
@Override
public void run() {//定时干的事情
submarineEnterAction();//潜艇入场
mineEnterAction();
moveAction();
outOfBoundsAction();
bombBangAction();
repaint();//重新调用paint()重画
}
}, interval, interval);//定时计划表
}
//画海洋对象
public void paint(Graphics g){//每10毫秒走一次,
//this.getImage().paintIcon(null,g,this.x,this.y);
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);
}
g.drawString("Score:"+score,200,50);
g.drawString("Life:"+ship.getLife(),400,50);
}
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.setResizable(false);
frame.setVisible(true);//自动调用paint()方法
world.action();
}
}