# JAVA 实验一:掌握继承与方法重写
# 实验任务书
第一部分
(1) 声明 Student 类,学生的属性包含学号、姓名、数学成绩和计算机成绩。要求:该类的构造方法中用到 this 关键字;对于每一个属性,都要有对应的 set 方法和 get 方法来设置属性的值和获取属性的值。还要有一个 void print () 方法,功能是输出成员变量的信息。
(2) 在主类的 main 方法中,创建学生类的数组,从键盘上输入若干学生的信息,之后输出这些学生的信息;将学生信息分别按照两门课程的成绩升序排序。
第二部分
(1) 声明学生类 Student 的子类 —— 研究生类 PostGraduate,其中,研究生类继承了父类的学号、姓名、数学成绩和计算机成绩,此外,研究生类还有自己的两个新属性:导师姓名(String 类型)和研究方向(String 类型)。
(2) 研究生类要重写父类的 void print () 方法,功能是输出成员变量(6 个成员变量)的信息。(想一想研究生的构造方法怎么写,提示,从父类继承的成员变量可以在子类的构造方法中使用 super 关键字。)
# 解答
# 文件结构
├── src (源文件夹)
│ ├── student1 (包)
│ ├── Main.java
│ └── Student.java (学生信息类)
# 代码
# Main.java
package student1; | |
import java.util.*; | |
public class Main { | |
public static void main(String[] args) { | |
Scanner reader = new Scanner(System.in); | |
System.out.println("是本科生信息还是研究生信息?\nA.本科生\tB.研究生"); | |
char choice = reader.next().charAt(0);//charAt (index) 用于返回索引处的字符 | |
switch(choice) | |
{ | |
case 'A': | |
case 'a': | |
System.out.println("输入学生的个数:"); | |
int stuNum = reader.nextInt(); | |
Student stu[] =new Student[stuNum]; | |
for(int i=0;i<stu.length;i++) | |
{ | |
System.out.println("请输入第"+(i+1)+"位学生学号,姓名,数学成绩,计算机成绩:"); | |
stu[i]=new Student(reader.nextInt(), reader.next(),reader.nextDouble(), reader.nextDouble()); | |
} | |
System.out.println("学生信息为:"); | |
for (Student i:stu) | |
{ | |
i.print(); | |
} | |
for(int i =0;i < stuNum-1;i++) | |
for(int j =0;j<stuNum-i-1;j++) | |
{ | |
if(stu[j].getMathScore()>stu[j+1].getMathScore()) | |
{ | |
Student temp; | |
temp =stu[j+1]; | |
stu[j+1]=stu[j]; | |
stu[j]=temp; | |
} | |
} | |
System.out.println("学生信息按数学成绩由低到高排序为:"); | |
for (Student i:stu) | |
{ | |
i.print(); | |
} | |
for(int i =0;i < stuNum-1;i++) | |
for(int j =0;j<stuNum-i-1;j++) | |
{ | |
if(stu[j].getComputerScore()>stu[j+1].getComputerScore()) | |
{ | |
Student temp; | |
temp =stu[j+1]; | |
stu[j+1]=stu[j]; | |
stu[j]=temp; | |
} | |
} | |
System.out.println("学生信息按计算机成绩由低到高排序为:"); | |
for (Student i:stu) | |
{ | |
i.print(); | |
} | |
break; | |
case 'B': | |
case 'b': | |
System.out.println("输入学生的个数:"); | |
int stuNum1 = reader.nextInt(); | |
Student stu1[] =new PostGraduate[stuNum1]; | |
for(int i=0;i<stu1.length;i++) | |
{ | |
System.out.println("请输入第"+(i+1)+"位学生学号,姓名,数学成绩,计算机成绩,导师姓名,研究方向:"); | |
stu1[i]=new PostGraduate(reader.nextInt(), reader.next(),reader.nextDouble(), reader.nextDouble(),reader.next(),reader.next()); | |
} | |
System.out.println("学生信息为:"); | |
for (Student i:stu1) | |
{ | |
i.print(); | |
} | |
for(int i =0;i < stuNum1-1;i++) | |
for(int j =0;j<stuNum1-i-1;j++) | |
{ | |
if(stu1[j].getMathScore()>stu1[j+1].getMathScore()) | |
{ | |
Student temp; | |
temp =stu1[j+1]; | |
stu1[j+1]=stu1[j]; | |
stu1[j]=temp; | |
} | |
} | |
System.out.println("学生信息按数学成绩由低到高排序为:"); | |
for (Student i:stu1) | |
{ | |
i.print(); | |
} | |
for(int i =0;i < stuNum1-1;i++) | |
for(int j =0;j<stuNum1-i-1;j++) | |
{ | |
if(stu1[j].getComputerScore()>stu1[j+1].getComputerScore()) | |
{ | |
Student temp; | |
temp =stu1[j+1]; | |
stu1[j+1]=stu1[j]; | |
stu1[j]=temp; | |
} | |
} | |
System.out.println("学生信息按计算机成绩由低到高排序为:"); | |
for (Student i:stu1) | |
{ | |
i.print(); | |
} | |
break; | |
} | |
} | |
} |
# Student.java
package student1; | |
public class Student { | |
int num; | |
String name; | |
double mathScore; | |
double computerScore; | |
Student(int num,String name,double mathScore,double computerScore){ | |
this.num= num; | |
this.name= name; | |
this.mathScore= mathScore; | |
this.computerScore= computerScore; | |
} | |
void setNum(int num) { | |
this.num=num; | |
} | |
int getNum() { | |
return this.num; | |
} | |
void setName(String name) { | |
this.name=name; | |
} | |
String getName() { | |
return this.name; | |
} | |
void setMathScore(double mathScore) { | |
this.mathScore =mathScore; | |
} | |
double getMathScore() | |
{ | |
return this.mathScore; | |
} | |
void setComputerScore(double computerScore) { | |
this.computerScore= computerScore; | |
} | |
double getComputerScore() | |
{ | |
return this.computerScore; | |
} | |
double getScoreSum() | |
{ | |
return this.computerScore+this.mathScore; | |
} | |
void print() { | |
System.out.println("学号:"+getNum()+",姓名:"+getName()+",数学:"+getMathScore()+",计算机:"+getComputerScore()); | |
} | |
} | |
class PostGraduate extends Student{ | |
String teacherName; | |
String resDirection; | |
PostGraduate(int num,String name,double mathScore,double computerScore,String teacherName,String resDirection){ | |
super(num, name, mathScore, computerScore); | |
this.teacherName= teacherName; | |
this.resDirection =resDirection; | |
} | |
void setTeacherName(String teacherName) { | |
this.teacherName= teacherName; | |
} | |
void setResDirection(String resDirection){ | |
this.resDirection= resDirection; | |
} | |
String getTeacherName() { | |
return this.teacherName; | |
} | |
String getResDirection() { | |
return resDirection; | |
} | |
void print() { | |
System.out.println("学号:"+getNum()+",姓名:"+getName()+",数学:"+getMathScore()+",计算机:"+getComputerScore()+",导师:"+getTeacherName()+",研究方向:"+getResDirection()); //PostGraduate 重写 print 方法,输出成员变量 | |
} | |
} |
# 实验报告书
# 实验目的
(1)掌握类的声明方法;
(2)掌握 this 关键字的作用;
(3)掌握 super 关键字的作用;
(4)掌握类的继承;
(5)掌握方法重写。
# 实验内容
第一部分
声明 Student 类,学生的属性包含学号、姓名、数学成绩和计算机成绩。要求:该类的构造方法中用到 this 关键字;对于每一个属性,都要有对应的 set 方法和 get 方法来设置属性的值和获取属性的值。还要有一个 void print () 方法,功能是输出成员变量的信息。
在主类的 main 方法中,创建学生类的数组,从键盘上输入若干学生的信息,之后输出这些学生的信息;将学生信息分别按照两门课程的成绩升序排序。
第二部分
声明学生类 Student 的子类 —— 研究生类 PostGraduate,其中,研究生类继承了父类的学号、姓名、数学成绩和计算机成绩,此外,研究生类还有自己的两个新属性:导师姓名(String 类型)和研究方向(String 类型)。
研究生类要重写父类的 void print () 方法,功能是输出成员变量(6 个成员变量)的信息。(想一想研究生的构造方法怎么写,提示,从父类继承的成员变量可以在子类的构造方法中使用 super 关键字。)
# 实验结果
第一部分:本科生:
第二部分:研究生:
# 实验分析
# 1、this 的作用
public class Student { | |
int num; | |
String name; | |
double mathScore; | |
double computerScore; | |
Student(int num,String name,double mathScore,double computerScore){ | |
this.num= num; | |
this.name= name; | |
this.mathScore= mathScore; | |
this.computerScore= computerScore; | |
} |
在这个构造函数中,参数的局部变量会把 Student 类中的属性屏蔽,所以需要加 this 关键字。this 代表当前对象的一个引用,如果在方法内部调用同一个类的另一个方法,就不必使用 this,直接调用即可。当前方法中的 this 引用会自动应用于同一类中的其他方法。
# 2、类的继承和重写
class PostGraduate extends Student{ | |
String teacherName; | |
String resDirection; | |
PostGraduate(int num,String name,double mathScore,double computerScore,String teacherName,String resDirection){ | |
super(num, name, mathScore, computerScore); | |
this.teacherName= teacherName; | |
this.resDirection =resDirection; | |
} |
在这里,新建立了一个学生的子类 —— 研究生类,用 extends 关键词进行继承,子类研究生类 PostGraduate 会自动继承父类 Student 的方法和属性,所以学生的基本属性:学号、姓名、数学成绩、计算机成绩都被继承了;
但是,研究生类与学生类不同的是,多了两个新的属性:导师姓名和研究方向,因此,需要重写函数,这里重写的是输出 void print (),在研究生类的声明中,新定义了两个 String 类的属性,在构造函数中进行赋值,然后:
void setTeacherName(String teacherName) { | |
this.teacherName= teacherName; | |
} | |
void setResDirection(String resDirection){ | |
this.resDirection= resDirection; | |
} | |
String getTeacherName() { | |
return this.teacherName; | |
} | |
String getResDirection() { | |
return resDirection; | |
} |
分别对这两个属性进行 get 和 set 方法,最后输出时,可以输出研究生类的所以属性。
# 3、super 关键字
PostGraduate(int num,String name,double mathScore,double computerScore,String teacherName,String resDirection){ | |
super(num, name, mathScore, computerScore); | |
this.teacherName= teacherName; | |
this.resDirection =resDirection; |
在子类研究生类的构造函数中,为了获取父类的所有对象,需要使用 super 关键字,super 是指向父类的引用,如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的 super () 方法调用。如果父类由没有默认的无参构造方法,编译器就会报错,super () 语句必须是构造方法的第一个子句。super 关键字用法:
1. 在子类的成员方法中,访问父类的成员变量。
2. 在子类的成员方法中,访问父类的成员方法。
3. 在子类的构造方法中,访问父类的构造方法。
# 4、在成绩排序中,使用的方法时最冒泡排序
例如按数学成绩从低到高排序:
for(int i =0;i < stuNum1-1;i++) | |
for(int j =0;j<stuNum1-i-1;j++) | |
{ | |
if(stu1[j].getMathScore()>stu1[j+1].getMathScore()) | |
{ | |
Student temp; | |
temp =stu1[j+1]; | |
stu1[j+1]=stu1[j]; | |
stu1[j]=temp; | |
} |
最后进行输出,获得最终结果。
# 实验总结
1、this 关键字的作用:代表当前对象的一个引用,在构造方法中也可以使用 this 代表当前对象。
2、super 关键字的作用:在子类的成员方法中,访问父类的成员变量。在子类的成员方法中,访问父类的成员方法。在子类的构造方法中,访问父类的构造方法。
3、类的继承使用 extends 关键字,使用父类的方法、对象等要使用 super 关键字。类的方法重写需要在构造函数中新定义新的属性并赋值,在类的方法中,使用 set 和 get 设置和获取属性的值。