一、实验目的
熟悉JAVA中的继承性和多态性。掌握子类的定义及用法,继承机制中的隐藏与覆盖。子类的构造方法的用法,对象的上转型对象,抽象类与抽象方法等。
二、实验要求
1.根据下面的要求,编写Java应用程序实现
编写程序模拟中国人、美国人是人;北京人是中国人。除主类外,程序中还有4个类:People、ChinaPeople、AmericanPeople和BeijingPeople类。要求如下:
-
People类有权限是protected的double型成员变量height和weight,以及public void speakHello()、public void averageHeight()和public void averageWeight()方法。
-
ChinaPeople类是People的子类,新增了public void chinaGongfu()方法。要求ChinaPeople重写父类的public void speakHello()、public void averageHeight()和public void averageWeight()方法。
-
AmericanPeople类是People的子类,新增public void americanBoxing()方法。要求AmericanPeople重写父类的public void speakHello()、public void averageHeight()和public void averageWeight()方法。
-
BeijingPeople类是ChinaPeople的子类,新增public void beijingOpera()方法。要求ChinaPeople重写父类的public void speakHello()、public void averageHeight()和public void averageWeight()方法。
People、ChinaPeople、AmericanPeople和BeijingPeople类的UML图如下图所示:
在主类中定义各类的对象并调用其方法输出相应信息。
package t1;
public class mymain {
public static void main(String args[]){
People people = new People();
ChinaPeople Chinese = new ChinaPeople();
AmericaPeople American = new AmericaPeople();
BeijingPeople beijingren = new BeijingPeople();
people.speakHello();
Chinese.speakHello();
American.speakHello();
beijingren.speakHello();
people.averageHeight();
Chinese.averageHeight();
American.averageHeight();
beijingren.averageHeight();
people.averageWeight();
Chinese.averageWeight();
American.averageWeight();
beijingren.averageWeight();
Chinese.chinaGongfu();
American.americanBoxing();
beijingren.beijingOpera();
}
}
class People{
protected double height;
protected double weight;
public void speakHello(){
System.out.printf("你好"+"\n");
}
public void averageHeight(){
height = 175;
System.out.printf("平均身高:"+height+"\n");
}
public void averageWeight(){
weight = 65;
System.out.printf("平均体重:"+weight+"\n");
}
}
class ChinaPeople extends People{
public void chinaGongfu(){
System.out.printf("中国功夫"+"\n");
}
//重写
public void speakHello(){
System.out.printf("中国人:你好"+"\n");
}
public void averageHeight(){
height = 170;
System.out.printf("中国人的平均身高:"+height+"\n");
}
public void averageWeight(){
weight = 60;
System.out.printf("中国人的平均体重:"+weight+"\n");
}
}
class AmericaPeople extends People{
public void americanBoxing(){
System.out.printf("美国拳击"+"\n");
}
//重写
public void speakHello(){
System.out.printf("美国人:你好"+"\n");
}
public void averageHeight(){
height = 180;
System.out.printf("美国人的平均身高:"+height+"\n");
}
public void averageWeight(){
weight = 70;
System.out.printf("美国人的平均体重:"+weight+"\n");
}
}
class BeijingPeople extends ChinaPeople{
public void beijingOpera(){
System.out.printf("京剧"+"\n");
}
//重写
public void speakHello(){
System.out.printf("北京人:你好"+"\n");
}
public void averageHeight(){
height = 170.5;
System.out.printf("北京人的平均身高:"+height+"\n");
}
public void averageWeight(){
weight = 60.5;
System.out.printf("北京人的平均体重:"+weight+"\n");
}
}
2.根据下面的描述,编写Java程序实现
假设银行Bank已经有了按整年year计算利息的一般方法,其中year只能取正整数。比如按整年计算的方法:
double computerInterest() {
interest=year*0.035*savedMoney;
return interest;
}
建设银行ConstructionBank是Bank的子类,准备隐藏继承的成员变量year,并重写计算利息的方法,即自己声明一个double型的year变量,比如,当year取值为5.216时,表示要计算5年零216天的利息,但希望首先按银行Bank的方法computerInterest()计算出5整年的利息,然后再自己计算216天的利息。那么,建设银行就必须把5.216的整数部分赋给隐藏的year,并让super调用隐藏的、按整年计算利息的方法。
要求ConstructionBank和BankOfQingdao类是Bank类的子类,ConstructionBank和BankOfQingdao都使用super调用隐藏的成员变量和方法。
计算5万元存5年零216天,在建设银行和青岛银行存的话,利息差额是多少?
ConstructionBank、BankOfQingdao和Bank类的UML图如下所示:
注:整年利率:0.035 ,建设银行按天计算利率:0.0001,青岛银行按天计算利率:0.00015
功能扩展:
参照建设银行或青岛银行,再编写一个商业银行,让程序输出8000元存在商业银行8年零236天的利息。商业银行按天计算利率是0.00012
package t2;
public class mymain2 {
public static void main(String args[]){
ConstructionBank con = new ConstructionBank();
con.savedMoney = 50000;
con.year = 5.216;
BankOfQingdao qingdao = new BankOfQingdao();
qingdao.savedMoney = 50000;
qingdao.year = 5.216;
System.out.printf("5万元存5年零216天,在建设银行和青岛银行存的话,利息差额是:"+(con.computerInterest()-qingdao.computerInterest())+"\n");
CommercialBank com = new CommercialBank();
com.savedMoney = 8000;
com.year = 8.236;
com.computerInterest();
}
}
class Bank{
int savedMoney;
int year;
double interest;
double computerInterest() {
interest = year*0.035*savedMoney;
return interest;
}
}
class ConstructionBank extends Bank{
double year; //5.216
double computerInterest(){
super.year = (int) year;
double conin;
int day = (int) (year%1*1000);
conin = day*0.0001*savedMoney + super.computerInterest();
System.out.printf("%d元存在商业银行%d年零%d天的利息:%f\n", savedMoney,super.year,day,conin);
return conin;
}
}
class BankOfQingdao extends Bank{
double year;
double computerInterest(){
super.year = (int) year;
double qdin;
int day = (int) (year%1*1000);
qdin = day*0.00015*savedMoney + super.computerInterest();
System.out.printf("%d元存在商业银行%d年零%d天的利息:%f\n", savedMoney,super.year,day,qdin);
return qdin;
}
}
class CommercialBank extends Bank{
double year;
double computerInterest(){
super.year = (int) year;
double comin;
int day = (int) (year%1*1000);
comin = day*0.00012*savedMoney + super.computerInterest();
System.out.printf("%d元存在商业银行%d年零%d天的利息:%f\n", savedMoney,super.year,day,comin);
return comin;
}
}
3.根据下面要求,编写一个Java应用程序
用类封装手机的基本属性和功能,要求手机即可以使用移动公司的SIM卡也可以使用联通公司SIM卡(可以使用任何公司提供的SIM卡)。
①.设计抽象类:设计一个抽象类SIM,该类有三个抽象方法:giveNumber()、setNumber()和giveCorpName()
②.设计手机类:设计MobileTelephone,该类有useSIM(SIM card)方法
③.各公司手机卡类:设计SIMOfChinaMobile、SIMOfChinaUnicom类
各类之间的关系如下:
package t3;
public class mymain3 {
public static void main(String args[]){
MobileTelephone phone = new MobileTelephone();
SIMOfChinaMobile mobile = new SIMOfChinaMobile();
mobile.setNumber("12345678901");
phone.useSIM(mobile);
phone.showMess();
SIMOfChinaUnicom unicom = new SIMOfChinaUnicom();
unicom.setNumber("12345678902");
phone.useSIM(unicom);
phone.showMess();
}
}
abstract class SIM{
abstract void setNumber(String x);
abstract String giveNumber();
abstract String giveCorepName();
}
class MobileTelephone{
SIM card;
void useSIM(SIM c){
card = c;
}
void showMess(){
System.out.printf("电话号码:"+card.giveNumber()+"\n");
System.out.printf("运营商:"+card.giveCorepName()+"\n");
}
}
class SIMOfChinaMobile extends SIM{
String number;
void setNumber(String a){
number = a;
}
String giveNumber(){
return number;
}
String giveCorepName(){
return "ChinaMobile:中国移动";
}
}
class SIMOfChinaUnicom extends SIM{
String number;
void setNumber(String a){
number =a;
}
String giveNumber(){
return number;
}
String giveCorepName(){
return "ChinaUnicom:中国联通";
}
}
4.根据下面要求,编写Java应用程序实现
要求有一个abstract类,类名为Employee。Employee的子类有YearWorker、MonthWorker、WeekWorker。YearWorker对象按年领取薪水,MonthWorker按月领取薪水,WeekWorker按周领取薪水。
Employee类有一个abstract方法:
public abstract earnings();
子类必须重写父类的earnings()方法,给出各自领取报酬的具体方式。
有一个Company类,该类用Employee对象数组作为成员,Employee对象数组的元素可以是YearWorker对象的上转型对象、MonthWorker对象的上转型对象或WeekWorker对象的上转型对象。程序能输出Company对象一年需要支付的薪水总额。
package t4;
public class mymain4 {
public static void main(String args[]){
Employee em[] = new Employee[3];
em[0] = new YearWorker();
em[1] = new MonthWorker();
em[2] = new WeekWorker();
Company com = new Company(em);
System.out.printf("该公司一年需要支付的薪水总额:"+(em[0].earnings()+em[1].earnings()+em[2].earnings()));
}
}
abstract class Employee{
public abstract int earnings();
}
class YearWorker extends Employee{
int num = 20;
int yearsalary = 48000;
public int earnings(){
return yearsalary*num;
}
}
class MonthWorker extends Employee{
int num = 10;
int monthsalary = 4000;
public int earnings(){
return monthsalary*num*12;
}
}
class WeekWorker extends Employee{
int num = 5;
int weeksalary = 1000;
public int earnings(){
return weeksalary*num*52;
}
}
class Company{
Employee[] yuangong;
Company(Employee[] a){
yuangong = a;
}
}
5.对于各种几何图形,一般都有求图形的面积、周长等方法。现在有圆、矩形和三角形三种图形,要求通过类来实现求三种图形的面积。
问题分析:
三种图形都有相同的方法,因此可以抽象出一个抽象类:图形类,该类有抽象的求面积方法。然后由该抽象类生成3个子类:圆类、矩形类、三角形类。在主类中实现求各类图形的面积。
各类之间的关系如下:
package t5;
public class mymain5 {
public static void main(String args[]){
Circle a = new Circle(1.0);
Rectangle b = new Rectangle(1.0,1.0);
Triangle c = new Triangle(1.0,1.0);
System.out.printf("圆的面积:"+a.area()+"\n");
System.out.printf("矩形的面积:"+b.area()+"\n");
System.out.printf("三角形的面积:"+c.area()+"\n");
}
}
abstract class Figure{
abstract double area();
}
class Circle extends Figure{
double r;
Circle(double a){
r = a;
}
double area(){
return Math.PI*r*r;
}
}
class Rectangle extends Figure{
double length;
double width;
Rectangle(double l, double w){
length = l;
width = w;
}
double area(){
return length*width;
}
}
class Triangle extends Figure{
double high;
double bottom;
Triangle(double h, double b){
high = h;
bottom = b;
}
double area(){
return 0.5*high*bottom;
}
}
6.设计一个动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声,要求如下:
- 编写抽象类Animal
Animal抽象类有2个抽象方法cry()和getAnimalName(),即要求各种具体的动物给出自己的叫声和种类名称。
- 编写模拟器类Simulator
该类有一个playSound(Animal animal)方法,该方法的参数是Animal类型。即参数animal可以调用Animal的子类重写的cry()方法播放具体动物的声音,调用子类重写的getAnimalName()方法显示动物种类的名称。
- 编写Animal类的子类:Dog和Cat类
各类的UML图如下所示:
在各子类中通过构造方法实现对子类成员变量的初始化。
- 编写主类Application(用户程序)
在主类Application的main方法中至少包含如下代码。
Simulator simulator = new Simulator();
simulator.playSound(new Dog(“藏獒”));
simulator.playSound(new Cat(“加菲猫”));
package t6;
public class Application {
public static void main(String args[]){
Simulator simulator = new Simulator();
simulator.playSound(new Dog("藏獒"));
simulator.playSound(new Cat("加菲猫"));
}
}
abstract class Animal{
abstract void cry();
abstract String getAnimalName();
}
//模拟器类
class Simulator{
void playSound(Animal animal){
System.out.printf(animal.getAnimalName()+":");
animal.cry();
System.out.printf("\n");
}
}
class Dog extends Animal{
String name;
Dog(String n){
name =n;
}
void cry(){
System.out.printf("汪汪");
}
String getAnimalName(){
return name;
}
}
class Cat extends Animal{
String name;
Cat(String n){
name = n;
}
void cry(){
System.out.printf("喵~");
}
String getAnimalName(){
return name;
}
}