6. 面向对象编程
1. 面向对象概念
阅读面对对象程序设计,回答以下问题:
1. 什么是面向对象编程
2. 什么是对象和类
3. 什么是类的封装
4. 什么是类的继承
5. 什么是类的多态
1.1 面向对象编程的概念
模拟人类的思维过程,一切皆对象
1.2 对象和类
1.2.1 对象
对象的两个要素:
-
属性:
用于描述对象静态特性(结构特性)的数据项 比如描述一个人的姓名、性别、年龄、出生日期等属性
-
方法:
用于描述对象动态特性(行为特性)的操作系列 比如人都具有工作、学习等行为特性
对象可以表示:
对象可以是看的见、摸的着的有形的实体,如计算机、飞机、汽车等等;
对象也可以表示人或组织所起的作用,如治病、教学、生产等;
对象还可以表示事件,如各种事故、演出、战斗、开会等;
对象更可以表示规则,如各种专家规则、约束条件、正则表达式等
1.2.2 类
把事物归纳、划分成类是我们认知世界常用的方法
分类的依据的原则是抽象,也就是忽略事物的非本质特征,只注意事物的本质特征
找出事物的共性并将具有共同性质的事物划分为同一个类
同一类中的对象有相同的属性(也称为成员变量,它描述该类的静态特性或结构特性)
同一类中的对象有相同的方法(也称服务,它描述该类的行为特性或动态特性)
同一类中的对象遵守相同的语义规则。(共同的约束或规则)
1.2.3 类和对象的关系
1.3面对对象编程原则
1.3.1 封装
对象将数据和数据的操作打包为一个不可分割的最基本模块,使得只有该类的方法可以操纵和改变这些数据,这就是封装
封装是允许有选择地隐藏类中的属性和方法
1.3.1 继承
继承(重用)现有类生成新类
继承关系:
父类是有其它类继承其行为的类
继承父类的类称为子类
1.3.3 多态
多态是建立在继承基础之上的
不同的子类继承自同一个父类,父类的用一个方法以不同方式实现
2. 面对对象程序设计
2.1 创建类
类就是对象的模板(template ),是对象的抽象。
而对象就是类的一个实例(instance)
类包含:属性;方法
数据成员是通过方法(函数)访问的
2.1.1 类定义
Java使用关键字class定义一个类 定义类时,用属性(成员变量)定义类的静态特征,用方法来定义类的行为特征。
修饰符 class 类名{
变量类型 变量名;
…
变量类型 变量名;
方法修饰符 返回类型 方法名(形参1,形参2,…){
//方法体
}
…
方法修饰符 方法名(参数1,参数2,…){
//方法体
}
}
例如:
public class Dog {
int age;
String name;
String color;
void barking() {
}
void sleeping() {
}
}
2.1.2 定义属性(变量)
语法格式:
修饰符 变量类型 变量名;
修饰符 变量类型 变量名 = 变量值;
private int row = 5;
类中的属性有:
-
局部变量
在方法、构造方法或者语句块中定义的变量被称为局部变量。 变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
-
成员变量
成员变量是定义在类中,方法体之外的变量。 这种变量在创建对象的时候实例化。 成员变量可以被类中方法、构造方法和特定类的语句块访问。
-
类变量
类变量也声明在类中,方法体之外,但必须声明为static类型。
-
this关键字:
//构造方法有三个参数 public Dog(int age,String name,String color){ //this代指当前对象,这样区分了局部变量和对象变量同名的问题 this.age = age; this.name = name; this.color = color; }
作用:表示对当前对象的引用;
表示类的成员变量,而不是方法中的成员变量,在两者同名时进行区分,最常用的this使用方式;
注意:this不能在static方法中使用
2.1.3 定义方法
语法格式:
修饰符 方法返回类型 方法名(形参1,形参2,…){
方法体;//语句
}
例如:
public int add(int i,int j) {
return i+j;
}
构造方法
构造方法是类的特殊方法,与类同名且没有返回值
对象的创建通过构造方法实现,构造方法的功能是完成对象的初始化,当类实例化一个对象会自动调用构造方法
类中必定有构造方法,若没有则系统自动添加一个无参无方法体的空构造方法
例如:
public Dog(int a,String n,String c){
age = a;
name = n;
color = c;
}
2.1.4 static定义类的属性和方法
-
静态变量
不管创建了类的多少实例,整个类中静态变量的副本只有一个。 引用静态变量的方法:通过类的名称,通过引用类的任一实例
例如:
//静态变量 static int numOfLegs = 4;
-
静态方法
静态方法只能访问静态成员,实例方法可以访问静态和实例成员 之所以不允许静态方法访问实例成员变量,是因为实例成员变量是属于某个对象的,而静态方法在执行时,并不一定存在对象 类方法没有this
例如:
//定义静态方法,获取腿的数量 public static int getLegs(){ return numOfLegs; }
-
main()方法
main()方法是一个特殊的方法,作为程序的入口,jvm通过调用主方法来执行程序:
public static void main(String[] args) { //方法体 }
注意:
主方法是静态的,所以如果要直接在主方法中调用其它方法,则该方法必须也是静态的 主方法没有返回值 主方法的形参为数组
2.2 创建对象
2.2.1 创建对象的格式
对象是类的实例化
Java中使用new关键字来创建对象
创建对象有两步:
声明:声明一个对象,包括对象名称和对象类型
实例化:使用关键字new来创建一个类的对象。
格式:
类名 对象名 = new 类名();
例如:
public class Dog {
int age;
String name;
String color;
//构造方法有三个参数
public Dog(int a,String n,String c){
age = a;
name = n;
color = c;
}
public static void main(String[] args) {
//生成Dog类的一个对象,并按照构造方法参数表传入参数值
Dog wangcaiDog = new Dog(1,"Wangcai","brown");
}
}
2.2.2. 关键字new的作用
创建一块内存空间并将内存空间分配给创建的对象
将对象的属性成员变量全部初始化,并执行构造方法
类成员变量初始值:
Java保证了在任何代码使用该对象之前,已将对象中的状态信息初始化为缺省值
2.3 属性和方法的调用
2.3.1. 对象的属性和方法调用:
格式:
对象.成员变量
对象.方法名()
例如:
//访问对象的变量
int age = wangcaiDog.age;
//调用对象的方法
wangcaiDog.barking();
2.3.2 类的属性和方法调用
格式:
类.成员变量
类.方法名()
例如:
//调用Dog类的属性
int numOfLegs = Dog.numOfLegs;
//调用Dog类的静态方法而不需要生成一个对象来调用
wangcaiDog.getLegs();
2.4 类的访问控制
Java中一般把属性数据和一些私有的方法声明为private或者protected类型,从而使这些数据或者方法不能被外部修改或调用。
只有我们希望被外部直接访问的属性数据和方法才声明为public。
如果在声明数据和方法时不写是private、protected还是public,那么类型为默认。
2.5 对象的比较
两个对象相比较,一定要注意是比较值还是比较地址
//生成Dog类的一个对象,并按照构造方法参数表传入参数值
Dog wangcaiDog = new Dog(1,"Wangcai","brown");
Dog xiaoheiDog = new Dog(1,"Wangcai","brown");
System.out.println("两个对象的比较结果为:"+(wangcaiDog==xiaoheiDog));
2.6 对象的销毁
对象在创建的时候,系统会分配内存空间给新建的对象,当对象被销毁,内存空间会归还给系统,该对象就不可以再继续使用了。
//生成Dog类的一个对象,并按照构造方法参数表传入参数值
Dog wangcaiDog = new Dog(1,"Wangcai","brown");
Dog xiaoheiDog = new Dog(1,"Wangcai","brown");
System.out.println("两个对象的比较结果为:"+(wangcaiDog==xiaoheiDog));
//销毁对象,将对象置为空
wangcaiDog = null;
3. Java源文件命名规则
源文件声明规则:
当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意这些规则。
一个源文件中只能有一个public类
一个源文件可以有多个非public类
源文件的名称应该和public类的类名保持一致。例如:源文件中public类的类名是Employee,那么源文件应该命名为Employee.java。
如果一个类定义在某个包中,那么package语句应该在源文件的首行。
如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面。
import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。
类有若干种访问级别,并且类也分不同的类型:抽象类和final类等。这些将在访问控制章节介绍。
除了上面提到的几种类型,Java还有一些特殊的类,如:内部类、匿名类。
4. Java包机制和import语句
4.1 Java包
包主要用来对类和接口进行分类。当开发Java程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类
4.2 Import语句
在Java中,如果给出一个完整的限定名,包括包名、类名,那么Java编译器就可以很容易地定位到源代码或者类。Import语句就是用来提供一个合理的路径,使得编译器可以找到某个类。 例如,下面的命令行将会命令编译器载入java_installation/java/io路径下的所有类
import java.io.*;
3. 练习和实践
-
练习一
1. 编写一个计算类 Sqrt Class。 2. 其中包含三个同名方法 sqrt() 用于开平方。 3. 它们都只有一个参数,参数的类型分别为 int 型、float 型和 double 型。 4. 它们的功能均为返回参数的平方根,返回值的类型与参数的类型相同。 5. 在方法 main( ) 中调用上面的三个方法并输出结果。
-
练习二
1. 编写一个学生的类,要求有姓名、年龄、兴趣、班级编号。 2. 编写一个教员类,要求有姓名、教授课程、专业方向、教龄,任课班级编号。 3. 设计一个主方法,要求在主方法中调用这两个类。 4. 写一个方法判断,学生和教员是否在同一个班级
-
练习三
1. 设计雇员Employee类。 2. 记录雇员的情况,包括姓名、年薪、受雇时间。 3. 要求定义 MyDate 类作为受雇时间,其中包括工作的年、月、日,并用相应的方法对Employee类进行设置。 4. 编写测试类测试Employee类。要求使用自己的包。
-
练习四
1. 设计一个长方形类,成员变量包括长和宽。 2. 类中有计算面积和周长的方法, 3. 并有相应的set方法和get方法设置和获得长和宽。 4. 编写测试类测试是否达到预定功能。
-
练习五
1. 学生有姓名(name)和成绩(score)信息。 2. 成绩有科目(course)和分数(grade)信息。 3. 学生类的getResult方法显示输出成绩信息, 4. setData方法实现初始化学生信息。 5. 编写学生类(Student)和成绩类(Score),并测试。