1. final:最终的、不可改变的------------------应用率不高
- 修饰变量:变量不能被改变
- 修饰方法:方法不能被重写
- 修饰类:类不能被继承
2. static final常量:应用率高
- 必须声明同时初始化
- 常常由类名点来访问,不能被改变
- 建议:常量所有字母都大写,多个单词用_分隔
- 编译器在编译时会将常量直接替换为具体的数,效率高
- 何时用:数据永远不变,并且经常使用
3. 抽象方法:
- 由abstract修饰
- 只有方法的定义,没有具体的实现(连{}都没有)
4. 抽象类:
- 由abstract修饰
- 包含抽象方法的类必须是抽象类
- 抽象类不能被实例化(new对象)
- 抽象类是需要被继承的,派生类:
- 重写所有抽象方法-------------------变不完整为完整
- 也声明为抽象类----------------------一般不这么做
- 抽象类的意义:
- 封装共有的属性和行为------------------代码复用
- 为所有派生类提供统一的类型---------向上造型(代码复用)
- 可以包括抽象方法,为所有派生类提供统一的入口(向上造型后能点出来),同时达到强制重写的目的
package cn.tedu.submarine;
import javax.swing.ImageIcon;
import java.awt.Graphics;
import java.util.Random;
//海洋对象;
public abstract class SeaObject {
public static final int LIVE=0;
public static final int DEAD=1;
protected int state=LIVE;//默认为活着的
protected int width;//宽
protected int height;//高
protected int x;//x坐标
protected int y;//y坐标
protected int speed;//速度
//专门给潜艇们提供的
//因为三种潜艇的宽高不一样所以数据不能写死,需要传参写活;
public SeaObject(int width,int height){//给,鱼雷潜艇,水雷潜艇,侦察潜艇
this.width=width;
this.height=height;
x=width;
Random rand=new Random();
y= rand.nextInt(World.HEIGHT-height-150+1)+150;
speed=rand.nextInt(3)+1;
}
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 abstract void move();
public abstract ImageIcon getImage();
public boolean isLive(){
return state==LIVE;
}
public boolean isDead(){
return state==DEAD;
}
public void paintImage(Graphics g){
if(this.isLive()){
this.getImage().paintIcon(null,g,this.x,this.y);
}
}
}
package cn.tedu.submarine;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
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={
new ObserveSubmarine(),
new TorpedoSubmarine(),
new MineSubmarine()
};
private Mine[] mines={
new Mine(200,300)
};
private Bomb[] bombs={
new Bomb(300,400)
};
public void paint(Graphics g){
//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);
}
}
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()方法
}
}
补充:
1. 设计规则:
- 将派生类所共有的属性和行为,抽到超类中--------------------抽共性
- 若派生类的行为/代码都一样,设计为普通方法
若派生类的行为/代码不一样,设计为抽象方法
- ......-----------------后天讲
2. 抽象方法/抽象类的疑问:
- 抽象方法存在的意义是什么?
- 保证当发生向上造型时,通过超类的引用能点出来那个方法---------------保证能点出来
- 既然抽象方法的意义是保证能点出来,那为什么不设计为普通方法呢?
- 设计为普通方法,意味着派生类可以重写也可以不重写,但设计为抽象方法,则可以强制派生类必须重写-----------强制派生类重写,以达到统一的目的