实验二Java类编程练习(汽院含答案)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验⼆Java类编程练习(汽院含答案)
实验⼆Java类编程练习
实验⽬的
1.掌握类及类的声明
2.掌握对象的定义和使⽤
3.掌握接⼝的定义与实现
实验导读
继承、封装和多态是Java⾯向对象的3⼤特性,它们是⾯向对象程序开发的重要环节。

继承机制的使⽤可以复⽤⼀些定义好的类,减少重复代码的编写。

多态机制可以动态调整对象的调⽤,降低对象之间的依存关系。

同时为了优化继承与多态,⼀些类除了继承⽗类还可以使⽤接⼝的形式,Java中的类可以同时实现多个接⼝,接⼝被⽤来建⽴类与类之间关联的标准。

1.类的继承(extends)
继承可以理解为现实世界中的“是⼀种(is-a)”关系,实现继承是通过extends关键字在声明类的时候指定其⽗类,其声明格式如下:
继承某个⽗类⽽⽣成新的⼦类不但拥有⽗类的变量与⽅法,还可以为⼦类添加新的成员变量和成员⽅法,以增强⽗类的功能,也就是所谓的扩展。

还可以使⽤super关键字引⽤⽗类的⽅法,然后再添加新的业务代码。

甚⾄还可以在⼦类中为⽗类的某个⽅法定义多个重载⽅法,增加该类的灵活性。

2.访问修饰符
Java中定义了private、public、protected和默认的访问修饰符,这些修饰符控制着对类和类的成员变量以及成员⽅法的访问规则。

另外,还可以辅助static和final关键字定义特殊规则。

他类都可以访问,包括任意包中的任意类以及⼦类。

private是私有类型的权限修饰符,使⽤private修饰的成员变量和成员⽅法,只能在本类中被使⽤,在⼦类中是不可见的,并且对其他包的类也是不可见的。

protected是保护级别的权限修饰符,它保护成员不会被其他包或⾮⼦类访问。

也就是说protected修饰的成员只能被⼦类和同⼀包中定义的其他类访问。

当不添加任何权限修饰符时,编译器会使⽤默认权限修饰符,该修饰符的权限级别
与protected类似,不同之处在于,其他包定义的⼦类⽆法访问⽗类默认权限修饰的成员。

3.封装(encapsulation)
封装是指把对象的属性隐藏在对象的内部,不允许外部直接访问和修改。

Java规范中的设置器和访问器就是实现封装的标准⽅法,它们⽤于设置和获取对象的属性值。

设置器⽅法的命名⼀般以set作为⽅法名的前缀,以属性名作为后缀。

访问器⽅法的命名⼀般以get或is作为⽅法名称的前缀,以属性名作为后缀。

对于boolean类型的属性,应该使⽤is前缀定义访问器⽅法。

例如:
public class Car {
private String color;
private boolean running;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
}
4.Object类
在Java中,所有的类都直接或间接继承了/doc/37e6ca63011ca300a6c390e5.html ng.Object类,它是所有类的⽗类。

Object类中常⽤的两个⽅法为equals()和toString()⽅法。

任何类都可以重写Object类中的⽅法。

5.对象的上转型对象
假设B类是A类的⼦类或间接⼦类,当我们⽤⼦类B创建⼀个对象,并把这个对象
的引⽤放到A类的对象中时:A a = new B(); 称这个A类对象a是⼦类对象b的上转型
对象。

●上转对象不能操作⼦类新增的成员变量(失掉了这部分属性);不能使⽤⼦类新增
的⽅法(失掉了⼀些功能)。

●上转型对象可以操作⼦类继承或隐藏成员变量,也可以使⽤⼦类继承的或重写的⽅
法。

●上转型对象操作⼦类继承或重写的⽅法时,就是通知对应的⼦类对象去调⽤这些⽅
法。

因此,如果⼦类重写了⽗类的某个⽅法后,对象的上转型对象调⽤这个⽅法时,
⼀定是调⽤了这个重写的⽅法。

