[size=18][/size]
4.2 类与对象
4.2.1 类
在面向对象的语言中,类是个很重要的概念。面向对象的方法把所有的处理对象进行归类。具有相同性质的对象归为一类。例如学校里有很多学生,每个学生都是一个对象,而“学生”则是一个类,它包含了所有在学校学习的人。
在Java语言里,对象是一组描述对象的属性和操作方法的集合,其中属性表明对象的状态,方法表明对象的行为。类是对象的定义。一个对象具有哪些属性和方法,由类来决定。从编程角度看,类是一种复合数据类型,它封装了一组变量和方法(函数)。
声明一个类的一般形式如下所示:
修饰符 class 类名{
//类体
}
其中修饰符说明了类的属性,可以是public、abstract、final等。这些修饰符的含意将会在后继的章节中介绍。类体就是类的成员变量和成员方法的声明。修饰符和类体的声明都是可以选的。下面是一个“人”的类的声明,虽然类体是空的:
class Person{
}
4.2.2 对象
对象与类是不同但是又紧密相联的概念。类是对象的定义,对象由类来生成。类与对象的关系好比铸造车间里模具与产品的关系。模具只有一个,但是用这个模具可以浇铸出很多成型的产品出来,模具的形状决定了浇铸出来的产品的外形。在Java语言里用new关键字来生成对象,通常的格式为:
类名 对象名=new 类名([参数]);
这里的对象名可以是任意合法的Java标识符。new关键字后带小括号的类名称为构造方法(函数)。默认的、也是最简单的构造方法是不带参数的,也可以自定义不同形式的构造方法以供不时之需。下例利用刚才的Person类来生成两个Person对象Mike和John:
Person Mike=new Person();
Person John=new Person();
用new Person()生成一个对象时不仅分配了内存空间还进行了一些初始化的工作,对象所包含的不仅只是各个属性名了,而是属性的具体值。如果没有给属性赋值,虚拟机会自动给它们赋于相应数据类型默认的初值。生成一个对象的过程也称为实例化,所以一个对象就是一个实例。Mike和John是对象名,对象名是用来引用对象的,对象里的变量和方法可以通过对象名来引用,所以对象名也称为引用(Reference)。引用类似于C/C++中指针的概念,与指针不同,引用不是直接指向对象所在的内存位置,但是它包含了内存地址的信息。Java中并没有指针,以指针进行内存操作常造成不预知的错误,还可能破坏安全性,也正是因为如此,Java被认为是“安全的”编程语言。上例中生成的对象和引用如下图所示:
图4-1 引用与对象
在某些特殊的情况下,可能生成实例但不需要引用,那可以直接用new来实例化。如下所示:
new Person();
new Person();
上面两行程序生成两个Person对象,但是每次生成的对象分别占用不同的内存空间,改变其中一个对象的状态不会影响其它对象的状态。就象每次用模具倒出一个毛坯一样, 尽管两个毛坯看起来很象,但它们绝对是两个不同的毛坯。
4.2.3 成员变量
在面向对象的思想中,通常用属性来描述对象的特征。在编程语言里,这一组从属于某类对象的属性是用变量来表示的,例如前文提到用来表示人的特征的身高、体重、姓名等等,就可以分别用不同类型的变量:double型的height、float型weight、String型的name来表示。这些属于类的变量,称为类的成员变量。
声明成员变量的一般形式如下:
修饰符 数据类型 成员变量名;
其中修饰符说明了类的成员变量的属性,可以是public、protected、private、static、transient、final、volatile等等。成员变量的类型可以是Java内置的或者是自定义的复杂数据类型,包括简单类型、类、接口、数组。例如,描述一个人有一座房产可以用House类型的变量house来表示,这里的House是用户自定义的类(复杂数据类型)。调用成员变量的一般形式是:
实例名.成员变量名
下面是一个“人”的类的声明,类名是Person。描述“人”的成员变量有:height、weight、sex、name、age等,还有房产house的声明。
【例4-1】
class Person{
double height;
float weight;
char sex;
String name;
int age;
House house;
}
class House{}
public class E4_1{
public static void main(String args[]){
Person p_Bill=new Person();
p_Bill.age=26;
p_Bill.height=180;
p_Bill.weight=145;
p_Bill.sex='m';
p_Bill.name="Bill Gates";
p_Bill.house=new House();
}
}
Person类有6个成员变量,其中5个是简单数据类型,1个是复合数据类型House。在类E4_1的main函数里生成了一个引用名为p_Bill的对象。通过这个p_Bill这个引用可以访问到这个人的年龄、身高、体重等属性。
上例的程序可以在全部放在一个源文件中,源文件名为必须为E4_1。Java的一个源文件允许多个类的存在,但是文件名必须和public类一致,一个源文件中只也能有一个public类。
成员变量不需要显式初始化可以直接使用。其实,它们还是有被初始化过的,称为隐式的初始化。没有显式初始化的成员变量是在为对象分配存储空间时自动被初始化,各种类型的变量被赋于默认的初始化值,如下所示:
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'(null)
boolean false
所有复合数据类型 null
下例打印了隐式初始化的Person类成员变量。
【例4-2】
class Person{
double height;
float weight;
char sex;
String name;
int age;
House house;
}
class House{}
public class E4_2{
public static void main(String args[]){
Person p_Bill=new Person();
System.out.println(p_Bill.age);
System.out.println(p_Bill.height);
System.out.println(p_Bill.weight);
System.out.println(p_Bill.sex);
System.out.println(p_Bill.name);
System.out.println(p_Bill.house);
}
}
得到的结果是:
0
0.0
0.0
null
null
4.2.4 成员方法
对象的方法可以用来改变对象的属性,或者用来接收来自其它对象的信息以及向其它对象发送消息。从编程角度看,类是一组Java语句的集合。这里说的方法和面向过程语言C、Pascal等中的函数其实是一个概念。但是在象Java这样的纯面向对象的语言里,“函数”只能包含在类里面,而且是用来描述类的行为的,一般称为方法。
定义方法的一般形式如下所示:
修饰符 返回类型 方法名([参数类型 参数名,…])[throws 异常列表] {
//方法体
}
方括号中为可选项。修饰符可以是public、protected、private、static、final、abstract、native、synchronized等。返回类型既可以是简单数据类型,也可以是复合数据类型(数组、类或接口)。如果方法没有返回值,也必须在返回类型处用void声明。或者可以说,这个方法返回void类型。例如:void setHeight(){},但是,一旦方法声明某种返回类型,方法体中必须用return关键字返回和声明类型一致的数据。throws用来声明抛出异常,见第七章异常处理与断言。
调用对象方法的一般格式是:
引用名.方法名([参数列表]);
下例是一个person类比较完整的定义:
【例4-3】
public class E4_3{
public static void main(String args[]){
Person p=new Person();
p.setAge(30);
System.out.println(p.getAge());
}
}
class Person{
private double height;
private float weight;
private char sex;
private String name;
private int age;
public void setAge(int age) {
this.age = age;
}
public void setHeight(double height) {
this.height = height;
}
public void setName(String name) {
this.name = name;
}
public void setSex(char sex) {
this.sex = sex;
}
public void setWeight(float weight) {
this.weight = weight;
}
public int getAge() {
return age;
}
public float getWeight() {
return weight;
}
public char getSex() {
return sex;
}
public String getName() {
return name;
}
public double getHeight() {
return height;
}
}
在上例里,每个成员变量都有两个方法与之对应,分别是set和get方法。set方法用来改变成员变量的值,返回类型是void,而get方法用来获取成员变量的值,它们的方法体中都用return来返回与方法声明时一致的数据类型。该例中的this关键字用来引用当前对象。
方法的用法和面向过程语言中的函数的用法是一样的。但是,在Java语言里,没有独立于类之外的方法,所有的方法都在类里面,所以一般通过对象名来调用方法。有些静态(static)方法则可以用类名来调用。上例E4_3类的main方法里生成一个名为p的Person对象,通过p这个引用调用setAge()方法设置p的年龄,最后调用getAge()打印p的年龄。
方法体内可以包含所有合法的Java指令。可以声明该方法所用到的局部变量,它的作用域只在该方法内部,当方法调用结束时,局部变量也就失效了。如果方法体内的局部变量名和类的成员变量的名字相同,则类的成员变量被隐藏,也就是失效了,当前有效的是局部变量。
【例4-4】
public class E4_4{
int x=0,y=0,z=0;
void action(int x){
x=11;//参数x
y=12;//类成员变量y
int z=13;//方法内部变量z
System.out.println("在init()方法内部:");
System.out.println("成员变量:"+"x="+this.x+" y="+this.y+" z="+this.z);
System.out.println("局部变量:"+"x="+x+" z="+z);
}
public static void main(String args[]){
E4_4 e=new E4_4();
ystem.out.println("调用前:");
System.out.println("成员变量:"+"x="+e.x+" y="+e.y+" z="+e.z);
e.action(1);
System.out.println("调用后:");
System.out.println("成员变量:"+"x="+e.x+" y="+e.y+" z="+e.z);
}
}
程序的输出是:
调用前:
成员变量:x=0 y=0 z=0
在init()方法内部:
成员变量:x=0 y=12 z=0
局部变量:x=11 z=13
调用后:
成员变量:x=0 y=12 z=0
在上例的action方法里,参数x和新定义的变量z作用范围都只在action方法内部,因为它们和类成员变量x,z同名,所以类成员变量被覆盖。在action方法内部使用x和z都将调用参数x和局部变量z,而不是类成员变量。但这不并意味着无法在方法内部调用到成员变量。在上例中,我们用到了this。this代表调用该方法的当前对象(实例)。所以可以用this来调用该对象所有的成员变量和成员方法。
方法可以带多个参数,用逗号分隔开。对于简单数据类型,Java实现的是值传递, 方法接收参数的值,但不改变实参的值。对于复合数据类型,Java实现的是引用的传递,可以改变原参数的值。下例说明了简单数据类型与引用数据类型的区别。
【例4-5】
public class E4_5{
int i=0;
public void primary(int x){
x=3;
}
public void complex(E4_5 e2){
e2.i=3;
}
public static void main(String args[]){
E4_5 e=new E4_5();
System.out.println("调用primary前:e="+e.i);
e.primary(0);
System.out.println("调用primary后:e="+e.i);
System.out.println("调用complex前:e="+e.i);
e.complex(e);
System.out.println("调用complex后:e="+e.i);
}
}
上例的输出是:
调用primary前:e=0
调用primary后:e=0
调用complex前:e=0
调用complex后:e=3
我们在类E4_4中定义了两个方法:primary(int x)和 complex(E4_4 e)。primary方法接收的参数是int类型的值,方法内部对接收到值赋于新值3,但由于该方法接收的是简单数据类型,所以方法内值的修改不会影响方法外成员变量的值。而complex接收的参数是引用类型。这时,引用e和引用e2指向同一个对象,如下图所示:
图4-2 e和e2指向同一个对象
既然它们代表同一个对象,e2对该对象的修改自然就影响了引用e。
分享到:
相关推荐
本文实例讲述了Python面向对象之类和对象。分享给大家供大家参考,具体如下: 类和对象(1) 对象是什么? 对象=属性(静态)+方法(动态); 属性一般是一个个变量;方法是一个个函数; #类的属性 就是 类变量 #...
【JAVA 教学 PPt(接口,类和对象尤其详尽)】 在Java编程语言中,接口、类和对象是核心概念,对于理解和构建复杂的软件系统至关重要。让我们深入探讨这些主题。 1. 接口(Interface): Java中的接口是一种完全...
"C++ 类和对象"是C++编程中的核心概念,它们是实现面向对象编程(OOP)的基础。在这个主题中,我们将深入探讨类与对象的概念、它们的作用以及如何在实际编程中使用它们。 类是C++中的一个关键构造,可以看作是创建...
本文将深入探讨C#2005中面向对象编程的基石——类和对象,通过解析给定文件的信息,提炼并扩展相关知识点。 ### 类的概念 类在面向对象编程中扮演着中心角色,它不仅封装了数据,还封装了对这些数据进行操作的方法...
Java面向对象设计类和对象 Java面向对象设计类和对象是面向对象程序设计的基础,它将现实世界模型自然延伸到程序设计中。类和对象是面向对象设计的核心概念,类描述对象的属性和行为,对象是类的实例,是一个实实在...
类和对象的定义类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起。对象是具有类类型的变量
在深入探讨C++编程语言的面向对象编程特点时,我们需要理解类和对象的相关概念。C++是一种支持面向对象的编程语言,而面向对象编程(OOP)的中心思想是将数据以及与数据相关的操作封装在一起,形成对象,以解决特定...
C++是一种强大的面向对象编程(OOP)语言,它的核心特性之一就是类和对象。类是C++中定义数据类型的方式,它封装了数据和操作这些数据的方法,而对象则是类的实例,代表着程序中的实体或者概念。在这个“C++类和对象...
通过书籍,个人整理的java基础之类的对象的定义的有关知识点
JAVA类和对象及数组是JAVA编程语言的基础概念。下面是关于JAVA类和对象及数组的习题,涵盖了构造方法、继承、多重继承、变量声明、数组初始化等方面的知识点。 1. 构造方法的调用方式: 构造方法是类的特殊方法,...
java类和对象练习题.docx
对JAVA学习中的类和对象进行详细介绍,很好的编程学习资料
C++类和对象上机练习,相当好的东西,值得参考!希望对你有用!
在编程领域,类和对象是面向对象编程(Object-Oriented Programming, OOP)的核心概念。面向对象编程是一种软件开发方法,它强调将程序结构组织为一系列相互协作的对象,而不是单一的过程或函数。这种思想源自于对...
Java是一种面向对象的编程语言,其核心概念是类和对象。在Java中,类是创建对象的蓝图,它定义了对象的属性和行为。对象则是类的实例,具备类中定义的特性和功能。 3.1 类 在Java中,类是描述一类事物的模板,它...
C++类和对象 C++类和对象是面向对象编程(OOP)的基础概念,类是对对象的抽象描述,对象是现实世界中某个具体的物理实体在计算机逻辑中的映射和体现。现实中的对象都具有属性和行为。 类的概念 在C++中,类是一种...
综上所述,谭浩强的《C++类和对象》主要讲解了面向对象程序设计的基本概念,包括对象、类、封装性、信息隐蔽、抽象、继承和多态性。通过理解和掌握这些概念,开发者能够更有效地设计和构建大型、复杂的软件系统。在...
day11-类和对象 1. 类和对象 1.1 类和对象的理解【理解】 客观存在的事物皆为对象 ,所以我们也常常说万物皆对象。 类 类的理解 类是对现实生活中一类具有共同属性和行为的事物的抽象 类是对象的数据类型,类...