实验3 继承性和多态

一、实验目的

熟悉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;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值