本任务带领大家使用面向对象方法定义自己的坦克类,并将其在面板上显示出来。和以前直接在面板上显示坦克图片相比,项目增加了一个Tank类,面板将会创建出坦克对象,并调用坦克对象的位置等属性进行显示。
类是由属性和方法构成的,属性由基本数据类型组成,方法用于描述类具有的功能和操作。在前面的任务中,我们编写过主方法main,调用过系统类提供的方法,下面我们将学习如何给自己定义的类编写方法。方法由五部分构成:
修饰符 返回值类型 方法名( 参数 ){
方法体
}
分别是访问修饰符、返回值类型、方法名、方法参数和方法体。
表明方法能被谁调用
每一个方法都可以返回信息,返回的信息必须是基本数据类型,因此在方法名前面我们需要定义方法返回值的类型。如果方法声明有返回值,则在方法体中必须使用return关键字返回一个值。如果方法不返回任何值,则必须声明为void。
编码规范要求首字母小写。
可选,参数用于方法接手调用者的信息,方法的参数在任务9中有详细介绍。
用于实现方法所表示的功能。
当我们使用Eclipse定义一个类时,会自动生成类的代码,我们只需要在类的{}括号里面编写相应的属性和方法即可。
定义一个类,实际就是将属性和方法打包在一起,在类中可以定义多个属性和方法,比如我们的坦克,它应该拥有名字、当前位置、速度、生命值等属性和移动、发射炮弹等方法。坦克的类图如8-2所示。
创建项目Project08,增加坦克Tank类。依据类图8-2,在坦克类中依次编写相关属性和方法,如代码清单8-1所示。
代码清单8-1:【Project08/src/Tank.java】
public class Tank {
//定义属性
String name = "坦克A";//名字
int lift = 100;//生命值
int speed = 10;//速度
//当前位置
int x = 100;
int y = 200;
//打印坦克信息
public void showTankInfo() {
System.out.println("坦克名字:" + name);
System.out.println("坦克生命值:" + lift);
System.out.println("坦克速度:" + speed);
System.out.println("坦克位置(" + x + ", " + y + ")");
}
//定义移动方法
public void move() {
System.out.println("移动");
}
//定义发射炮弹方法
public void fire(){
System.out.println("发射炮弹");
}
}
定义类之后,我们就可以通过new关键字创建出对象,并通过【对象名.属性】、【对象名.方法】访问属性和方法。类的属性和方法只有生成对象之后才能使用,不能直接通过【类名.属性】、【类名.方法】访问
在前面的任务学习中,我们一直在使用系统类提供的方法,现在我们来访问自己编写的类属性和方法,如代码清单8-2所示。
代码清单8-2:【Project08/src/Start.java】
public class Start {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建坦克对象
Tank tank = new Tank();
//使用.访问对象属性
System.out.println("坦克名称:" + tank.name);
System.out.println("坦克生命:" + tank.lift);
//修改坦克属性值
tank.lift = 50;
System.out.println("坦克生命:" + tank.lift);
//使用.访问对象方法
tank.move();
tank.fire();
}
}
封装是面向对象方法的重要原则,就是把你的类属性私有化,让其他用户无法访问和修改,而必须通过你提供的公共方法来操作。通过封装,其他用户不知道你的类中有那些私有属性,用户不会知道类中的内部细节。
在我们代码清单8-2中,启动类可以随意的修改坦克对象的生命值,坦克对象公开自己的属性让其它类访问是很危险的,必须有一种机制来保护自己的属性。Java提供了三种修饰符来控制属性和方法的访问权限,分别是public、protected和private,我们这里只介绍public和private修饰符,protected修饰符在单元9中介绍。
private修饰符表示私有的意思,表示只有自己才能使用,它常用在属性定义中,如:
private int lift = 100;//生命值
使用了private之后,在其它类中调用Tank对象访问此属性时,Eclipse代码提示将会找不到私有化的属性life,如图8-3所示。
如果强行输入访问代码,将会提示在tank对象中找不到life属性,如图所示。
要想访问私有化属性,则必须通过对象的提供的public方法,即访问Tank对象任何私有属性都必须通过Tank对象的允许。
public修饰符一般用在类和类的方法中,如:
public class Tank {} //公共类
public static void main(String[] args) {} //公共方法
public void move() //公共方法
使用了public修饰的类可以让其它类使用,使用了public修饰的方法可以让其它类直接调用。例如上面的坦克life私有属性,我们不能在其它类中直接访问它,那么就可以提供一个获取坦克生命值的公共方法和减少生命值的公共方法给其它类调用。
//减少生命值
public void reduceLife() {
lift = lift - 10;
}
然后在启动类中调用此方法,如代码清单8-3所示。
代码清单8-3:【Project08/src/Start.java】
public class Start {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建坦克对象
Tank tank = new Tank();
// 使用.访问对象属性
tank.showTankInfo();
//访问对象public方法,修改坦克属性值
tank.reduceLife();
tank.showTankInfo();
}
代码清单8-3:【Project08/src/Tank.java】
public class Tank {
// 定义私有属性
private String name = "坦克A";// 名字
private int lift = 100;// 生命值
private int speed = 10;// 速度
// 当前位置
private int x = 100;
private int y = 200;
//坦克外观
private String url = "img/tank.png";
// 打印坦克信息
public void showTankInfo() {
System.out.println("坦克名字:" + name);
System.out.println("坦克生命值:" + lift);
System.out.println("坦克速度:" + speed);
System.out.println("坦克位置(" + x + ", " + y + ")");
}
// 定义移动方法
public void move() {
System.out.println("移动");
}
// 定义发射炮弹方法
public void fire() {
System.out.println("发射炮弹");
}
//定义获取坐标、图片位置方法
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
在项目Project08中创建GamePanel面板类,如代码清单8-4所示。
代码清单8-4:【Project08/src/GamePanel.java】
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class GamePanel extends JPanel{
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
}
}
在面板类GamePanel中定义一个属性tank,并创建Tank类型对象。在面板绘制方法中通过调用坦克方法绘制坦克,如代码清单8-5所示。
代码清单8-5:【Project08/src/GamePanel.java】
……
public class GamePanel extends JPanel{
//创建坦克
Tank tank = new Tank();
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
//绘制坦克
ImageIcon icon = new ImageIcon(tank.getUrl());
g.drawImage(icon.getImage(), tank.getX(), tank.getY(), this);
}
}
在启动类中创建框架,并将面板加入框架显示,如代码清单8-6所示。
代码清单8-6:【Project08/src/Start.java】
public class Start {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame frame = new JFrame(“坦克”);
//创建面板加入框架
GamePanel gamePanel = new GamePanel();
frame.add(gamePanel );
//调用框架对象的设置大小方法
frame.setSize(300, 300);
//调用框架对象的显示方法
frame.setVisible(true);
}
}