第四章 类与对象
4.1 编程言语的几个发展阶段
1、面向机器语言
用诸如100011110110100这样的指令序列来编写
2、面向过程语言
采用自顶向下、逐步求精的程序设计方法,使用三种基本控制结构构造程序,即任何程序都可由顺序、选择、循环三种基本控制结构构造
3、面向对象语言
更加符合人的思维模式
三个特性:封装;继承;多态
4.2 类
java语言是面向对象语言,它的源程序是由若干个类组成的,源文件的扩展名为.java的文本文件。
类是java语言中最重要的“数据类型”,类声明的变量被称作对象,即类是用来创建对象的模板。
类的实现包括两部分:类声明和类体
其中:class是关键字,用来定义类。class 类名 是类的声明部分,类的声明必须是合法的java标识符。
4.2.1
写类的目的是为了描述一类事物共有的属性和功能。
给类命名时,遵守下列编程风格
1、如果类名使用字母,首字母大写。
2、取名字最好做到见名知意,当类名由几个“单词”复合而成时,每个单词首字母大写。
4.2.2 类体
类体被{}包含。
4.2.3 成员变量与局部变量
1、变量分为成员变量和局部变量
类体中定义的变量成为 成员变量,成员变量在整个类内部有效,其有效性与其在类体中书写的前后位置无关。
成员变量定义时有默认值
在方法体中定义的变量和方法的参数被称为 局部变量
局部变量只在定义它的方法内有效
局部变量在定义时没有默认值
2、成员变量又分为实例成员变量(简称实例变量)和类变量(也称静态变量)
如果成员变量的类型前面加上关键字static,这样的成员变量称为类变量或静态变量
其他变量称为实例变量
3、区分成员变量和局部变量
如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即该成员变量在这个方法内暂时失效。例如:
如果想在该方法中使用被隐藏的成员变量,必须使用关键字this
4、局部变量没有默认值
成员变量有默认值,但局部变量没有默认值,因此在使用局部变量之前,必须保证局部变量有具体的值。实例如下:
4.2.4 方法
方法的定义包括两部分:方法声明和方法体
一般格式:
1、方法声明部分(方法头)
方法头由方法的类型、名称和名称之后的一对小括号以及其中的参数列表所构成
例如
注意:方法返回的数据类型可以是java中的任何数据类型的一种,当一个方法不需要返回数据时,返回类型必须是void。
方法的参数在整个方法内有效,方法内的局部变量从声明塔的位置开始有效,如果局部变量声明在一个复合语句中,那么该局部变量的有效范围是该复合语句。如果局部变量的声明是在一个循环语句中,那么该局部变量的有效范围是该循环语句。实例如下
2、类方法和实例方法
类中的方法也可分为实例方法和类方法
方法声明时,方法类型前面不加关键字static是实例方法,加关键字static是类方法。
3、方法的分类
1)构造方法
构造方法是一种特殊方法,它的名字必须和它所在的类的名字完全相同,而且没有类型。
2)重载方法
方法重载的意思是:一个类中可以有多个方法具有相同名字,但这些方法的参数必须不相同,即或者参数个数不同,或者参数类型不同。方法的返回类型和参数的名字不参与比较。
方法重载是一种多态的体现
4.2.5 需要注意的问题
类体的内容由两部分构成:1、变量的声明 2、方法的定义
定义类需要注意的地方:
1)对成员变量的操作只能放在方法中,方法可以对成员变量和该方法中声明局部变量进行操作。在声明成员变量时可以赋予初值,但是不可用在类体中有单独的赋值语句,但局部变量必须赋初值。
2)实例方法既能对类变量操作也能对实例变量操作,而类方法只能对类变量操作。
3)一个类中的方法可以互相调用,实例方法可以调用该类中的其他方法,类中的类方法只能调用该类的类方法。
4.3 构造方法与对象的创建
和基本数据类型不同,在用类声明对象后,还必须要创建对象,即为声明的对象分配变量(确定对象所具有的属性),当使用一个类创建一个对象时,也称给出了这个类的一个实例。通俗的讲,类是创建对象的“模板”,没有类就没有对象。构造方法和对象的创建密切相关。
4.3.1 构造方法
构造方法是一种特殊的方法,它的名字必须与它所在的类的名字完全相同,而且没有类型。
允许一个类中编写若干个构造方法,但必须保证他们的参数不同,即参数个数 或 类型不同。
构造方法的作用是在创建对象时使用,主要是用来初始化各个成员变量,以便给类所创建的对象一个合理的初始状态。
需要注意的是如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句
如果类里定义了一个或多个构造方法,那java不提供默认的构造方法。
构造方法没有类型
4.3.2 创建对象
创建一个对象包括对象的声明和为对象分配变量两个步骤
1、对象的声明
2、为声明的对象分配变量
使用new运算符和类的构造方法为声明的对象分配变量,并返回一个引用值给对象名称,即创建对象,如果类中没有构造方法,系统会调用默认的构造方法,默认的构造方法是无参数的,且方法体中没有语句
static class circle{
int r=1;
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
}
public static void main(String[] args) {
circle c; //
c=new circle();
System.out.println(c.getR());
}
3、对象的内存模型
通过对象的声明和分配内存后,每个对象都对应两个值:引用值和实体值
1)声明对象时的内存模型
此时的引用值为null
2)对象分配变量后的内存模型
此时引用值和实体值都不为null
3)创建多个不同的对象
一个类通过使用new运算符可以创建多个不同的对象
如:XiyoujiRenwu() zhubajie=new XiyoujiRenwu();
XiyoujiRenwu() sunwukong=new XiyoujiRenwu();
4.3.3 使用对象
1、对象操作自己的变量(体现对象的属性)
通过运算符 “ . ” 来操作自己的变量
2、对象调用类中的方法(体现对象的行为)
通过.方法的方式来产生一定的行为
4.3.4 对象的引用和实体
一个类创建的两个对象,如果具有相同的引用,那么就具有完全相同的实体
例
假如使用如下赋值语句:
p1=p2;
即把p2中的引用赋给了p1,因此p1和p2本质上是一样
(由于java有内存垃圾自动回收机制,所以,p2赋值给p1之后,p1指向的实体就被回收了,这点比C语言要好)
4.4 类与程序的基本结构
一个java程序(也称一个工程)是由若干个类所构成的,这些类可以放在一个源文件中,也可以是多个。
4.5 参数传值
参数是局部变量,当对象调用方法时,参数被分配内存空间,并要求调用者向参数传递值,即方法被调用时,参数变量必须有具体的值。
4.5.1 传值机制
在java中,方法的所有参数都是“传值”的,也就是说,方法中参数变量的值是调用者指定的值
1、对于基本数据类型的参数,向该参数“传值”,传递的是值的拷贝
2、对于参数是引用型时,“传值”传递是变量的引用而不是变量所引用的实体,java的引用型数据包括 对象、数组和接口
4.5.2 基本数据类型参数的传值
4.5.3 引用类型参数的传值
4.5.4 可变参数
可变参数是指在声明方法时不给出参数列表中从某项开始直至最后一项参数的名字和个数,但这些参数的类型必须相同。
可变参数使用 “…” 表示若干个参数,这些参数的类型必须相同,并且最后一个参数必须是方法的参数列表中的最后一个参数。
getSum(1,2,3)返回的是1,2,3之和即1+2+3,为6;
4.6 对象的组合
一个类可以把对象作为自己的成员变量,
如果用这样的类创建对象,那么该对象中就会有其他对象,也就是说该对象将其他对象作为自己的组成部分,或者说该对象是由几个对象组合而成的
实例代码
public class test {
static class Circle {
double radius, area;
void setRadius(double r) {
radius = r;
}
double getRadius() {
return radius;
}
double getArea() {
area = 3.14 * radius * radius;
return area;
}
}
static class Circular {
Circle bottom;
double height;
void setBottom(Circle c) {
bottom = c;
}
void setHeight(double h) {
height = h;
}
double getVolme() {
if (bottom == null)
return -1;
else
return bottom.getArea() * height / 3.0;
}
double getBottomRadius() {
return bottom.getRadius();
}
public void setBottomRadius(double r) {
bottom.setRadius(r);
}
}
public static void main(String[] args) {
Circle circle = new Circle(); // 【代码1】
circle.setRadius(10); // 【代码2】
Circular circular = new Circular(); // 【代码3】
System.out.println("circle的引用:" + circle);
System.out.println("圆锥的bottom的引用:" + circular.bottom);
circular.setHeight(5);
circular.setBottom(circle); // 【代码4】
System.out.println("circle的引用:" + circle);
System.out.println("圆锥的bottom的引用:" + circular.bottom);
System.out.println("圆锥的体积:" + circular.getVolme());
System.out.println("修改circle的半径,bottom的半径同样变化");
circle.setRadius(20); // 【代码5】
System.out.println("bottom的半径:" + circular.getBottomRadius());
System.out.println("重新创建circle,cirlce的引用将发生变化");
circle = new Circle(); // 重新创建circle 【代码6】
System.out.println("circle的引用:" + circle);
System.out.println("但是不影响circular的bottom的引用");
System.out.println("圆锥的bottom的引用:" + circular.bottom);
}
}
4.6.1 组合与复用
示例
public class Example4_9 {
public static void main(String args[]) {
SIM simOne = new SIM(13889776509L);
MobileTelephone mobile = new MobileTelephone();
mobile.setSIM(simOne);
System.out.println("手机号码:"+mobile.lookNumber());
SIM simTwo = new SIM(15967563567L);
mobile.setSIM(simTwo);
System.out.println("手机号码:"+mobile.lookNumber());
}
}
public class MobileTelephone {
SIM sim;
void setSIM(SIM card) {
sim = card;
}
long lookNumber(){
return sim.getNumber();
}
}
public class SIM {
long number;
SIM(long number){
this.number = number;
}
long getNumber() {
return number;
}
}
4.6.2 关联关系和依赖关系的UML图
4.7 实例成员与类成员
1、实例变量和类变量的声明
在声明成员变量时,用关键字static修饰的是类变量(也称静态变量),否则称为实例变量
2、实例变量和类变量的区别
不同对象的实例变量互不相同
所有对象共享类变量
通过类名直接访问类变量
4.8 方法重载与多态
方法重载的意思:一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同,可以是参数个数、参数类型的不同。
4.9 this 关键字
this 是java的一个关键字,表示某一个对象,this 可以出现在实例方法和构造方法中,但不能出现在类方法中,this出现在构造方法中代表使用该构造方法所创建的对象,this出现在实例方法中代表正在调用该方法的当前对象
4.10 包
4.10.1 包语言
通过关键字package声明包语句
package语句作为java源文件的第一条语句,为该源文件中声明的类指定包名
package 语句格式:package 包名;
4.11 import 语句
一个类可能需要另一个类声明的对象作为自己的成员或方法中的局部变量,如果这两个类在同一个包中,没有问题,否则需要使用import语句
4.12.1 访问权限
当用一个类创建了一个对象之后,该对象可以通过 " . " 运算符操作自己的变量、使用类中的方法,但对象操作自己的变量和使用类中的方法是有一定限制的
访问限制修饰符有private 、 protected 、 public
4.12.2 私有变量和私有方法
用关键字private修饰的成员变量和方法称为私有变量和私有方法
对于私有成员变量或方法,只有在本类中创建该类的对象时,这个对象才能访问自己的私有成员变量和类中的私有方法
4.12.3 共有变量和共有方法
用关键字public修饰的成员变量和方法称为共有变量和共有方法
我们在任何一个类中用类A创建一个对象后,该对象能访问自己的public变量和类中的public方法
4.12.4 友好变量和友好方法
当另一个类中用类A创建一个对象后,如果这个类与A类在同一个包中,那么该对象能访问自己的友好变量和友好方法
在任一个与A同一包中的类中,也可以通过A类的类名访问A类的类友好成员和类友好方法
4.12.5 受保护的成员变量和方法
用protected修饰的成员变量和方法被称为受保护的成员变量和受保护的方法
4.12.6 public类与友好类
可以在任何另外一个类中使用public类创建对象
如果一个类不加public修饰,这样的类被称作友好类
在另外一个类中使用友好类创建对象时,要保证它们在同一包中
4.13 基本类型的类封装
java的基本数据类型
byte 、 int 、 short 、 long 、 float 、 double 、 char
java提供了基本数据类型相关的类,实现了对基本数据类型的封装
Byte 、 Integer 、 Short 、 Long 、 Float 、 Double、Character。这些类在java.lang包中
4.14 对象数组
声明10个Student对象,可以采用对象数组
Student [] stu=new Student[10];
声明之后,Student[0]~Student[9]都是空对象,需要创建对象
例如:Student[0]=new Student();