《Java技术》第三次作业--面向对象——继承、抽象类、接口
(一)学习总结
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语句要放在第一个语句位置。super放在第一语句位置
运行结果:
GrandParent Created.String:Hello.Grandparent.
Parent Created
Child Created
public为共有类,子继承父母,不能反过来调用,因为父类不知道子类有什么变量而且子类也得不到初始化的父类变量,导致程序出错
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();
}
}
错误:
1:父类中没有sleep,需要在父类Animal中声明在sleep方法实现覆写。
2:下转型,通过(Dog)animal将父类转为子类。
运行结果:
汪汪......!
狗狗睡觉......
狗狗睡觉......
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
(2)那么,程序的运行结果到底是什么呢?利用eclipse打开println(per)方法的源码,查看该方法中又调用了哪些方法,能否解释本例的运行结果?
(3)在Person类中增加如下方法
public String toString(){
return "姓名:" + this.name + ",年龄:" + this.age ;
}
重新运行程序,程序的执行结果是什么?说明什么问题?
1:不管有没有tostring方法,都会调用,所以输出了地址。
2:源码:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
valueOf(x) //if the argument is null, then a string equal to "null";
otherwise, the value of obj.toString() is returned.
如果参数为空字符串,则返回值为空;否则,返回tostring()的返回值。
3:结果:
姓名:张三,年龄:20
姓名:张三,年龄:20
说明了,子类Person类覆写了Object类中toString()方法
4.汽车租赁公司,出租汽车种类有客车、货车和皮卡三种,每辆汽车除了具有编号、名称、租金三个基本属性之外,客车有载客量,货车有载货量,皮卡则同时具有载客量和载货量。用面向对象编程思想分析上述问题,将其表示成合适的类、抽象类或接口,说明设计思路。现在要创建一个可租车列表,应当如何创建?
设计思路:
构造Car为父类,声明共有属性:编号名称租金
分被构造客车,货车,皮卡,三个类,继承Car类,再分别声明载客量,载货量,载客量和载货量
构造测试类,测试。
package date20180411;
public class Tes {
public static void main(String arsg[]){
Kecar ke=new Kecar();
ke.setName("只能载人的客车");
ke.setNo("001");
ke.setMoney("100 ");
ke.setZaikeliang("25人");
System.out.println(ke.tostring()+"载客量为"+ke.getZaikeliang());
Huocar huo=new Huocar();
huo.setName("只能载货的货车");
huo.setNo("002");
huo.setMoney("500");
huo.setZaihuoliang("2吨");
System.out.println(huo.tostring()+"载货量为"+huo.getZaihuoliang());
Pikacar pi=new Pikacar();
pi.setName("啥都能装的皮卡");
pi.setNo("003");
pi.setMoney("1000");
pi.setZaihuoliang("5吨");
pi.setZaikeliang("3人");
System.out.println(pi.tostring()+" 载货量为"+pi.getZaihuoliang()+" 载客量为"+pi.getZaikeliang());
}
}
package date20180411;
public abstract class Car {
private String no;
private String name;
private String money;
public Car() {
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMoney() {
return money;
}
public void setMoney(String money) {
this.money = money;
}
public String tostring() {
return this.name+" "+this.no+"的租金是:"+this.money;
}
}
package date20180411;
public class Kecar extends Car {
private String zaikeliang;
public String getZaikeliang() {
return zaikeliang;
}
public void setZaikeliang(String zaikeliang) {
this.zaikeliang = zaikeliang;
}
}
package date20180411;
public class Huocar extends Car {
private String zaihuoliang;
public String getZaihuoliang() {
return zaihuoliang;
}
public void setZaihuoliang(String zaihuoliang) {
this.zaihuoliang = zaihuoliang;
}
}
package date20180411;
public class Pikacar extends Car {
private String zaikeliang;
private String zaihuoliang;
public String getZaikeliang() {
return zaikeliang;
}
public void setZaikeliang(String zaikeliang) {
this.zaikeliang = zaikeliang;
}
public String getZaihuoliang() {
return zaihuoliang;
}
public void setZaihuoliang(String zaihuoliang) {
this.zaihuoliang = zaihuoliang;
}
}
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();
}
}
编译出错
dog类的eat方法需要加上public
当重写接口中的方法时,如果不添加public,那么它只有包访问权限,这样在方法被继承的过程中,他的访问权限就会被降低。java编译器中这样的情况是不允许的。
运行结果:
I'm breathing
I'm eating
6.其他需要总结的内容。
接口要定义完整格式,借口声明用interface,接口实现用 implements:class 类名 implements 接口列表 { 类体 }
接口回调实现多态:把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法。实际上,当接口变量调用被类重写的接口方法时,就是通知相应的对象调用这个方法。
接口应用:工厂模式。
注意抽象和接口的使用
(二)实验总结
本次实验包括实验四和实验五两次的内容:
对完成实验内容过程中遇到的问题、解决方案以及程序的设计思路和思考等进行归纳总结。
实验四:
1:设计思路:首先开户,需要密码,姓名,开户金额,所以构造方法,需要传入这三个变量,声明静态变量交易额,注意交易额和余额的关系,存钱+,取钱-,判断密码正确与否,判断余额是否充足。
问题1:
开户之后,姓名,密码,余额,为空
解决方法:
只声明一个对象
2:设计思路:定义共有属性员工类,包含姓名,年龄,性别三个属性,定义管理层类和职员类,分别继承员工类,声明自己特有属性,进行测试。
问题:无
3:设计思路:首先定义平面类(包含面积和周长两个抽象方法)和立体类(包含体积和表面积两个抽象方法),再定义圆,矩形,三角形三个类,继承平面类,分别重写抽象方法,定义圆柱,圆锥,球三个类继承立体类,重写抽象方法,测试类中,产生随机数,声明对象,随机产生不同对象的面积周长(表面积体积),判断输入是否相等。
问题1:小数点后有精度问题
解决方法:使用Math.abs()函数,进行比较
4:设计思路:定义Animal类,声明抽象方法eat,定义lion,monkey,pigeon类继承Animal类,重写抽象方法,在feeder类里,让feedAnimals方法接收一个Animal数组,利用循环输出不同对象的不同的eat方法。测试类定义三个对象数组,通过feeder对象调用feedanimal方法输出喂养状态。
实验五:
1:设计思路:首先定义接口,包含编号、种类、品种、单价、数量等属性,声明Cat和Dog,实现接口,定义petshop类,构造方法开辟空间,购买时不能超过宠物剩余量。
问题1:在测试过程中,出现输出地址情况
解决方法:在调用数组时,传递参数出错。
问题2:出现,宠物名和数量不一致,购买的宠物和输出的购买宠物列表不一致。
解决方法:声明的数组要和之前的数组对应,不对应时,数组下标++。
2:设计思路:定义接口,定义名字和叫声的抽象方法。定义cat和dog类,接口实现,对抽象方法重写。模拟器类playSound(Animal animal)方法。即参数animal可以调用实现Animal接口类重写的cry()方法和调用重写的getAnimalName()方法,测试类声明模拟器类对象,调用方法输出。
问题:无
3:设计思路:(1)定义一个抽象类交通工具类Transportation,属性:编号,型号,运输负责人。方法:无参构造和含三个参数的构造方法,get和set方法,抽象方法transport()
(2)定义一个专用运输车类JDTransportation继承交通工具类,继承父类构造方法,实现transport()方法,输出一个运输信息。
(3)定义一个接口GPS实现对货物的定位。接口中有方法showCoordinate()跟踪货物的位置信息。
(4)定义一个类Phone实现GPS接口
(5)定义一个快递任务类SendTask,具有私有属性:快递单号、货物重量。方法:无参和含参构造方法,get和set方法,
sendBefore()方法输出运输前的检查信息和快递单号。
send(Transportation t,GPS tool)方法输出运货人、车辆编号、型号信息,该方法中调用transport方法输出运输信息,调用showCoordinate()方法输出货物位置坐标。
sendAfter( Transportation t )方法输出货物运输完成后的信息
问题:无
4:设计思路:首先定义字符型的生日和入职时间,通过date接口实现转化,然后格式化输出,时间比较:用getTime方法,比较时间大小。
问题:无
(三)代码托管:链接:https://gitee.com/Mty19971013/java-hebau/tree/master/第三次作业