●可以将对象的上转型对象再强制转换到⼀个⼦类对象,这时,该⼦类对象⼜具备了
⼦类所有属性和功能。

6.多态(polymophism)
多态性就是指⽗类的某个⽅法被其⼦类重写时,可以各⾃产⽣⾃⼰的功能⾏为。

当⼀个类有很多⼦类时,并且这些⼦类都重写了⽗类中的某个⽅法。

那么当我们把⼦类创建的对象的引⽤放到⼀个⽗类的对象中时,就得到了该对象的⼀个上转型对象,那么这个上转的对象在调⽤这个⽅法时就可能具有多种形态。

多态性的实现:通过⽅法的重载(overloading)、覆盖(overriding)和接⼝来实现。

●⽅法重载是Java实现⾯向对象的多态性机制的⼀种⽅式。

同⼀个类中多个⽅法有
相同的名字,不同的参数列表,这种情况称为⽅法重载。

返回类型不同并不⾜以构成⽅法重载。

当重载⽅法被调⽤时,编译器根据参数的类型和数量来确定实际调⽤哪个重载⽅法的版本。

●⽅法覆盖是Java实现多态性机制的另⼀种⽅式。

在类层次结构中,如果⼦类中的
⼀个⽅法与⽗类中的⽅法有相同的⽅法名并具有相同数量和类型的参数列表,这种情况称为⽅法覆盖。

当⼀个覆盖⽅法通过⽗类引⽤被调⽤,Java根据当前被引⽤对象的类型来决定执⾏哪个版本的⽅法。

可以通过super关键字调⽤直属⽗类中被覆盖的⽅法版本。

参考代码:附录⼀Java Code之多态。

7.接⼝
接⼝是特殊的类,只有⽅法的原型,⽅法的实现在其⼦类中具体定义。

Java不⽀持多继承性,即⼀个类只能有⼀个⽗类。

单继承性使得Java简单,易于管理程序。

为了克服单继承的缺点,Java使⽤了接⼝,⼀个类可以实现多个接⼝。

⼀个类通过使⽤关键字implements 声明⾃⼰使⽤⼀个或多个接⼝。

如果使⽤多个接⼝,⽤逗号隔开接⼝名。

如:
如果⼀个类使⽤了某个接⼝,那么这个类必须实现该接⼝的所有⽅法,即为这些⽅法提供⽅法体。

接⼝只关⼼功能,并不关⼼功能的具体实现。

接⼝回调是指:可以把实现某⼀接⼝的类创建的对象的引⽤赋给该接⼝声明的接⼝变量中。

那么该接⼝变量就可以调⽤被类实现的接⼝中的⽅法。

实际上,当接⼝变量调⽤被类实现的接⼝中的⽅法时,就是通知相应的对象调⽤接⼝的⽅法。

参考代码:附录四和接⼝有关的匿名类
8.内部类
Java⽀持在⼀个类中声明另⼀个类,这样的类称作内部类,⽽包含内部类的类成为内部类的外嵌类。

内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的⽅法也可以调⽤外嵌类中的⽅法。

内部类的类体中不可以声明类变量和类⽅法。

外嵌类的类体中可以⽤内部类声明对象,作为外嵌类的成员。

参考代码:附录⼆内部类的⽤法
9.匿名类
●和类有关的匿名类
当使⽤类创建对象时,程序允许我们把类体与对象的创建组合在⼀起,也就是说,类创建对象时,除了构造⽅法还有类体,此类体被认为是该类的⼀个⼦类去掉类声明后的类体,称作匿名类。

匿名类就是⼀个⼦类,由于⽆名可⽤,所以不可能⽤匿名类声明对象,但却可以直接⽤匿名类创建⼀个对象。

匿名类⼀定是内部类,匿名类可以继承⽗类的⽅法也可以重写⽗类的⽅法,匿名类可以访问外嵌类中的成员变量和⽅法,匿名类的类体中不可以声明static成员变量和static⽅法。

匿名类的主要⽤途就是向⽅法的参数传值。

