类和对象
对象
面向对象程序设计的思想是以对象来思考问题,首先要将现实世界的实体抽象为对象,然后考虑这个对象具备的属性(静态)和行为(动态)。例如,现在面临一个人要从武汉到北京可采取的方式,步骤如下:
- 首先可以从这一问题中抽象出对象,这里抽象出的对象为大雁。
- 然后识别这个对象的属性。对象具备的属性都是静态属性,如人的身高、体重等。
- 接着识别这个对象的动态行为,即这个人可以进行的动作,如读书、运动等,这些行为都是这个对象基于其属性而具有的动作。
- 识别出这个对象的属性和行为后,这个对象就被定义完成。然后可以根据这个人具有的特性制定他要从武汉到北京出行的具体方案。
究其本质,所有人都具有以上的属性和行为,可以将这些属性和行为封装起来,以描述人这类群体。由此可见,类实质上就是封装对象属性和行为的载体,而对象则是类抽象出来的一个实例。
对象的创建
语法:
Test test = new Test();
Test test = new Test(“a”);
设置值 | 描述 |
---|---|
Test | 类名 |
test | 创建Test类对象 |
new | 创建对象操作符 |
“a” | 构造方法的参数 |
访问对象的属性和行为
格式:
对象.成员变量
public class TransferProperty {
int i = 47; // 定义成员变量
public void call() { // 定义成员方法
System.out.println("调用call()方法");
for (i = 0; i < 3; i++) {
System.out.print(i + " ");
if (i == 2) {
System.out.println("\n");
}
}
}
public TransferProperty() { // 定义构造方法
}
public static void main(String[] args) {
TransferProperty t1 = new TransferProperty(); // 创建一个对象
TransferProperty t2 = new TransferProperty(); // 创建另一个对象
t2.i = 60; // 将类成员变量赋值为60
// 使用第一个对象调用类成员变量
System.out.println("第一个实例对象调用变量i的结果" + t1.i++);
t1.call(); // 使用第一个对象调用类成员方法
// 使用第二个对象调用类成员变量
System.out.println("第二个实例对象调用变量i的结果"+ t2.i);
t2.call(); // 使用第二个对象调用类成员变量
}
}
结果:
调用静态变量时:
public class TransferProperty {
static int i =47;
public void call() { // 定义成员方法
System.out.println("调用call()方法");
for (i = 0; i < 3; i++) {
System.out.print(i + " ");
if (i == 2) {
System.out.println("\n");
}
}
}
public TransferProperty() { // 定义构造方法
}
public static void main(String[] args) {
TransferProperty t1 = new TransferProperty();
TransferProperty t2 = new TransferProperty();
t2.i = 60;
System.out.println("第一个实例对象调用变量i的结果" + t1.i++);
t1.call();
System.out.println("第二个实例对象调用变量i的结果"+ t2.i);
t2.call();
}
}
当时没理解为什么第二个i结果是3,原因在于运行t1.call()方法时,在for循环中对i重新赋值,使i=0。若for(int i=0; i<3; i++)则 t2.i = 61,因为程序新建了一个i的内存区域。
程序给静态变量给定了一个固定的内存地址,所以当给t2.i赋值时,对象t1调用的i是同一个内存,即t1.i=60。
当然,虽然程序不会报错,但调用静态变量时这样写的格式不对。下面有讲到调用静态变量的格式应为类名.静态类变量。即代码应该写为TransferProperty . i
对象的引用
格式:
类名 对象引用名称
如Book book;
对象的比较
两种方式有着本质区别
- “ == ” 运算符
- equals() 方法
public class Compare {
public static void main(String[] args) {
String c1 = new String("abc"); // 创建两个String型对象引用
String c2 = new String("abc");
String c3 = c1; // 将c1对象引用赋予c3
// 使用“==”运算符比较c2与c3
System.out.println("c2==c3的运算结果为:" + (c2 == c3));
// 使用equals()方法比较c2与c3
System.out.println("c2.equals(c3)的运算结果为:" + (c2.equals(c3)));
}
}
- equals()方法是String类中的方法,用于比较两个对象引用所指的内容是否相等;
- “ == ” 运算符比较两个对象引用的地址是否相等。
类
具有相同属性和行为的一类实体被称为类。
在Java语言中,类中对象的行为是以方法的形式定义的,对象的属性是以成员变量形式定义的,所以类包括对象的属性和方法。
成员变量
public class Book{
private String name; //定义一个String型的成员变量
public String getName(){ //定义一个getName()方法
int id = 0; //局部变量
setName("Java"); //调用类中其他方法
return id + this.name; //设置方法返回值
}
private void setName(String name){ //定义一个setName()方法
this.name = name; //将参数值赋予类中的成员变量
}
public Book getBook(){
return this; //返回Book类引用
}
}
成员方法
语法格式:
权限修饰符 返回值类型 方法名(参数类型 参数名){
……//方法体
return 返回值;
}
Java中的成员方法无返回值,可以使用void关键字表示返回值类型
在成员方法中可以调用其他成员方法和类成员变量。如在getName()方法中调用了setName()方法将图书名称赋予一个值。同时在成员方法中可以定义一个变量,这个变量为局部变量。
局部变量
局部变量在使用时必须进行赋值操作或被初始化
this关键字
- 调用成员变量或成员方法
- 作为方法的返回值
public class Book{
private String name; //定义一个String型的成员变量
//setName()方法实现的功能是将形参name的值赋予成员变量name
private void setName(String name){ //定义一个setName()方法
this.name = name; //将参数值赋予类中的成员变量
}
}
成员变量与setName()方法中的形式参数的名称相同,都为name,那么该如何在类中区分使用的是哪一个变量呢?
- 规定使用this关键字
- this用于引用对象的成员变量和成员方法
如上述代码,this.name指的是Book类中的成员变量name,而this.name=name语句中的第二个name则指的是形参name。形参name在方法的作用域中覆盖了成员变量name,当局部变量或方法参数覆盖了成员变量时,就要添加this关键字明确引用的是类成员还是局部变量或方法参数。
静态变量
由static修饰的变量、常量和方法被称作静态变量、常量和方法。
调用格式:
类名.静态类成员
public class Math{
public static double PI =3.14; //定义静态变量
public double pi=3.15;
public static void method1(){ //定义静态方法
//do Something
}
public void method2(){
System.out.println(Math.PI); //调用静态变量
Math math= new Math();
System.out.println(math.pi);
Math.method1(); //调用静态方法
}
//编译器会报错
public static Math method3(){ //在类中定义一个静态方法
method2(); //调用非静态方法
return this; //在return语句中使用this关键字
}
}
虽然静态成员也可以使用“对象.静态成员”的形式进行调用,但通常不建议用这样的形式,因为这样容易混淆静态成员和非静态成员
上述代码在编译器中会报错, 是因为method3()方法为一个静态方法,而在其方法体中调用了非静态方法和this关键字。
在Java语言中对静态方法有两点规定:
- 在静态方法中不可以使用this关键字
- 在静态方法中不可以直接调用非静态方法
注意
在Java中规定不能将方法体内的局部变量声明为static的。例如下述代码就是错误的:
public class example{
public void method(){ //void和static冲突
static int i = 0;
}
}
技巧
如果在执行类时,希望先执行类的初始化动作,可以使用static定义一个静态区域,例如:
public class example{
static{
//some
}
}
当这段代码被执行时,首先执行static块中的程序,并且只会执行一次。
类的构造方法
构造方法的特点:
- 构造方法没有返回值 ,即不需要使用void关键字修饰
- 构造方法的名称要与本类的名称相同
语法格式:
public book(){
… //构造方法体
}
构造方法的名称一般和所在类的名称相同
在构造方法中可以为成员变量赋值,这样当实例化一个本类的对象时,相应的成员变量也将被初始化。
例:编写一个矩形类,将长与宽作为矩形类的属性,在构造方法中将长、宽初始化,定义一个成员方法求此矩形的面积。
public class Rectangle {
public double length;
public double width;
public Rectangle(double length, double width) { //构造方法
this.length = length;
this.width = width;
}
public double s() {
return length * width;
}
public static void main(String arg[]) {
Rectangle rectangle = new Rectangle(10,5);
System.out.println(rectangle.s());
}
}