本文共 5721 字,大约阅读时间需要 19 分钟。
面向对象是java语言最基本的特征之一。java中类和对象的基本概念。
对象是面向对象方法中的核心概念,也是理解面向对象技术的关键。
对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体。现实世界的对象拥有两个特征:状态和行为。而面向对象程序设计语言中的对象是以现实世界中对象为模型构造的,所以也具有状态与行为,其中状态保存在一组变量中,行为则通过方法实现。
对象的方法一方面把对象的内部变量包裹、保护起来,使得只有对象自己的方法才能操作这些内部变量;另一方面,对象的方法还是对象与外部环境和其他对象交互、通信的接口,外界对象通过这些接口驱动对象执行指定的行为,提供相应的服务。现实世界中所有对象都归属于某种对象类型。同一类型的对象具有共同的特征与行为。对象类型就是同种类型对象的集合与抽象。如我们开的小汽车,就是“车”这类交通工具中的一个实例。
对象类型在英语中称为Class of Objects,所以class(类)这个关键词来进行对象类型的定义。使用class定义的类在程序中称为一种抽象数据类型,它是面向对象程序设计语言的基本概念。一个类定义好后,我们就可以像使用其他数据类型一样,声明该类的变量并创建该变量所指向的对象,然后通过该变量调用对象的方法实现对对象的操作。 将类实例化就得到了现实世界实体的面向对象的映射——对象。 类描述了同一类对象都具有的数据和行为。java语言中的类将这些数据和行为封装起来,形成了一种复合数据类型。创建以个新类,就创建了一种新的数据类型。类定义一次,可以用new运算符实例化同一类的多个实力对象。因此类定义和描述了一类对象的共同特征。 实例: 定义一个描述雇员信息的类EmpInfo,在主函数中创建该类的实例对象并进行访问。class EmpInfo{ String name; String department; String tel; int age; public EmpInfo(String name, int age, String tel, String department){ //定义EmpInfo类的构造方法 this.name = name; this.department = department; this.tel = tel; this.age = age; } void print(){ System.out.println(this.name + " is " + this.age + ", tel is : " + this.tel + ", at " + department); }}public class ClassTest{ public static void main(String[] args){ EmpInfo emp1 = new EmpInfo("Jack", 25, "15666666666", "department of technology"); EmpInfo emp2 = new EmpInfo("Sam", 30, "17111111111", "department of technology"); emp1.print(); emp2.print(); } }
上例中定义了一个类EmpInfo,它相当于一个新类型,所以在主类的main()方法中,可以声明该类的变量,并通过实例化使这些变量指向该类的具体对象,程序中便可以通过变量访问相应的对象。
类有两种基本成分:变量和方法,称为成员变量和成员方法。类的成员变量可以是基本类型的数据或数组,也可以是一个类的实例;类的方法用于处理该类的数据。方法与其他语言中的函数的区别在于:
java类的定义分两部分:类的声明和类体。类体部分包括类成员变量的声明、构造方法和成员方法的声明与定义。
类的声明中,主要是声明类的名字以及类的其他属性。完整格式如下:
[public][abstract][final]class class_name[extends SupperClassName][implements interfaceNameList]{ //类体}
其中修饰符public、abstract或final说明了类的属性;extends关键词表示类继承了以SupperClassName为类名的父类;implements关键词表示类实现了interfaceNameList中列出的各个接口。这些修饰符的含义在后面都会逐一介绍。
类声明后的大括号{}中的部分就是类体。类体是一个类定义的主要部分。类体提供了这个类的对象在生命周期中需要的所有代码,包括构造和初始化新对象的构造方法,表示类及其对象状态的变量,实现类及其对象行为的方法,并且在极少数情况下还可以添加清除对象的finalize()方法,这些元素统称为类的成员。需要注意的是,虽然类的构造方法也在类的{}内,但是它却不是类的方法,也不是类的成员。
出现在类体中但在方法外的变量就是类的成员变量。类成员变量的基本声明与一般变量声明一样,必须包括类型与变量名,但是增加了很多可选的修饰选项。成员变量完整的声明格式如下:
[public|protected|private][static][final][transient][volatile] type varibleName;
修饰符解释:
public、protected或private说明了对该对象成员变量的访问权限。 static属性表示该成员变量为类变量,没有用static修饰符的成员变量为实例变量。 final用来声明一个常量,在程序中不能修改它的值,并且常量名应该由下划线分开的大写词表示,如MAX_NAME。 transient声明一个暂时性变量,默认情况下,类中所有变量都是对象永久状态的一部分,当对象被保存到外存时,这些变量必须同时被保存。但是用transient限定的变量则不属于对象永久状态,因而不能永久保存。 volatile修饰的变量,在被多个并发线程共享时,系统将采取更优化的控制方法提高线程并发执行效率。成员方法包括:方法声明和方法体。
成员方法的完整定义:[public | protected | private][static][final][abstract][native][synchronized]<方法名> ([ <参数列表> ])[throws ]{ //方法体} 参数列表> 方法名>
public|protected|private限定对成员方法的访问权限。
static指明它为类方法,而实例方法时不需要加static限定的。 abstract指明方法为抽象方法,没有实现体。 final指明方法不能被重写。 native表明方法用其他语言实现。 synchronized用来控制多个并发线程对共享数据的访问。 throws ExceptionList列出该方法将要抛出的异常。方法体是对方法的实现,它包括局部变量的声明以及所有合法的java语句。方法体中声明的局部变量,它的作用域只在该方法内部,当方法执行结束时,局部变量也将不存在了。如果局部变量的名字和类的成员变量的名字相同,则类的成员变量将被隐藏,如果要将该类成员变量显露出来,则需要在该变量的前面加上关键词this。
class EmpInfo{ private String name; private String department; private int age; public EmpInfo(String name, int age, String department){ this.name = name; this.department = department; this.age = age; } void emp(String nameE, int age, String departmentE){ String name = nameE; //name使同名类成员变量隐藏 String department = "财务部"; this.department = departmentE; this.age = age; //给类成员变量age赋值 System.out.println(name + " is " + this.age + ", at " + this.department); } public int getAge(){ return this.age; }}public class ClassTest{ public static void main(String[] args){ EmpInfo emp1 = new EmpInfo("Jack", 25, "department of technology"); emp1.emp("tom", 23, "TT"); int age = emp1.getAge(); System.out.println(age); } }
方法体中可以使用return语句退出该方法,使程序控制流返回到调用该方法的语句处。退出的return可以带返回值,也可以不带返回值。如果带了返回值,只需要在return关键词后加上相应的值或表达式即可,并且返回值的类型必须和方法声明中的返回值值类型一致。如果没有返回值,方法返回类型可以声明为void,既可以使用不带参数的return语句结束方法。
如:return; java中方法调用的参数传递方式是传值。即不会改变原变量的值。但是当方法的参数类型是对象或数组引用类型时,在方法调用中传递,传递给形参的仍然是对应变量的值,只不过这个值是对某个对象或数组的引用,即对象或数组所在内存空间的地址,所以在方法中可以直接对该参数指向的对象进行修改,并且方法退出时,对象的修改将会被保留,但是对象的引用不会被改变。class Info{ void printAge(int age){ //改变传进来参数的值 age += 5; } void changeArray(int[] a){ //改变传进来数组中的内容 for(int i = 0; i < a.length; i++){ a[i] *= i; } }}public class VarTest{ public static void main(String[] args){ int tomAge = 23; int[] a = { 1,2,4,5,3,6}; Info info = new Info(); info.printAge(tomAge); //打印主函数中的tomAge变量的值 System.out.println("tomAge is " + tomAge); info.changeArray(a); //打印主函数中数组a的内容 for (int i = 0; i < a.length; i++){ System.out.print(a[i] + " "); } }}
执行结果:
tomAge is 230 2 8 15 12 30
在主函数中,调用Info类的printAge方法并将主函数中的tomAge变量传进去(info.printAge(tomAge)),并且在方法中对传进的参数进行改变,然后再主函数中打印一下原变量tomAge的值,从打印的结果可以看出,变量的值并未改变,说明确实是传值,方法调用并未改变作为参数的变量的值。而在调用changeArray()方法时,将主函数的中数组a作为实参传进去了,由于数组是对象,传的是引用,所以在方法中对该数组的任何改变都会影响源数组中内容,由此出现了上面打印的结果。
转载地址:http://lcmdi.baihongyu.com/