类的继承与方法重写
文章目录
一、实验目的:
1、理解类继承的意义和作用;
2、掌握类继承的程序设计;
3、理解父类中哪些成员可以直接继承、哪些成员不能被继承;
4、掌握成员方法的重写;
5、理解哪些方法可以被重写、哪些方法不能被重写;
6、理解重写与重载的区别。
二、实验要求:
以下每一个类单独保存一个文件:
1、设计一个类,名为People:
(1)成员变量为:
姓名,数据类型为String
性别,数据类型为char,数据包括’F’和’M’。
家庭地址,数据类型String
(2)设计一个构造方法:
包括三个参数,分别对应成员变量姓名、性别、家庭地址,在实例化时对三个成员变量赋初值。
(3)设计一个成员方法info(),访问修饰符为public,以String类型,输出三个成员变量的值,输出格式为:
姓名:XXX,性别:X,地址:XXXXXXXXXXXXXXXXXX
(4)设计一个成员方法display(),访问修饰符为final,用于显示三个成员变量的值,显示格式为:
姓名: XXXXXX
性别: X
地址: XXXXXXXXXXXXXXXXXXXX
class People // 创建People类
{
String name; // 设置三个成员变量
char sex;
String address;
public People(String name, char sex, String address) // 定义一个含有三个参数的构造方法
{
this.name = name;
this.sex = sex;
this.address = address;
}
public People() // 定义一个不含参数的构造方法
{
}
public String info() // 定义info()方法,返回具体信息,返回值类型为String
{
return "姓名:" + this.name + ",性别:" + sex + ",地址" + address; // 有返回值,所以有return
}
final void display() // 定义一个私有方法disploy(),输出具体信息,返回值类型为void
{
System.out.println("姓名:" + this.name);
System.out.println("性别:" + this.sex);
System.out.println("地址:" + this.address);
}
}
提醒:char类型的变量用单引号表示。
2、设计一个职工Staff类
(1) 继承People类;
(2) 增加如下成员变量:
毕业院校,类型String
入职年份,类型int
(3)设计一个构造方法,实现对包括父类的所有成员变量赋初值。通过调用父类的构造方法实现对父类三个成员变量赋初值,接着对本类中新增的两个成员变量赋初值。
(4)重写父类的info()方法,返回值为String,通过调用父类的info()方法取得父类三个成员的值,增加本类2个成员变量,实现String的完整输出,格式:
姓名:XXX,性别:X,地址:XXXXXXXXXXXXXXXXXX,毕业院校:XXXXX,入职年份:XXXXX年
(5)重写父类的display()方法,显示整个对象的全部信息。注意编译出现什么问题,分析为什么?如何修改。
编译出现的问题
原因分析:
因为display()方法第一次出现是在People类中,且它的限制修饰符为final,所以意味着,在后续不能对display()方法重写。
如何修改:
将People类中的display()方法的限制修饰符改为public或者不加(为缺省)。
class Staff extends People // 创建一个Staff类,继承自People类
{
public String school; // 设置两个成员变量
public int year;
public Staff(String name, char sex, String address, String school, int year) // 定义一个含有五个参数的构造方法
{
super(name, sex, address); // 显式的调用People类的成员变量
this.school = school;
this.year = year;
}
public Staff() // 定义一个不含参数的构造方法
{
}
public String info() // 对People类的info()方法进行重写
{
return super.info() + ",毕业院校:" + this.school + ",入职年份:" + this.year; // 显式的调用People类中的返回值再与字符拼接一起,作为Staff类的返回值
}
/*
public void display() // 重写People类的disploy()方法
{
super.display();
}
*/
}
3、设计一个Teacher类:
(1) 继承Staff类;
(2) 增加如下成员变量:
职称,数据类型为String
级别,数据类型为int;一般有12级,1—12级
(3) 设计一个构造方法,通过构造方法在实例化时实现对所有成员变量、包括父类的成员变量进行初始化;
(4)重写父类的info()方法,返回类型为String,通过调用父类的同名方法、用它返回包括所有父类的所有成员变量的值。
class Teacher extends Staff // 创建Teacher类,继承自Staff类
{
public String title; // 定义两个成员变量
public int rank;
public Teacher(String name, char sex, String address, String school, int year, String title, int rank) 定义一个含有七个参数的构造方法
{
super(name, sex, address, school, year); // 显式的调用Staff类的成员变量
this.title = title;
this.rank = rank;
}
public Teacher() // 定义一个不含参数的构造方法
{
}
public String info() // 重写Staff类里的info()方法
{
return super.info() + ",职称为:" + this.title + ",级别为:" + this.rank; // // 显式的调用Staff类中的返回值再与字符拼接一起,作为Teacher类的返回值
}
}
4、设计一个可以执行的TeacherManagement类
在该类的main()方法中,用Teacher类定义、实例化TC1和TC2两个对象,并调用对象的info()方法显示对象的所有信息。
class TeacherManagement
{
public static void main(String[] args) // 主入口函数
{
Teacher TC1 = new Teacher(); // 实例化两个Teacher对象,名为CT1和CT2
Teacher TC2 = new Teacher();
System.out.println(TC1.info()); // 输出Teacher类中的info()方法
System.out.println(TC2.info());
}
}
5、按成程序编写、调试、测试
在实验报告中体现全部源代码、基本调试过程、和最终的运行结果(原始屏幕)。
6、程序运行结束
执行Dir命令,把Dir执行结果作为报告的最后部分提交。
完整代码
class TeacherManagement
{
public static void main(String[] args) // 主入口函数
{
Teacher TC1 = new Teacher(); // 实例化两个Teacher对象,名为CT1和CT2
Teacher TC2 = new Teacher();
System.out.println(TC1.info()); // 输出Teacher类中的info()方法
System.out.println(TC2.info());
}
}
class People // 创建People类
{
String name; // 设置三个成员变量
char sex;
String address;
public People(String name, char sex, String address) // 定义一个含有三个参数的构造方法
{
this.name = name;
this.sex = sex;
this.address = address;
}
public People() // 定义一个不含参数的构造方法
{
}
public String info() // 定义info()方法,返回具体信息,返回值类型为String
{
return "姓名:" + this.name + ",性别:" + sex + ",地址" + address; // 有返回值,所以有return
}
final void display() // 定义一个私有方法disploy(),输出具体信息,返回值类型为void
{
System.out.println("姓名:" + this.name);
System.out.println("性别:" + this.sex);
System.out.println("地址:" + this.address);
}
}
class Staff extends People // 创建一个Staff类,继承自People类
{
public String school; // 设置两个成员变量
public int year;
public Staff(String name, char sex, String address, String school, int year) // 定义一个含有五个参数的构造方法
{
super(name, sex, address); // 显式的调用People类的成员变量
this.school = school;
this.year = year;
}
public Staff() // 定义一个不含参数的构造方法
{
}
public String info() // 对People类的info()方法进行重写
{
return super.info() + ",毕业院校:" + this.school + ",入职年份:" + this.year; // 显式的调用People类中的返回值再与字符拼接一起,作为Staff类的返回值
}
/*
public void display() // 重写People类的disploy()方法
{
super.display();
}
*/
}
class Teacher extends Staff // 创建Teacher类,继承自Staff类
{
public String title; // 定义两个成员变量
public int rank;
public Teacher(String name, char sex, String address, String school, int year, String title, int rank) // 定义一个含有七个参数的构造方法
{
super(name, sex, address, school, year); // 显式的调用Staff类的成员变量
this.title = title;
this.rank = rank;
}
public Teacher() // 定义一个不含参数的构造方法
{
}
public String info() // 重写Staff类里的info()方法
{
return super.info() + ",职称为:" + this.title + ",级别为:" + this.rank; // 显式的调用Staff类中的返回值再与字符拼接一起,作为Teacher类的返回值
}
}
代码运行结果:
实验小结:
在实例化Teacher类时,如果是无参实例化,那么Teacher和它的父类以及父类的父类,直到最开始的类,都需要一个空参构造方法。
在调用父类的方法或变量时,需要显式的调用,用到super;在一个方法中,调用自身的变量时,如果参数名与变量名重复的话,需要加“this.”
调用变量的方法有三种:1.类名.变量名,2.在实例化类之后,可以采用 对象.变量名的方法进行调用,3.直接访问;
但是在主函数中,因为主函数的限制修饰符为static,所以我们需要注意静态变量与成员变量之间的关系,简而言之就是,各个变量和方法在程序运行初待在的地方,栈,堆,方法区。需要对此了解,才能正确调用各变量及方法。