实验1 中国人、北京人和美国人
一、实验目的
1.了解子类的继承性
2.掌握子类对象的创建过程
3.成员变量的继承与隐藏
4.掌握方法的继承与重写
二、实验内容
编写程序模拟中国人、美国人是人,北京人是中国人。除主类外,程序中还有4个类:People、ChinaPeople、AmericanPeople和BeijingPeople类。要求如下:
1.People类有权限是protected的double型成员变量height和weight,以及public修饰的speakHello()、averageHeight()和averageWeight()方法。
2.ChinaPeople类是People的子类,新增public修饰的chinaGongfu()方法,重写父类的三个方法
3.AmericanPeople类是People的子类,新增public修饰的americanBoxing()方法,重写父类的三个方法
4.Beijing类是ChinaPeople的子类,新增public修饰的beijingOPera()方法,重写父类继承People的三个方法
三、程序代码
1.People.java文件内容
1. class People { 2. protected double weight,height; 3. public void speakHello() { 4. System.out.println("yayayaya"); 5. } 6. public void averageHeight() { 7. height=173; 8. System.out.println("average height:"+height); 9. } 10. public void averageWeight() { 11. weight=70; 12. System.out.println("average weight:"+weight); 13. } 14. }
2.ChinaPeople.java文件内容
1. class ChinaPeople extends People { 2. public void speakHello() { 3. System.out.println("您好"); 4. } 5. public void averageHeight() { 6. height = 168.78; 7. System.out.println("中国人的平均身高:"+height+" 厘米"); 8. System.out.println("中国人的平均体重:65公斤");}//【代码1】 //重写public void averageWeight()方法,输出:"中国人的平均体重:65公斤" 9. public void chinaGongfu() { 10. System.out.println("坐如钟,站如松,睡如弓"); 11. } 12. }
3.AmericanPeople.java文件内容
1. class AmericanPeople extends People { 2. public void speakHello() { 3. System.out.println("How do you do"); 4. } //【代码2】 //重写public void speakHello()方法,输出"How do you do" 5. public void averageHeight() { 6. System.out.println("American's average height:176 cm"); 7. }//【代码3】 //重写public void averageHeight()方法,输出"American's average height:176 cm" 8. public void averageWeight() { 9. weight = 75; 10. System.out.println("American's average weight:"+weight+" kg"); 11. } 12. public void americanBoxing() { 13. System.out.println("直拳、钩拳、组合拳"); 14. } 15. }
4.Beijing.java文件内容
1. class BeijingPeople extends ChinaPeople { 2. public void averageHeight() { 3. System.out.println("北京人的平均身高: 172.5厘米"); 4. }//【代码4】 //重写public void averageHeight()方法,输出:"北京人的平均身高: 172.5厘米" 5. public void averageWeight() { 6. System.out.println("北京人的平均体重:70公斤"); 7. }//【代码5】 //重写public void averageWeight()方法,输出:"北京人的平均体重:70公斤" 8. public void beijingOpera() { 9. System.out.println("花脸、青衣、花旦和老生"); 10. } 11. }
5.Example.java文件内容
1. public class Example { 2. public static void main(String args[]) { 3. ChinaPeople chinaPeople=new ChinaPeople(); 4. AmericanPeople americanPeople=new AmericanPeople(); 5. BeijingPeople beijingPeople=new BeijingPeople(); 6. chinaPeople.speakHello(); 7. americanPeople.speakHello(); 8. beijingPeople.speakHello(); 9. chinaPeople.averageHeight(); 10. americanPeople.averageHeight(); 11. beijingPeople.averageHeight(); 12. chinaPeople.averageWeight(); 13. americanPeople.averageWeight(); 14. beijingPeople.averageWeight(); 15. chinaPeople.chinaGongfu(); 16. americanPeople.americanBoxing(); 17. beijingPeople.beijingOpera() ; 18. beijingPeople.chinaGongfu(); 19. } 20. }
四、实验指导
1.如果子类可以继承父类的方法,子类就有权利重写这个方法,子类通过重写父类的方法以示自己的特殊性
2.方法重写时一定要保证方法的名字、返回值类型、参数个数和类型同父类的某个方法完全相同,只有这样,子类继承的这个方法才被隐藏
实验3 银行计算利息
一、实验目的
让学生掌握重写的目的以及怎样使用super关键字
二、实验内容
假设银行Bank已经有了按整年year计算利息的一般方法,其中year只能取正整数。
建设银行ConstructionBank是Bank的子类,准备隐藏继承的成员变量year,并重写计算利息的方法,即自己声明一个double型的year变量,比如当year取值是5.216时,表示要计算5年零216天的利息,但希望首先按银行Bank的computerInstrest()计算5整年的利息,然后自己计算216天的利息。那么,建设银行就必须把5.216的整数部分赋值给隐藏的year,并让super调用隐藏的、按整年计算利息的方法。
要求ConstructionBank和BankOfDalian类是Bank类的子类,ConstructionBank和BankOfDalian都是用super调用隐藏的成员变量和方法。
三、程序代码
1.Bank.java文件内容
1. class Bank { 2. int savedMoney; 3. int year; 4. double interest; 5. double interestRate = 0.29; 6. public double computerInterest() { 7. interest=year*interestRate*savedMoney; 8. return interest; 9. } 10. public void setInterestRate(double rate) { 11. interestRate = rate; 12. } 13. }
2.Construction.java文件内容
1. class ConstructionBank extends Bank { 2. double year; 3. public double computerInterest() { 4. super.year=(int)year; 5. double r = year-(int)year; 6. int day=(int)(r*1000); 7. double yearInterest = super.computerInterest();//【代码1】 //super调用隐藏的computerInterest()方法 8. double dayInterest = day*0.0001*savedMoney; 9. interest= yearInterest+dayInterest; 10. System.out.printf("%d元存在建设银行%d年零%d天的利息:%f元\n", 11. savedMoney,super.year,day,interest); 12. return interest; 13. } 14. }
3.BankOfDalian.java文件内容
1. class BankOfDalian extends Bank { 2. double year; 3. public double computerInterest() { 4. super.year=(int)year; 5. double r = year-(int)year; 6. int day=(int)(r*1000); 7. double yearInterest = super.computerInterest();//【代码2】// super调用隐藏的computerInterest()方法 8. double dayInterest = day*0.00012*savedMoney; 9. interest= yearInterest+dayInterest; 10. System.out.printf("%d元存在大连银行%d年零%d天的利息:%f元\n", 11. savedMoney,super.year,day,interest); 12. return interest; 13. } 14. }
4.SavaMoney.java文件内容
1. public class SaveMoney { 2. public static void main(String args[]) { 3. int amount=8000; 4. ConstructionBank bank1 = new ConstructionBank(); 5. bank1.savedMoney = amount; 6. bank1.year = 8.236; 7. bank1.setInterestRate(0.035); 8. double interest1 = bank1.computerInterest(); 9. BankOfDalian bank2 = new BankOfDalian(); 10. bank2.savedMoney = amount; 11. bank2.year = 8.236; 12. bank2.setInterestRate(0.035); 13. double interest2=bank2.computerInterest(); 14. System.out.printf("两个银行利息相差%f元\n",interest2-interest1); 15. } 16. }
四、实验指导
1.当super调用被隐藏的方法时,该方法中出现的成员变量是被子类隐藏的成员变量或继承的成员变量
2.子类不继承父类的构造方法,因此,子类在其构造方法中需使用super来调用父类的构造方法,而且super必须是子类构造方法中的头一条语句,即如果在子类的构造方法中,没有明显地写出super关键字来调用父类的某个构造方法,那么默认的有“super();”。类中定义多个构造方法时,应当包括一个不带参数的构造方法,以防止子类省略super时出现错误。
实验4 公司支出的总薪水
一、实验目的
掌握向上转型对象的使用。在讲继承与多态时,我们通过子类对象的向上转型体现继承的多态性,即把子类创建的对象的引用放到一个父类的对象中时,得到该对象的一个向上转型的对象,那么这个向上转型对象在调用方法时,就可以具有多种形态,不同对象的向上转型对象调用同一个方法可能产生不同的行为
二、实验内容
有一个abstract类,类名为Employee。Employee的子类有YearWorker、MonthWorker、WeekWorker。YearWorker对象按年领取薪水,MonthWorker按月领取薪水,WeekWorker按周领取薪水。Employee类有一个抽象的方法:
public abstract earnings();
子类必须重写父类的earnings()方法,给出各自领取报酬的具体形式。
有一个Company类,该类用Employee对象数组作为成员,Employee对象数组的元素可以是YearWorker对象向上转型的对象、MonthWorker对象向上转型的对象、WeekWorker对象向上转型的对象。程序能输出Company对象一年需要支付的薪水总额。
三、程序代码
CompanySalary.java文件内容
1. abstract class Employee { 2. double salary;//员工每次发放的薪水。 3. public abstract double earnings(); 4. } 5. class Company { 6. Employee[] employee; 7. double salaries=0; 8. Company(Employee[] employee) { 9. this.employee=employee; 10. } 11. public double salariesPay() { 12. salaries=0; 13. for(int i=0;i<employee.length;i++) { 14. salaries=salaries+employee[i].earnings(); 15. }//【代码4】 //计算salaries。 16. return salaries; 17. } 18. } 19. class YearWorker extends Employee{ 20. public YearWorker(){ 21. salary=20000;//年薪 22. } 23. public double earnings() { 24. salary=3000; 25. return 12*salary; 26. }//【代码1】 //重写earnings()方法 27. } 28. class MonthWorker extends Employee{ 29. public MonthWorker(){ 30. salary=12*5000;//月薪 31. } 32. public double earnings() { 33. salary=3000; 34. return salary; 35. }//【代码2】 //重写earnings()方法 36. } 37. class WeekWorker extends Employee { 38. public WeekWorker(){ 39. salary=500;//周薪 40. } 41. public double earnings() { 42. salary=300; 43. return 12*4*salary; 44. }//【代码3】 //重写earnings()方法。 45. } 46. class DayWorker extends Employee { 47. public DayWorker(){ 48. salary=100;//日薪 49. } 50. public double earnings() { 51. salary=90; 52. return 365*salary; 53. } 54. } 55. public class CompanySalary { 56. public static void main(String args[]) { 57. Employee [] employee=new Employee[29]; //公司有29名雇员 58. for(int i=0;i<employee.length;i++) { //雇员简单地分成三类 59. if(i%4==0) 60. employee[i]=new WeekWorker(); 61. else if(i%4==1) 62. employee[i]=new MonthWorker(); 63. else if(i%4==2) 64. employee[i]=new YearWorker(); 65. else if(i%4==3) 66. employee[i]=new DayWorker(); 67. } 68. Company company=new Company(employee); 69. System.out.println("公司薪水总额:"+company.salariesPay()+"元"); 70. } 71. }
实验5 编程题
设计一个动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声。要求如下:
- 编写抽象类Animal
Animal抽象类有2个抽象方法cry()和getAnimaName(),即要求各种具体的动物给出自己的叫声和种类名称。
- 编写模拟器类Simulator
该类有一个playSound(Animal animal)方法,该方法的参数是Animal类型。即参数animal可以调用Animal的子类重写的cry()方法播放具体动物的声音、调用子类重写的getAnimalName()方法显示动物种类的名称。
- 编写Animal类的子类:Dog,Cat类
- 编写主类Application(用户程序)
1. abstract class Animal{ 2. public abstract void cry(); 3. public abstract String getAnimalName(); 4. } 5. class Dog extends Animal{ 6. public void cry() { 7. System.out.println("汪汪汪!"); 8. } 9. public String getAnimalName() { 10. return "小狗"; 11. } 12. } 13. class Cat extends Animal{ 14. public void cry() { 15. System.out.println("喵喵喵!"); 16. } 17. public String getAnimalName() { 18. return "小猫"; 19. } 20. } 21. class Stimulator{ 22. public void playSound(Animal animal) { 23. System.out.println("播放"+animal.getAnimalName()+"种类声音:"); 24. animal.cry(); 25. } 26. } 27. public class Application { 28. public static void main(String[] args) { 29. Stimulator simulator = new Stimulator(); 30. simulator.playSound(new Dog()); 31. simulator.playSound(new Cat()); 32. } 33. }
实验6 评价成绩
一、实验目的
通过实验让学生掌握类怎样实现接口
二、实验内容
体操比赛计算选手成绩的办法是去掉一个最高分和最低分再计算评价分,而学校考查一个班级的某科考试情况时,是计算全班同学的平均成绩。Gymnastics类和School类都实现了ComputerAverage接口,但实现方法不同。
三、程序代码
Estimator.java文件内容
1. public interface CompurerAverage { 2. public double average(double x[]); 3. } 4. class Gymnastics implements CompurerAverage { 5. public double average(double x[]) { 6. int count=x.length; 7. double aver=0,temp=0; 8. for(int i=0;i<count;i++) { 9. for(int j=i;j<count;j++) { 10. if(x[j]<x[i]) { 11. temp=x[j]; 12. x[j]=x[i]; 13. x[i]=temp; 14. } 15. } 16. } 17. for(int i=1;i<count-1;i++) { 18. aver=aver+x[i]; 19. } 20. if(count>2) 21. aver=aver/(count-2); 22. else 23. aver=0; 24. return aver; 25. } 26. } 27. class School implements CompurerAverage {//重写public double average(double x[]);返回数组x[]的元素的算术平均 28. public double average(double x[]) { 29. int count=x.length; 30. double aver=0; 31. for(int i=0;i<count;i++) { 32. aver=aver+x[i]; 33. } 34. if(count>0) 35. aver=aver/(count); 36. else 37. aver=0; 38. return aver; 39. }//重写public double average(double x[])方法,返回数组x[]的元素的算术平均 40. }
1. public class Estimator { 2. public static void main(String args[]) { 3. double a[] = {9.89,9.88,9.99,9.12,9.69,9.76,8.97}; 4. double b[] ={89,56,78,90,100,77,56,45,36,79,98}; 5. CompurerAverage computer; 6. computer=new Gymnastics(); 7. double result= computer.average(a); //computer调用average(double x[])方法,将数组a传递给参数x 8. System.out.printf("%n"); 9. System.out.printf("体操选手最后得分:%5.3f\n",result); 10. computer=new School(); 11. result=computer.average(b);//【代码3】 //computer调用average(double x[])方法,将数组b传递给参数x 12. System.out.printf("班级考试平均分数:%-5.2f",result); 13. } 14. }
四、实验指导
1.可以把实现某一接口的类创建的对象的地址复制给该接口声明的接口引用变量,那么该接口引用变量就可以调用被类实现的方法。
2.接口产生的多态就是指不同的子类在实现同一个接口时可能具有不同的实现方式。
实验7 创建和使用抽象类
学校员工实训
1. import java.util.Scanner; 2. abstract class EEmployee{//定义抽象类 3. private String name,sex;//声明私有字段 4. protected EEmployee (String name,String sex) {//受保护的构造方法 5. this.name = name; 6. this.sex = sex; 7. } 8. public String toString() {//重写从Object类继承来的toString()方法 9. return name+","+sex; 10. } 11. abstract public double subsidy();//声明用于计算津贴的抽象方法 12. abstract public boolean important();//声明用于判断是否是骨干员工的抽象方法 13. } 14. class Teacher extends EEmployee{//构造方法 15. private String title; 16. public Teacher (String name,String sex,String title) { 17. super(name,sex); 18. this.title = title; 19. } 20. public double subsidy() {//实现subsidy()抽象方法 21. switch(title) { 22. case "教授": 23. return 1000; 24. case "副教授": 25. return 800; 26. case "讲师": 27. return 500; 28. default: 29. return 300; 30. } 31. } 32. public boolean important() {//实现important()抽象方法 33. return title.equals("教授")||title.equals("副教授"); 34. }} 35. class Worker extends EEmployee{//定义继承于EEmployee抽象类的Worker类 36. private int workAge; 37. protected Worker(String name,String sex,int workAge) {//构造方法 38. super(name,sex); 39. this.workAge = workAge; 40. } 41. public double subsidy() { 42. return workAge*50; 43. } 44. public boolean important() { 45. return workAge >= 10; 46. } 47. } 48. public class SchoolEmployee {//主类 49. public static void main(String[] args) {//主方法 50. Scanner val = new Scanner(System.in); 51. System.out.println("输入姓名、性别、职称/工龄:"); 52. String n = val.next();//读取用户键盘输入(姓名) 53. String s = val.next();//读取用户键盘输入(性别) 54. Teacher t;//声明一个Teacher类变量 55. Worker w;//声明一个Worker类变量 56. if(val.hasNextInt()) {//判断是否为整型 57. w=new Worker(n,s,val.nextInt()); 58. System.out.println(w.toString()+","+w.subsidy()+","+w.important()); 59. } 60. else {//如果不是整型 61. t=new Teacher(n,s,val.next());//创建Teacher类对象 62. System.out.println(t.toString()+","+t.subsidy()+","+t.important()); 63. } 64. val.close(); 65. } 66. }