参考代码:附录三和类有关的匿名类
和接⼝有关的匿名类
Java允许直接⽤接⼝名和⼀个类体创建⼀个匿名对象,此类体被认为是实现了接⼝的类去掉类声明后的类体,称作匿名类。

参考代码:附录四和接⼝有关的匿名类
实验内容
1. 对象的创建和使⽤
编写⼀个圆环类Ring的Java程序。

圆环类有3个数据成员,分别是内半径innerRadius,外半径outerRadius和颜⾊color,这些属性通过get和set⽅法进⾏封装。

另外,圆环类中的getArea⽅法可以返回其⾯积。

把程序中的代码补充完整,并查看结果。

public class Ring {
private double innerRadius;
private double outerRadius;
public String color;
public Ring(double iRadius, double oRadius, String c) { //初始化数据成员
【补充代码…】
}
//⽤get和set⽅法封装数据成员
【补充代码…】
public double getArea() {
【补充代码…】
}
public static void main(String[] args) {
Ring ring = new Ring(5,8,"red");
System.out.println("圆环的内半径: " + ring.getInnerRadius( ));
System.out.println("圆环的外半径: " + ring.getOuterRadius( ));
System.out.println("圆环的颜⾊: " + ring.color);
System.out.println("圆环的⾯积: " + ring.getArea() + "\n");
ring.setInnerRadius(4);
【补充代码】 //设置圆环ring的外半径为6
ring.setColor("blue");
System.out.println("圆环的内半径: " + ring.getInnerRadius( ));
System.out.println("圆环的外半径: " + ring.getOuterRadius( ));
System.out.println("圆环的颜⾊: " + ring.color);
System.out.println("圆环的⾯积: " + ring.getArea());
}
}
思考:
1)将程序中的语句Ring ring = new Ring(5,8,"red"); 改成Ring ring = new
Ring();修改后编译运⾏,此时有错误发⽣吗?分析错误的原因。

2)接着为程序添加⼀个如下所⽰的默认构造函数,观察程序运⾏是否还有上述错误发⽣?
public Ring() {
innerRadius = 1.0;
outerRadius = 2.0;
color = "white";
}
3)如果在输出圆环的⾯积时要求保留两位⼩数,程序如何修改?
4)请为圆环类Ring在添两个⽅法以便能返回内圆和外圆的周长,然后在主函数
2. 使⽤类来封装对象的属性和功能
编写⼀个Java程序,该程序中有3个类:Trangle、Lader和Circle,分别⽤来刻画“三⾓形”、“梯形”和“圆形”。

具体要求如下:
Trangle类具有类型为double的三个边(sideA,sideB,sideC),以及周长(length)、⾯积(area)属性,Trangle类具有返回周长(getLength)、⾯积(getArea)以及修改三个边(setABC)的功能。

另外还有⼀个boolean型的属性(boo),该属性⽤来判断三个数是否构成⼀个三⾓形。

Lader类具有类型为double的上底(above)、下底(bottom)、⾼(height)、⾯积(area)属性,具有返回⾯积(getArea)的功能。

Circle类具有类型为double的半径(radius)、周长(length)和⾯积(area)属性,具有返回周长(getLength)、⾯积(getArea)的功能。

把程序中的代码补充完整,并查看结果。

