这一节,我们要学会一些基本的实现类的操作,理解构造函数的作用和用法。
目录
一、实例变量和封装
1.变量
所谓的实例变量是一个变量(虽然很废话),变量嘛,就是一个存储单位,没错吧。那么我辛辛苦苦建立了一个类,我要用吧,用就一定会遇上实例(instance),这个实例可以是类的一个参数,也可以有其他用途,但我总归是要记录下来的,那就用到实例变量来存了。如果汉语看不懂,那么我用代码语言相信就能懂了。
public class Yourclassname
{
private int value;
// 设置私有变量(外端是不可访问的) 设置变量的类型 设置变量名
}
2.封装
咱们写代码是为了实现功能对吧?但是比如说,你这段代码的功能是实现计数,但是你总不能每次在写其他代码遇到需要计数的时候再写一遍或者复制一遍这段代码,太麻烦了。所以我们就需要封装,将一个或一群功能的代码封装起来,这样我们就可以简单地通过我们这个封装函数的名字来引入,然后通过这个封装的公共接口的方法来使用它。
说白了就是,比如你每次烧水,不用从大自然钻木取火和造壶开始烧水,直接去拿人家做好的热水壶插上电就可以烧水了。
举一个计数器的代码例子给说明一下,会更加生动。
package Chapter_3;
//这是模拟一个计数器
public class Counter {
private int value;
/**
* get value
*
* @return value
*/
public int getValue() {
return value;
}
/**
* add 1.
*/
public void click() {
count1++;
if (value < linited) {
value = value + 1;
}
}
/**
* reset 0
*/
public void reset() {
value = 0;
}
}
二、指定类的公共接口
刚刚我也说了,封装是为了更好地调用,那么这部分我们来学习一下调用所需要的公共接口。为了方便理解,就依照我教材上的例子来讲解:
首先是设计一个银行账户类(BankAccount)。
指定方法
第一章的时候就说过,方法分为访问器方法和修改器方法,这里也不例外。
可以想象,一个银行账户能包括的最基础的操作有哪些?
public double getBalance()
{
// 内部填入相关代码 比如下面的这个
return 0;
}
指定构造函数&为公共接口注释
构造函数是什么呢?是专门用来初始化对象的。它与方法类似,但是有两个重要的区别:
·构造函数名总是与类名相同
·构造函数没有返回类型(甚至没有void)
另外吧,有一个有道德的开发者,至少应该学会注释。不过注释也是有讲究的,比如:有参数的方法要加@parm、有返回值的要加@return。javadoc工具会会将注释格式化为统一的简洁文档,就像在官网上看到的API文档一样。
展示一下BankAccount类的代码:
package Chapter_3;
/**
* 账户有一个余额,
* 可以通过存钱和取钱改变这个余额。
*/
public class BankAccounter {
private double balance;
/**
* 构造一条余额为0的银行账户
*/
public BankAccounter() {
balance = 0;
}
/**
* 构造一个有初始余额的账户
*
* @param initialBalance 初始余额
*/
public BankAccounter(double initialBalance) {
balance = initialBalance;
}
/**
* 存钱
*
* @param amount 金额
*/
public void deposit(double amount) {
balance = balance + amount;
}
/**
* 取钱
*
* @param amount 金额
*/
public void withdraw(double amount) {
balance = balance - amount;
}
/**
* 得到当前余额
*
* @return 当前余额
*/
public double getBalance() {
return balance;
}
}
案例测试
package Chapter_3;
/**
* 测试BankAccount类的一个类
*/
public class BankAccountTester {
/**
* 测试BankAccount类的方法
*
* @param args 未用
*/
public static void main(String[] args) {
BankAccounter harryChecking = new BankAccounter();
// 建立银行账户
harryChecking.deposit(2000);
// 存款2000
harryChecking.withdraw(500);
// 取出500
System.out.println(harryChecking.getBalance());
// 调用方法得到现在的账户余额
System.out.println("Excepted:1500");
// 按照预计结果应该是1500
}
}
运行效果:
三、局部变量
局部变量指:在方法体中声明的一个变量。参数变量和局部变量是比较相似却又有区别:参数变量是在方法首部中声明,例如public void receivePayment(double amount),这个amount就是参数变量,而局部变量public double giveChange(){ double a=0;.......},这个a就是局部变量,并且局部变量是一定要初始化的,也就是说一定要赋值,不能只是double a;这样,否则编译器会报错。
但是两种变量也是很重要的一点共通就是:只在方法里面存在且有效,方法退出就立刻失效。
四、this的引用
this是用作隐式参数的,具体该怎么说清楚,我现在也不能保障可以做到,只能谈谈我的理解,不过好在,这个也不是什么强制学习的内容,觉得难的可以跳过,不影响。
有建立方法和调用方法这两种关于方法的方面。其中,实现时,对于每一个参数都要提供一个参数变量。但是调用的时候却不需要为调用这个方法的对象(比如ABC.deposit(500);这个当中ABC就是对象)提供相应的参数变量。这个对象就称之为隐式参数,所有的其他参数变量则称之为显示参数。
五、综合
这次,我们结合第三章和第二章的内容,搞一个大的。利用第二章的图形,第三章的封装、局部变量等等内容,做一个绘画汽车的例子。
// //CarComponent.java
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
/**
This component draws two car shapes.
*/
public class CarComponent extends JComponent
{
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Car car1 = new Car(0, 0);
int x = getWidth() - 60;
int y = getHeight() - 30;
Car car2 = new Car(x, y);
car1.draw(g2);
car2.draw(g2);
}
}
//Car.java
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
/**
A car shape that can be positioned anywhere on the screen.
*/
public class Car
{
private int xLeft;
private int yTop;
/**
Constructs a car with a given top left corner.
@param x the x coordinate of the top left corner
@param y the y coordinate of the top left corner
*/
public Car(int x, int y)
{
xLeft = x;
yTop = y;
}
/**
Draws the car.
@param g2 the graphics context
*/
public void draw(Graphics2D g2)
{
Rectangle body = new Rectangle(xLeft, yTop + 10, 60, 10);
Ellipse2D.Double frontTire
= new Ellipse2D.Double(xLeft + 10, yTop + 20, 10, 10);
Ellipse2D.Double rearTire
= new Ellipse2D.Double(xLeft + 40, yTop + 20, 10, 10);
// The bottom of the front windshield
Point2D.Double r1 = new Point2D.Double(xLeft + 10, yTop + 10);
// The front of the roof
Point2D.Double r2 = new Point2D.Double(xLeft + 20, yTop);
// The rear of the roof
Point2D.Double r3 = new Point2D.Double(xLeft + 40, yTop);
// The bottom of the rear windshield
Point2D.Double r4 = new Point2D.Double(xLeft + 50, yTop + 10);
Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
Line2D.Double roofTop = new Line2D.Double(r2, r3);
Line2D.Double rearWindshield = new Line2D.Double(r3, r4);
g2.draw(body);
g2.draw(frontTire);
g2.draw(rearTire);
g2.draw(frontWindshield);
g2.draw(roofTop);
g2.draw(rearWindshield);
}
}
// CarViewer.java
import javax.swing.JFrame;
public class CarViewer
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(300, 400);
frame.setTitle("Two cars");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CarComponent component = new CarComponent();
frame.add(component);
frame.setVisible(true);
}
}