Version 3.0
第三章类和对象
2
回顾
Java 具有 8种基本数据类型,int,boolean、
char,short,long,float 及 double
Java 中的运算符可划分为四大子集:算术运算符、位运算符、关系运算符、逻辑运算符
Java 支持下列控制结构:选择、循环、跳转
数组可用来将同一类型的数据存储在连续的内存位置
3
目标
掌握如何创建类和构造对象
掌握方法的重载和覆盖
了解类的继承
了解包概念
4
类和对象 2-1
对象表示现实世界中某个具体的事物。
抽象是从特定的实例中抽取共同的性质以形成一般化概念的过程。
对象具有两方面的含义:
在现实世界中:
是客观世界中的一个实体
在计算机世界中:
是一个可标识的存储区域
5
类和对象 2-2
类是具有共同属性和行为的对象的抽象。
类可以定义为数据和方法的集合 。
类也称为模板,因为它们提供了对象的基本框架。
类对象抽象实例化属性或状态操作或行为数据或变量方法封装的实体 =数据 +方法
6
创建类
class name {
type variable1;

type variableN;
type methodname1(parameter-list){
//方法体
}

type methodnameN(parameter-list){
//方法体
}
}
在类中,属性是通过成员变量体现的,而操作是用成员函数(又称为方法)实现的。
Java中定义类的通用格式:
成员变量(对象属性)
成员方法
(对象行为或操作)
7
定义方法
定义方法的一般格式:
[access] type methodname1([parameter-list]){
//方法体
}
发往某个对象的消息对应于一个方法调用。作为对消息的响应,对象将执行一个类似于过程体的方法。方法是包含在类中的函数。
方法名称返回类型修饰符,
可选 参数列表,可选
举例:
public void setdate(int day,int month,int
year){
day=23; month=7; year=2003;
}
8
对象作为参数
class Test{
int a,b;
Test(int i,int j) {
a=i;
b=j;
}
//可以在函数中改变 对象状态
void change(Test obj)
{
obj.a=50;
obj.b=40;
}
}
当对象作为函数参数时,
在函数中只能改变该对象的状态,但不能改变该对象的引用
void swapobj(Day x,Day y){
Day temp=y;
y=x;
x=temp;
}
引用本身按值传递
Day
2002,5,30
Day
2003,7,23
obj1
obj2
x
y
调用 swapobj(obj1,obj2)
改变对象状态
9
this引用
public class PassTest {
int x;
PassTest(int x) {
this.x=x;
}
public void passingValue(){
System.out.println(“x 等于 " +x);
}
public static void main(String args[]) {
PassTest test = new PassTest(10);
test.passingValue();
}
}
关键字 this 与对象关联
它用于指示当前对象指明此对象的变量 x 应赋值为通过构造函数传递的自变量 x
的值。
10
简单访问控制 - private 和 public
public 声明的数据成员和成员函数可从类外部的任何地方访问。
而 private 数据将被隐藏,
在类外不可见,这就实现了数据封装的思想。
要从类外操纵 private 成员,
只能通过类的 public或
protected成员来实现。
11
方法重载( overloading)
方法重载是 Java实现面向对象的多态性机制的一种方式。
同一个类中多个方法有相同的名字,不同的参数列表,这种情况称为方法重载 。
返回类型不同并不足以构成方法重载。
当重载方法被调用时,编译器根据参数的类型和数量来确定实际调用哪个重载方法的版本。
12
方法重载示例
class Calculation {
public void add( int a,int b) {
int c = a + b;
System.out.println("两个整数相加得 "+ c);
}
public void add( float a,float b){
float c = a + b;
System.out.println("两个浮点数相加得 "+c);
}
public void add( String a,String b) {
String c = a + b;
System.out.println("两个字符串相加得 "+ c);
}
}
class CalculationDemo {
public static void
main(String args[]) {
Calculation c = new
Calculation();
c.add(10,20);
c.add(40.0F,35.65F);
c.add("早上 ","好 ");
}
} 编译器决定调用版本
13
构造函数
构造函数名称与类名称相同
构造函数没有返回类型
其任务是在创建对象时初始化其内部状态
class Fruit {
boolean seedLess;
boolean seasonal;
float price;
Fruit(boolean seed,boolean season,float p) {
seedLess = seed;
seasonal = season;
price = p;
}
}
14
创建对象
使用下列语法可创建对象:
new 构造函数
关键字 new 通常称为创建运算符,用于分配对象内存,并将该内存初始化为缺省值。
一旦 new 完成分配和初始化内存,它就将调用构造函数来执行对象初始化。
当创建一个类时,只是创建了一种新的数据类型。对象是类的一个实例。
class FruitDemo {
public static void main(String args[]){
Fruit f = new Fruit(true,false,50.0F);
}
} 创建对象
15
缺省初始值
Java 保证了在任何代码使用该内存之前,
已至少将内存初始化为可预知的缺省值类型 缺省值 类型 缺省值
byte (byte)0 char '\u0000 '
short (short)0 float 0.0F
int 0 double 0.0D
long 0L 对象引用 null
boolean false
16
重载构造函数
Java 为每一个类自动提供缺省构造函数
缺省构造函数将成员变量的值初始化为缺省值
一旦创建了自己的构造函数,缺省的构造函数将不复存在。
重载构造函数提供了一组创建对象的方式,可以根据需要决定是否带初始参数。
public class constructOverload {
int x;
constructOverload() {
x=0;
System.out.println("不带参数的构造函数 ");
}
constructOverload(int x){
this.x=x;
System.out.println("带一个参数的构造函数 ");
}
}
17
继承
被继承的类称为父类
继承父类的类称为子类
执行继承时,子类将获得父类的属性,并具有自身特有的属性。
继承是面向对象编程技术的一块基石,它允许创建分等级层次的类。运用继承,可以创建一个通用类定义一系列一般特性。该类可以被更具体的类继承
Emoloyee类:
name
sex
Worker类:
category
dressAllowance
Officer类:
empClass
vehicle
职员类,具有姓名和性别两个属性工人类,继承了父类的姓名和性别属性外还包含类别和是否有服装津贴属性主任类,还包含级别和是否配备交通工具属性
18
extends关键字
extends关键字用于继承类。
声明一个继承父类的类的通常形式如下:
class subclass-name extends superclass-name {
//类体
}
没有 extends,默认父类为 Object
只能有一个父类,即单继承
子类继承父类的全部成员注意
19
super关键字
super关键字用来解决如何直接访问或初始化从父类继承来的属性。
super有两种通用形式:调用父类的构造函数、用来访问被子类的成员覆盖的父类成员。
它用在对象的构造函数中,将构造细节通过继承链往上传递。
super()必须是在子类构造函数中的第一个执行语句。
20
继承示例
class Employee {
String name; //姓名
char sex; //性别
Employee(String n,char s){
name = n; sex = s;
}
public String getName() { return name; }
public char getSex(){ return sex;}}
class Worker extends Employee {
char category;//类别
boolean dressAllowance; //是否提供服装津贴
Worker(String n,char s,char c,boolean d){
super(n,s);
category = c; dressAllowance = d;
}
public char getCategory(){return category;}
public boolean getAll(){ return dressAllowance; }
}
class InheDemo {
public static void main(String args[]) {
Worker w = new Worker("M.John",'M','B',true);
System.out.println("工人 信息 ");
System.out.println("姓名,"+w.getName());
System.out.println("性别,"+w.getSex());
System.out.println("类别,"+w.getCategory());
if(w.getAll())
System.out.println("提供 服装津贴 ");
else
System.out.println(“未提供 服装津贴,);
}
}
21
instanceof
class Student {}
class Graduate extends Student {}
class UndergraduateStudent extends Student {}
public class st {
public static void main(String []args) {
UndergraduateStudent s1 = new UndergraduateStudent();
Graduate s2=new Graduate();
Student x;
x=s1;
if (x instanceof UndergraduateStudent)
System.out.println(“x是 UndergraduateStudent类的实例 。,);
else
System.out.println(“x是 Graduate类的实例 。,);
}
}
instanceof 测试第一个参数的运行时类型是否为与第二个参数兼容的赋值。
x在运行时指向
s1,所以 if语句条件返回 true
22
类型转换
执行自动类型转换需要两个条件:
– 接受转换的两种类型是兼容的
– 目的类型数的范围比源类型的大
强制类型转换语句的通用格式如下:
(目标类型) value
UndergraduateStudent s1 = new UndergraduateStudent();
Graduate s2=new Graduate();
Student x;
x=s1;
Graduate s3=new Graduate();
if (x instanceof Graduate)
s3= (Graduate)x;
注意:从父类到子类的转换,建议在转换前判断父类是否指向子类的对象
23
Object 类
Object类是类体系结构的根
Java 系统中的每个类都是 Object 类直接或间接的子类
Object 类包括在 java.lang 包中
此类定义了所有对象都具备的基本状态和行为
可以用类型为 Object的变量来引用任意类型的对象
24
equals()
用于比较两个对象是否相等,相等返回 true
Object 类中提供的 equals 方法使用恒等函数来确定对象是否相等
Object类中实现的 equals方法只能用来判断两个不同的对象是否指向同一个内存区域
子类一般通过覆盖 Object的 equals方法实现有意义的测试,可以实现:若同一类型的两个不同对象包含相同的信息即返回 true
Integer one = new Integer(1);
Integer anotherOne = new Integer(1);
if (one.equals(anotherOne))
System.out.println("对象相等 ");
25
toString()
toString 用于返回对象的字符串表示。
建议所有子类都覆盖此方法。
使用,+”运算符将对象同一个字符串连接,
Java编译器会自动调用 toString方法,获取对象的字符串表现形式。
Derived d = new Derived();
System.out.println("Derived 的 toString()," + d);
自动调用 d.toString
方法,获取对象的字符串表示形式
26
方法覆盖( override)
方法覆盖是 Java实现多态性机制的另一种方式。
在类层次结构中,如果子类中的一个方法与父类中的方法有相同的方法名并具有相同数量和类型的参数列表,这种情况称为方法覆盖 。
当一个覆盖方法通过父类引用被调用,Java根据当前被引用对象的类型来决定执行哪个版本的方法。
可以通过 super关键字调用直属父类中被覆盖的方法版本。
27
方法覆盖示例
class SuperClass {
int a;
SuperClass(){ a = 10; }
public void printA(){System.out.println("父类中 a ="+a);}
}
class SubClass extends SuperClass {
int a;
SubClass(int a){ this.a = a; }
public void printA(){ System.out.println("子类中 a = "+a); }
}
public class OverrideDemo {
public static void main(String args[]) {
SuperClass s1 = new SubClass(10);
s1.printA();
}
} 将调用子类的 printA方法
28

在 Java中,包主要有以下用途,
– 包允许将类组合成较小的单元
– 有助于避免命名冲突
– 包允许在更广的范围内保护类、数据和方法
包可以是类、接口和子包的集合
29
使用包
创建包
package mypackage;
访问 Java 包成员
mypackage.My_Class
导入包
import package_name.*;
导入子包
import package_name.*;
30
总结 2-1
对象代表现实世界中的实体
类是对象的抽象,将对象的属性和行为 抽象为类中的数据和方法。
在 Java 中,extends 关键字用于继承类。
super关键字用来解决如何直接访问或初始化从父类继承来的属性 。
构造函数没有返回类型,名称与类的名称相同。
关键字 this 与对象关联用于指明当前对象。
31
总结 2-2
instanceof 测试第一个参数的运行时类型是否为与第二个参数兼容的赋值。
Object 类是类体系结构的根。
同一个类中多个方法有相同的名字不同的参数列表称为方法重载 。
若子类中与父类中的某方法有相同的方法名并具有相同数量和类型的参数列表,称为方法覆盖 。
包是类、接口和其他子包的集合。