(一)学习总结
1.阅读下面程序,分析是否能编译通过?如果不能,说明原因。应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来?
class Grandparent {
public Grandparent() {
System.out.println("GrandParent Created.");
}
public Grandparent(String string) {
System.out.println("GrandParent Created.String:" + string);
}
}
class Parent extends Grandparent {
public Parent() {
System.out.println("Parent Created");
super("Hello.Grandparent.");
}
}
class Child extends Parent {
public Child() {
System.out.println("Child Created");
}
}
public class Test{
public static void main(String args[]) {
Child c = new Child();
}
}
不能通过编译,super语句只能写在子类构造方法的首行,运行结果:
GrandParent Created.String:Hello.Grandparent.
Parent Created
Child Created
子类的构造方法在运行之前,必须调用父 类的构造方法,因为在类中的所有方法中,只有构造方法是被优先调用的,所以所以super调用构造方法必须只能放在构造方法的首行,并且在一个构造方法中只能出现一次。所以不能反过来。
2.阅读下面程序,分析程序中存在哪些错误,说明原因,应如何改正?正确程序的运行结果是什么?
class Animal{
void shout(){
System.out.println("动物叫!");
}
}
class Dog extends Animal{
public void shout(){
System.out.println("汪汪......!");
}
public void sleep() {
System.out.println("狗狗睡觉......");
}
}
public class Test{
public static void main(String args[]) {
Animal animal = new Dog();
animal.shout();
animal.sleep();
Dog dog = animal;
dog.sleep();
Animal animal2 = new Animal();
dog = (Dog)animal2;
dog.shout();
}
}
animal.sleep();错误,父类对象不能调用子类新增加的方法,调用只能调用子类继承和重写过的方法;Dog dog = animal;错误,在进行对象的向下转型前,必须首先发生对象的向上转型。修改:
class Animal{
void shout(){
System.out.println("动物叫!");
}
public void sleep(){};
}
class Dog extends Animal{
public void shout(){
System.out.println("汪汪......!");
}
public void sleep() {
System.out.println("狗狗睡觉......");
}
}
public class Test{
public static void main(String args[]) {
Animal animal = new Dog();
animal.shout();
animal.sleep();
Dog dog =(Dog) animal;
dog.sleep();
Animal animal2 = new Animal();
dog = (Dog)animal2;
dog.shout();
}
}
运行结果:
汪汪......!
狗狗睡觉......
狗狗睡觉......
3.运行下列程序
class Person {
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
}
public class Test{
public static void main(String args[]){
Person per = new Person("张三",20) ;
System.out.println(per);
System.out.println(per.toString()) ;
}
}
(1)程序的运行结果如下,说明什么问题?
Person@166afb3
Person@166afb3
因为Person类中没有重写toString方法,所以test类调用的其实是Object类中的toString方法。
(2)那么,程序的运行结果到底是什么呢?利用eclipse打开println(per)方法的源码,查看该方法中又调用了哪些方法,能否解释本例的运行结果?
返回的一个字符串用于描述当前对象,返回的具体内容:类名@对象的hash码十六进制表示。
源码:
(3)在Person类中增加如下方法
public String toString(){
return "姓名:" + this.name + ",年龄:" + this.age ;
}
重新运行程序,程序的执行结果是什么?说明什么问题?
运行结果:
Object类是所有类的父类,所以这样输出对象时调用的是被子类覆写过的toString方法,即便对象per后面不写.toString,默认调用的也是子类覆写过的toString方法,所以两个输出结果是一样的。
可参考教材P229
4.汽车租赁公司,出租汽车种类有客车、货车和皮卡三种,每辆汽车除了具有编号、名称、租金三个基本属性之外,客车有载客量,货车有载货量,皮卡则同时具有载客量和载货量。用面向对象编程思想分析上述问题,将其表示成合适的类、抽象类或接口,说明设计思路。现在要创建一个可租车列表,应当如何创建?
创建一个汽车接口:包含编号、名称、租金三个属性,一个载客量接口,一个载货量接口,创建一个客车类:继承汽车接口和载客量接口;一个货车类:继承汽车接口和载货量接口;一个皮卡类:继承汽车接口、载客量接口和载货量接口。再创建一个租车类,声明接口变量,实例化成相应的子类对象,分别调用子类重写的方法,用于输出租车列表。
5.阅读下面程序,分析代码是否能编译通过,如果不能,说明原因,并进行改正。如果能,列出运行结果
interface Animal{
void breathe();
void run();
void eat();
}
class Dog implements Animal{
public void breathe(){
System.out.println("I'm breathing");
}
void eat(){
System.out.println("I'm eating");
}
}
public class Test{
public static void main(String[] args){
Dog dog = new Dog();
dog.breathe();
dog.eat();
}
}
不能通过编译,第一:因为接口是由全局变量和抽象方法组成的,访问权限必须是public,在子类覆写时不能降低访问标志符的级别,所以应改成 public void eat()
第二:子类必须要继承父类的所有方法。
更改:
interface Animal{
void breathe();
void run();
void eat();
}
class Dog implements Animal{
public void breathe(){
System.out.println("I'm breathing");
}
public void eat(){
System.out.println("I'm eating");
}
public void run() {
System.out.println("I'm runing");
}
}
public class Test{
public static void main(String[] args){
Dog dog = new Dog();
dog.breathe();
dog.eat();
}
}
6.其他需要总结的内容。
(二)实验总结
本次实验包括实验四和实验五两次的内容:
对完成实验内容过程中遇到的问题、解决方案以及程序的设计思路和思考等进行归纳总结。
格式如下:
实验四
1、程序设计思路:定义一个银行类,包含静态方法欢迎语,构造方法,存款方法,取款方法,静态方法结束语。交易类用于模拟测试。
问题1:在测试的时候,出现了存钱不累积,开户的信息不存储,进行取钱和存钱不能在开户的基础上进行加减。
原因:在声明对象的时候是在循环内部声明的,所以出现了多个对象
解决方案:在外部统一声明,用同一个对象调用。
2、程序设计思路:继承父类所有方法,并增加新的方法。
3、程序设计思路:平面图型类分别被圆形类,三角形类,矩形类继承;立体图型类分别被圆柱类,圆锥类,球类继承;在测试类中声明两个父类的对象,分别用于调用相应的子类方法,一个判断周长,面积的方法;一个判断表面积,体积的方法。
4、程序设计思路:动物类分别被狮子类、猴子类、鸽子类继承,喂食类,测试类分别对对象向上转型实例化,并开辟相应的数组空间,以调用子类重写的方法。
问题1:向上转型
原因:没有给数组开辟空间
解决方案:分别开辟空间
实验五
1、程序设计思路:设计宠物接口,猫类和狗类分别实现接口,商店类:一个方法为数组开辟空间,用来存放宠物店里已有宠物;一个添加方法,给数组存储宠物信息;展示宠物方法用来输出店里的所有宠物;一个查找方法,当用户输入要购买的宠物编号时,就在数组中进行查找,找到后就存入一个新的数组,用于最后打印购物清单。一个show类:先向用户展示所有宠物,用户可输入要购买的宠物编号和数量,然后用户可选择继续购买,或是打印清单,最后打印购物清单和价钱合计。
问题1:出现空指针异常
原因:查找时出现问题,可以通过编号找到相应的宠物,但是会在输出的时候出现异常,就不再向下进行了,不能打印最后的合计,
解决方案:仍未解决
2、程序设计思路:接口Animal,有两个抽象方法,接口的Dog类和Cat类,模拟器类Simulator,参数可以调用子类重写的方法,测试类。
3、程序设计思路:定义抽象类交通工具类,运输车类继承抽象类,定位接口,一个Phon类实现接口,快递任务类:输出运输信息。测试类:用户可输入重量和单号,则输出物流信息。
4、程序设计思路:日期类按照书上的方式改写了,但是测试类不知道该怎么调用。
(三)代码托管(务必链接到你的项目)
码云提交历史截图
上传实验项目代码到码云,在码云项目中选择“统计-提交”,设置搜索时间段,搜索本周提交历史,并截图。
https://gitee.com/hebau_java_cs16/Java_CS02GX/commits/master