// Trangle .java
class Trangle
{
double sideA,sideB,sideC,area,length;
boolean boo;
public Trangle(double a,double b,double c)
{
//带参数的构造⽅法
setABC(a,b,c);
}
double getLength()
{
//⽅法体,要求计算出length的值并返回
【补充代码…仿照getArea()⽅法编写】
}
public double getArea()
{
if(boo)
{
double p=(sideA+sideB+sideC)/2.0;
area=Math.sqrt(p*(p-sideA)*(p-sideB)*(p-sideC)) ; return area;
}
else
{
System.out.println("不是⼀个三⾓形,不能计算⾯积"); return 0;
}
}
public void setABC(double a,double b,double c)
{
//参数a,b,c分别赋值给sideA,sideB,sideC
【补充代码…】
if(【补充代码】) //a,b,c构成三⾓形的条件表达式
{
【补充代码】 //给boo赋值。

}
else
{
【补充代码】 //给boo赋值。

}
}
}
// Lader.java
class Lader
{
double above,bottom,height,area;
Lader(double a,double b,double h)
{
//带参数的构造⽅法,将参数a,b,h分别赋值给above,bottom,height 【补充代码…】
}
double getArea()
{
//⽅法体,,要求计算出area返回
【补充代码…】
}
}
// Circle.java
class Circle
{
double radius,area, length;
Circle(double r)
{
//带参数的构造⽅法
【补充代码】
}
double getArea()
{
//⽅法体,要求计算出area返回
【补充代码…】
}
double getLength()
{
//getArea⽅法体的代码,要求计算出length返回
【补充代码…】
}
void setRadius(double newRadius)
{
radius=newRadius;
}
double getRadius()
{
return radius;
}
}
// AreaAndLength.java
public class AreaAndLength
{
public static void main(String args[])
{
double length,area;
Circle circle = null;
Trangle trangle = null;
Lader lader = null;
【补充代码】 //创建对象circle(半径为5)
【补充代码】 //创建对象trangle(边长分别为3,4,5)
【补充代码】 //创建对象lader
【补充代码】 // circle调⽤⽅法返回周长并赋值给length System.out.println("圆的周长:"+length);
【补充代码】 // circle调⽤⽅法返回⾯积并赋值给area
System.out.println("圆的⾯积:"+area);
【补充代码】 // trangle调⽤⽅法返回周长并赋值给length
System.out.println("三⾓形的周长:"+length);
【补充代码】 // trangle调⽤⽅法返回⾯积并赋值给area
System.out.println("三⾓形的⾯积:"+area);
【补充代码】 // lader调⽤⽅法返回⾯积并赋值给area
System.out.println("梯形的⾯积:"+area);
【补充代码】 // trangle调⽤⽅法设置三个边,要求将三个边修改为12,34,1。

【补充代码】 // trangle调⽤⽅法返回⾯积并赋值给area
System.out.println("三⾓形的⾯积:"+area);
【补充代码】 // trangle调⽤⽅法返回周长并赋值给length
System.out.println("三⾓形的周长:"+length);
}
3. 掌握上转型对象的使⽤,多态的特性
定义⼀个抽象(abstract)类,类名为Employee。

Employee的⼦类有YearWorker、MonthWorker和WeekWorker。

YearWorker 对象按年领取薪⽔(每年10万),MonthWorker对象按⽉领取薪⽔(每⽉1万),WeekWorker对象按周领取薪⽔(每周
0.5万,设定⼀个⽉4周)。

Employee类有⼀个抽象(abstract)⽅法:
public abstract double earnings();
⼦类必须重写⽗类的earnings()⽅法,给出各⾃领取每年报酬的具体⽅式。

有⼀个Company类,该类⽤Employee数组作为成员,Employee数组的单元可以是YearWorker对象、MonthWorker对象、WeekWorker对象的上转型对象。

程序能输出Company对象⼀年需要⽀付的薪⽔总额。

请按模版要求,将代码补充完整。

abstract class Employee {
public abstract double earnings();
}
class YearWorker extends Employee {
【补充代码…】//重写earnings()⽅法
}
class MonthWorker extends Employee {
【补充代码…】//重写earnings()⽅法
}
class WeekWorker extends Employee {
【补充代码…】//重写earnings()⽅法
}
class Company {
Employee[] employees;
double salaries = 0;
Company(Employee[] employees) {
this.employees = employees;
}
public double salariesPay() {
salaries = 0;
【补充代码…】//计算salaries
return salaries;
}
}
public class HardWork {
public static void main(String[] args) {
Employee[] employees = new Employee[20];
for (int i = 0; i < employees.length; i++) { if(i%3==0) employees[i] = new WeekWorker();
else if(i%3==1)
employees[i] = new MonthWorker();
else if(i%3==2)
employees[i] = new YearWorker();
}
Company company = new Company(employees);
System.out.println("公司年⼯资总额:" + company.salariesPay()); }
}
4.掌握嵌套类和内部类的概念和⽤法
编写⼀个程序要求定义⼀个外部类Outer,然后在Outer类中定义⼀个内部类Inner 和局部类Local,内部类Inner和局部类Local 的任务都是显⽰出外部类中的数组元素,然后求出这些数组元素的平均值。

请按模版要求,将代码补充完整。

class Outer {
private int data[];
Outer(int x[]) {
data = x;
}
void checkInner() {
Inner innerObj = new Inner();
【补充代码】// 调⽤Inner对象的show()⽅法
System.out.println("内部类计算的平均值: " + innerObj.average());
}
void checkLocal() {
class Local {
void show() {
System.out.print("从局部类显⽰数组元素:");
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
int average() {
int sum = 0;
for (int i = 1; i < data.length; i++) {
sum += data[i];
}
【补充代码】// 返回data数组的平均值
}
}
Local localObj = new Local();
localObj.show();
System.out.println("局部类计算的平均值: " + localObj.average()); }
class Inner {
void show() {
System.out.print("从内部类显⽰数组元素:");
for (int i = 0; i < data.length; i++) {
【补充代码】// 打印data数组的每个元素
}
System.out.println();
}
int average() {
int sum = 0;
for (int i = 1; i < data.length; i++) {
sum += data[i];
}
return sum / data.length;
}
}
}
public class InnerClassTest {
public static void main(String[] args) {
int a[] = { 6, 8, 9, 22, 34, 7, 2, 1, 15 };
Outer outerObj = new Outer(a);
outerObj.checkInner();
【补充代码】// 调⽤outerObj对象的checkLocal⽅法}
}
5.编写⼀个学⽣信息管理系统,掌握接⼝的定义⽅法以及类的继承、封装和多态的特性。

学⽣信息管理系统类图
1)定义学⽣类Student.java,该类有学号、姓名和系部三个成员变量,并⽤get
和set⽅法进⾏属性的封装,请参考类图进⾏编写。

2)定义接⼝IStudentDAO,其中包含下列数据操作⽅法
// 插⼊学⽣信息记录
public void insertStudent(Student stu);
// 删除指定学号学⽣信息记录
public void deleteStudent(String sno);
// 更新指定学⽣信息记录
public void updateStudent(Student stu);
// 按学号查询指定学⽣信息记录
public Student findStudentBySno(String sno);
// 显⽰指定学号学⽣信息记录
public void displayStudentBySno(String sno);
// 显⽰所有学⽣信息记录
public void displayAllStudent();
3)定义接⼝IStudentDAO的实现类StudentDAOImpl,其中包含⼀个静态的集合对象⽤来保存学⽣信息记录,以及接⼝的所有实现⽅法,请参考类图进⾏编写。

代码提⽰:
static List students= new ArrayList();
ArrayList类是实现了List接⼝的动态数组,数组元素可以动态增加和减少。

常⽤⽅法如下:
public int size()返回此列表中的元素数。

public boolean isEmpty()如果此列表中没有元素,则返回 true
public boolean add(E e)将指定的元素添加到此列表的尾部。

public boolean remove(Object o)移除此列表中⾸次出现的指定元素(如
果存在)。

/**
* 显⽰所有学⽣信息记录参考代码
*/
@Override
public void displayAllStudent() {
if (students.size() > 0) {
for (Student stu : students) {
System.out.println("学号: " + stu.getSno() + "\t 姓名: "
+ stu.getSname() + "\t系部: " +
stu.getSdept());
}
}else {
System.out.println("数据库中⽆学⽣记录!");
}
}
4)定义主类MainClass,实现应⽤程序的所有逻辑功能。

参考代码如下:import java.util.Scanner;
public class MainClass {
/**
* 菜单显⽰
* @param scanner
* @return int
*/
static int menu_select(Scanner scanner) {。

相关文档
最新文档