1 面向对象的基本概念
1.1 什么是面向对象
面向对象程序设计(Object Oriented Programming,OOP)是一种基于对象概念的软件开发方法,是目前软件开发的主流方法。
1.2 对象
1.2.1 什么是对象
在面向对象的世界中认为万事万物皆可成为对象,但对象强调的是一个具体的个体,例如:杨树不是一个对象,但我家院子里的那颗杨树就是一个对象。
1.2.2 对象由什么构成
- 对象由状态和行为构成。
- 对象的状态是指对象的数据,对象的状态由变量表示,也叫对象的属性。
- 对象的行为是指对象的功能,对象的行为由方法表示。
例如:
学生对象{
状态:姓名,成绩
行为:听课,写作业
}
1.2.3 怎样创建对象
对象是由类实例化的时候创建,因此创建对象必须先定义类。
1.3 类
1.3.1 什么是类
类是具有相同的状态和相同的行为的一组对象的集合。例如:有学号、有姓名、有成绩的状态,有听课、写作业的行为的所有对象可以归为一个类,称其为学生类。类简单的理解就是具有多个对象的统称,而不是一个个体。
1.3.2 类与对象的关系
类与对象的关系就如同模具与由此模具制作出的模型之间的关系。一个类给出它所有对象的一个统一的定义,而它每个对象则都是符合这种定义的一个实例,因此类和对象的关系就是抽象和具体的关系。
1.3.3 类与对象的区别
- 类是对某一类事物的抽象描述,不是具体的个体。
- 对象是对某一事物的具体描述,是具体的个体。
2 定义类
2.1 类的构成
类是由属性和方法构成的。
2.2 类的定义
语法:
public class 类名 {
//可编写0到n个属性
数据类型 变量名1;
数据类型 变量名2;
//可编写0到n个方法
修饰符 返回值类型 方法名(参数) {
执行语句;
}
}
注意:
- public类的类名必须和类所在文件的文件名一致。
- 如果不是public类,那么类名与类所在的文件名可以不一致。
- 类名的命名规则是:帕斯卡命名法。
示例:
class Student{
//类的属性
String name;
int score;
String no;
//类的方法
public void play(){
System.out.printf("我的名字是%s,我的成绩是%d,我的学号是%s",name,score,no);
}
}
3 实例化对象
通过类创建对象的过程称为类的实例化,实例化的结果是产生一个实例,实例也叫对象。
3.1 实例化对象
语法
在程序中,实例化用new表示,new也是分配内存的意思
类名 对象名 = new 类名();
示例:
Student s1 = new Student();
Student s2 = new Student();
3.1.1 对象的内存分配
4 使用对象
对象的调用和方法是使用成员运算符来完成的。
4.1 对象调用属性
Student s1 = new Student();
s1.name = "haha";
s1.score = 78;
Student s2 = new Student();
s2.name = "yaya";
s2.score = 98;
4.2 对象调用方法
Student s1 = new Student();
s1.name = "haha";
s1.score = 78;
s1.play();//调用方法
Student s2 = new Student();
s2.name = "yaya";
s2.score = 98;
s2.play();//调用方法
运行结果:
5 方法重载(overload)
方法重载是OOP中的一个重要概念,而实际开发中经常用到方法重载。
5.1 方法重载的定义
在同一个类中:同名不同参,与返回值无关。
例如:
public class Student{
public void play(){
}
public int play(int time){
return 0;
}
}
5.2 方法重载的调用
方法重载根据参数匹配原则进行调用
public void play(){
System.out.printf("我的名字是%s,我的成绩是%d,我的学号是%s",name,score,no);
System.out.println();
}
public int play(int time){
return 0;
}
...(省略部分代码)
s1.play(1);//调用的是第5行的方法
s2.play();//调用的是第1行的方法
6 构造方法
6.1 什么是构造方法
在Java中,当类创建一个对象时,为该类对象的属性进行初始化的方法被称作构造方法。构造方法也叫构造函数,或者叫构造器。
- 构造方法的方法名必须与类名相同。
- 构造方法没有返回值,也不写void。
class Student{
//构造方法
Student(){
}
}
6.2 构造方法的作用
为成员变量进行初始化。
6.3默认构造函数
当一个类没有定义构造函数时,那这个类默认具有一个无参的构造函数。默认构造函数为对象的属性赋默认值。
例如:
class Student{
String name;
int score;
String no;
public void play(){
System.out.printf("我的名字是%s,我的成绩是%d,我的学号是%s",name,score,no);
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student;
s1.play();
}
}
输出结果为:
为什么输出的是null,0,null?
因为本例中没有定义构造函数,系统会自动添加一个默认构造函数,默认构造函数是无参的,会为所有的属性赋默认值,因此name是null,score是0,no是null。
6.4 构造方法的调用
构造方法是在实例化对象时调用的。并且实例化时传递的参数必须有构造方法的参数一致。
例如:
class Student {
String name;
int score;
String no;
Student(String name1,int score1){
name= name1;
score= score1;
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 =new Student("haha",76);//调用student类的构造方法,为name和score属性初始化,no为默认值null
}
}
注意:构造方法不允许通过对象名调用。
6.5 构造方法的重载
class Student{
String name;
int score;
String no;
//第1种构造方法的重载
Student(String name1, int score1){
name = name1;
score = score1;
}
//第2种构造方法的重载
Student(String name1, int score1, String no1){
name = name1;
score = score1;
no = no1;
}
public void play(){
System.out.printf("我的名字是%s,我的成绩是%d,我的学号是%s",name ,score ,no);
System.out.println();
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student("yaya",78);//调用第1种构造方法的重载
s1.play();
Student s2 = new Student("haha", 98,"111");//调用第2种构造方法的重载
s2.play();
}
}
7 this关键字
7.1 this关键字的使用
在类中,如果类的属性名和方法内部的局部变量同名时,那么在方法内部使用的是局部变量,也就是变量使用遵循就近原则,例如:
Student(String name,int score){
name = name;
score = score;
此时,就无法判断name的指代了,如此看来类的属性名和构造方法的参数名称不能相同。
但使用this关键字就能使类的属性名和构造方法的参数名称相同。使用示例如下:
class Student{
String name;
int score;
String no;
Student(String name,int score){
//this代表正在运行的对象,当执行第16行代码时,调用了构造函数,此时this代表第16行的s1
this.name = name; //this.name指的是对象的属性,name是指方法的参数
this.score = score; //this.score指的是对象的属性,score是指方法的参数
}
public void play(){
System.out.printf("我的名字是%s,我的成绩是%d,我的学号是%s",name ,score ,no);
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student("yaya", 78);
s1.play();
}
}
运行结果:
7.2 this关键字的省略
在非static方法内部使用属性,可以省略,例如:
public void sayHello(){
System.out.printf("我是%s,我的成绩是%d,我的学号是%s",this.name,this.score,this.no);
}
可以写成
public void sayHello(){
System.out.printf("我是%s,我的成绩是%d,我的学号是%s",name,score,no);
}
7.3 this调用重载方法
例如:我们知道学生姓名和成绩,不知道学号,但是显示学生信息时要求将学号显示为”未知“,而不是null。
分析:
有两种情况
- 知道姓名和成绩,不知道学号
- 知道姓名,成绩,学号
所以要设计两种构造的重载,设计结果如下:
class Student {
String name;
int score;
String no;
Student(String name,int score){
this(name,score,"未知");//构造方法内部的this()表示调用本类的其他构造方法
}
Student(String name,int score,String no){
this.name= name;
this.score= score;
this.no = no;
}
}
注意:当使用this调用本类其他构造方法时,必须是构造方法内的第一行代码。
8 变量
变量分为成员变量和局部变量
8.1 局部变量
局部变量是定义在方法内的变量
例如:
public void sayHello(){
int height = 20;//局部变量
}
8.2 成员变量
成员变量是类的属性,是定义在类内,方法外的变量。
例如:
class Student {
String name;
int score;
String no;
}
8.3 成员变量和局部变量的区别
- 作用域不同
- 成员变量作用域:整个类
- 局部变量的作用域:方法内
- 初始值不同
- 成员变量由构造函数初始化的
- 局部变量需要手动初始化
在同一个方法中不允许有同名的局部变量,在不同的方法中可以有同名的局部变量。
局部变量可以和成员变量名相同,并且在使用时局部变量有更高的优先级。
9 对象数组
需求:
- 班级里有5名学生,输入每名学生的姓名和总成绩。
- 根据学生总成绩从高到低排名,显示学生名次、姓名、总成绩。
分析:
- 有哪些对象?有学生对象,有班级对象
- 对象有什么属性和方法?
- 学生有姓名,成绩的属性,学生不需要方法
- 班级有多名学生的属性,班级有排序方法,输出的方法
代码:
1:创建学生类
public class Student {
//属性
String name;
int score;
//构造
public Student(String name, int score) {
this.name = name;
this.score = score;
}
}
班级类:
public class ClassInfo {
//属性
Student []stus = null;
//构造函数初始化班级大小
public ClassInfo(int size){
this.stus = new Student[size];
}
//排序方法
public void sort(){
if(this.stus.length==0){
return;
}
for (int i = 0; i < this.stus.length-1; i++) {
for (int j = 0; j < this.stus.length - i - 1; j++) {
if(this.stus[j].score<this.stus[j+1].score){
Student temp = this.stus[j];
this.stus[j] = this.stus[j+1];
this.stus[j+1] = temp;
}
}
}
}
//输出方法
public void print(){
for (int i = 0; i < stus.length; i++) {
System.out.printf("姓名:%s,成绩%d,名次:%d",stus[i].name,stus[i].score,(i+1));
System.out.println();
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
//1:创建5个学生
Student s1 = new Student("刘茂兵",60);
Student s2 = new Student("田舍翁",80);
Student s3 = new Student("杨礼之",90);
Student s4 = new Student("余晨",65);
Student s5 = new Student("乔思义",70);
//2:创建班级
ClassInfo classInfo = new ClassInfo(5);
classInfo.stus[0] = s1;
classInfo.stus[1] = s2;
classInfo.stus[2] = s3;
classInfo.stus[3] = s4;
classInfo.stus[4] = s5;
//3:排序
classInfo.sort();
//4:输出
classInfo.print();
}
}
运行结果
姓名:杨礼之,成绩90,名次:1
姓名:田舍翁,成绩80,名次:2
姓名:乔思义,成绩70,名次:3
姓名:余晨,成绩65,名次:4
姓名:刘茂兵,成绩60,名次:5