-
类的基本结构
如果一切都是对象,那么是什么决定某一类对象的行为与外观呢?答案时“类”。类是构造对象的模板或蓝图。就像建筑物与设计图纸,通过一份设计图纸,可以构造处建筑物,而Java开发人员在编写代码时,实际上是编写类代码,对象只有程序运行时才存在。
当用户创建一个Java程序时,可以通过类声明来定义类。通常,这些类里没有main方法,只有一些属性和方法。一个完整的程序,应该由若干个类组成,其中一般只有一个类有main方法。
在Java中,最简单的类的定义语法为:
class 类名
{
//类中的代码
}
第一行称为类的声明。两个花括号之间的部分称为类体,类体中可以包含方法或成员变量。
例如下面代码定义了一个简单的类Student。
class Student { .......}
在具体的编程中,一个完整的类还包含构造函数、成员变量、方法等,将在后面逐一介绍。
-
类之间的关系
在面向对象的思想中,类之间存在一下几种常见的关系
1、USES-A 关系
“USES-A 关系” 是一种最明显、最常见的关系,若类A中的方法操纵了类B(对象)的成员,则称之为类A “USES-A” (用到了)类B。例如,汽车启动前检查汽油是否足够,例:
class Car
{
private int cubage=100;
public void startIsEnough()
{
if(cubage>80)
System.out.println("汽油充足,汽车可以启动");
else
System.out.println("汽车不可以启动");
}
}
public class Sample3_1
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Car c=new Car();
c.startIsEnough();
}
}
在上述例子中,main方法实例化Car类后,调用startIsEnough()方法,形成“IS-A”关系。因为汽油储量设备为100,满足储备量充足规则,可以启动,所以运行结果中打印了”汽油充足,可以启动”。
2、HAS-A关系
“HAS-A”关系是一种拥有关系,若类A中有B类型的成员引用变量,则类A“HAS-A”(即拥有)类型B。例如,轿车拥有轮胎:
class Car
{
private Type t=new Type();
public Type getTypeInfo()
{
return t;
}
}
class Type
{
private String material="橡胶" ;
private String color="黑色" ;
public String getMaterial()
{
return material;
}
public String getColor()
{
return color;
}
}
public class Sample3_2
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Car c=new Car();
System.out.println("轮胎的颜色为:"+c.getTypeInfo().getColor());
System.out.println("轮胎的材料为:"+c.getTypeInfo().getMaterial());
}
}
通过上述代码可以看出“HAS-A”关系的具体含义,由于汽车对象拥有了轮胎对象,所以汽车对象也就拥有了轮胎对象中的一切可见信息。
3、IS-A关系
在面向对象中“IS-A”的概念是基于继承的, 旨在表达一个类是另一个类的子类。也就是说,若类A是类B子类的一种,则可以说类A “IS-A”(是一种)类B。例如,“苹果”是“水果”的一种,则他们之间的关系为“苹果” IS-A(是一种)“水果”。
在实际开发中需要同时用到以上介绍的几种关系,要抓住现实世界中事物之间的实际关系来进行抽象,然后再Java世界中建立模型。如果搞错了关系的类型,有可能影响系统的开发或维护。
-
构造函数
在创建对象时,对象的成员可以由构造函数方法进行初始化。构造函数是一种特殊的方法,它具有和他所在的类完全一样的名字。一旦定义好一个构造函数,创建对象时就会自动调用它。构造函数没有返回类型,这是因为一个类的构造函数的返回值就是这个类本身。构造函数的任务就是初始化以一个对象的内部状态,所以用new操作符创建一个实例后,立刻就会得到一个可用的对象。例如,利用构造函数初始化汽车的各项参数:
package Car;
class Car
{
private String color;
private String brand;
//下面为构造函数,构造函数与类名相同。在构造函数中,初始化汽车的颜色和品牌
public Car()
{
this.color="黑色";
this.brand="大众";
}
//构造方法
public String getColor()
{
return this.color;
}
public String getBrand()
{
return this.brand;
}
}
public class Sample3_3
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Car c=new Car();
System.out.println("汽车的颜色为:"+c.getColor());
System.out.println("汽车的品牌为:"+c.getBrand());
}
}
在上面的例子中,main方法实例化Car类时,调用Car类的构造函数初始化类变量。在Car类中,构造函数是不包含任何参数的。有时也需要为构造函数定义参数,方便赋值,下面的例子同时定义了两个构造函数,分别带参数和不带参数:
package Car;
class Car
{
private String color;
private String brand;
//无参构造函数
public Car()
{
this.color="黑色";
this.brand="大众";
}
//有参构造函数
public Car(String co ,String br )
{
this.color=co;
this.brand=br;
}
//构造方法
public String getColor()
{
return this.color;
}
public String getBrand()
{
return this.brand;
}
}
public class Sample3_3
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Car c1=new Car();
System.out.println("汽车的颜色为:"+c1.getColor());
System.out.println("汽车的品牌为:"+c1.getBrand());
Car c2=new Car("红色","奥迪");
System.out.println("汽车的颜色为:"+c2.getColor());
System.out.println("汽车的品牌为:"+c2.getBrand());
}
}
上面说的例子当中,包含两个构造函数,有时一个类可能有多个构造函数,每个构造函数的参数类型均不相同,多个构造函数可看作方法的重载,只能根据参数类型匹配合适的构造函数。但构造方法与普通方法不同,是一种特殊的方法,具体有以下特点:
- 构造方法的方法名必须与类名相同
- 构造方法没有返回类型,也不能定义为void,在方法名面前不声明方法类型
- 构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域
- 构造方法不能由编程人员调用,而要系统调用
- 构造方法可以重载,以参数的个数,类型或排列顺序区分
- 一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参的默认构造器,这个构造器不执行任何代码
-
类成员
定义了类之后,就可以在类体中声明两种类的成员,成员变量与成员方法。
1、成员变量的使用
成员变量就是类的属性,类定义中的属性指定了一个对象区别于其他对象的值。例如,学生类的定义包括年龄、姓名和班级这些属性,每个对象的这些属性都有自己的值。所有由类定义建立的对象都共享类的方法,但是,它们都具有各自属性变量的副本。
成员变量有时也可以称为实例变量,其定义写在类体中:
class Student
{
public int stuAge;
public String stuName;
public String stuClass;
//年龄,姓名,班级
}
public class Sample3_5
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Student s1=new Student();
Student s2=new Student();
//为s1赋值
s1.stuAge=21;
s1.stuName="张三";
s1.stuClass="200801";
//为s2赋值
s2.stuAge=23;
s2.stuName="李四";
s2.stuClass="200802";
System.out.println(s1.stuName+' '+s1.stuAge+' '+s1.stuClass);
System.out.println(s2.stuName+' '+s2.stuAge+' '+s2.stuClass);
}
}
有点像C语言中的结构体,从上述例子中可以看出,两个对象成员变量有其各自的值,互不影响,new操作创建对象后将返回其引用值,一般在new操作完成后都将其返回的对象引用赋值给一个引用,也就是让引用指向创建的对象。如果只是用new操作创建对象不让某个引用指向该对象,则对象自创建后就不能对其进行访问了。因为在Java中,访问对象只能通过指向对象的引用来实现。
2、成员变量的初始值
变量类型 | 默认值 |
boolean | false |
char | '\u000' |
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0D |
对象引用型 | null |
对象引用型成员变量,其初始值为null,表示此引用没有指向任何对象,这里需要注意的是,字符串(String)类型空引用(null)与空字符串不同,空引用表示没有指向任何对象,而空字符串表示内容为空的字符串对象。
-
对象的创建
有了类就可以利用其创建对象了,在Java中创建对象很简单,只要用new关键字即可,由类创建对象的过程中称为实例化,每个对象是类的一个实例,如学生类是对什么是学生做定义,而张三、李四是学生类的实例。
创建对象与基本类型的声明类似,首先说明创建对象的所属类名,然后为对象的名称,例如 Student s=new Student();Student 为对象所属类,s为对象名称,通过new为新对象创建内存空间。与变量相比,对象的内存控件要大很多,因为对象是以类为模板创建的具体实列,具有属性和方法,例如s对象具有班级、姓名等属性,具有上课、下课等方法。如果要调用该对象则需要用点运算符' . '连接需要的属性和方法,例如s.name=“李四”;。