classGrandparent{publicGrandparent(){System.out.println("GrandParentCreated.");}publicGrandparent(Stringstring){System.out.println("GrandParentCreated.String:"+string);}}classParentextendsGrandparent{publicParent(){System.out.println("ParentCreated");super("Hello.Grandparent.");}}classChildextendsParent{publicChild(){System.out.println("ChildCreated");}}publicclassTest{publicstaticvoidmain(Stringargs[]){Childc=newChild();}}这个程序不能通过编译。程序中Parent类继承了Grandparent类,父类中已经含有无参构造方法,对父类含参数的构造方法,子类可以通过在定义自己的构造方法中使用super关键字来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句。修改结果:
classGrandparent{publicGrandparent(){System.out.println("GrandParentCreated.");}publicGrandparent(Stringstring){System.out.println("GrandParentCreated.String:"+string);}}classParentextendsGrandparent{publicParent(){ super("Hello.Grandparent."); System.out.println("ParentCreated");}}classChildextendsParent{publicChild(){System.out.println("ChildCreated");}}publicclassTest{publicstaticvoidmain(Stringargs[]){Childc=newChild();}}运行结果:
GrandParentCreated.String:Hello.Grandparent.ParentCreatedChildCreated构造方法的继承原则:
不能在调用父类的构造方法之前,运行子类的构造方法。构造方法(constructor)是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。构造函数的功能主要用于在类的对象创建时定义初始化的状态。
构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。因为父类不知道子类有什么变量,子类也得不到初始化的父类变量,导致程序运行出错!
classAnimal{voidshout(){System.out.println("动物叫!");}}classDogextendsAnimal{publicvoidshout(){System.out.println("汪汪......!");}publicvoidsleep(){System.out.println("狗狗睡觉......");}}publicclassTest{publicstaticvoidmain(Stringargs[]){Animalanimal=newDog();animal.shout();animal.sleep();Dogdog=animal;dog.sleep();Animalanimal2=newAnimal();dog=(Dog)animal2;dog.shout();}}程序中的错误:1.编译出错animal.sleep();Dogdog=animal;
2.编译时没有问题但运行时会出错
Animalanimal2=newAnimal();dog=(Dog)animal2;dog.shout();原因:1.animal是子类Dog的上转型对象,上转型对象不能操作子类新增加的成员变量,不能使用子类新增的方法。父类对象定义为子类对象称为向下转型,对于向下转型,需要强制转型,即必须明确指明要转型的子类类型:格式:子类名称子类对象=(子类)父类实例;2.animal2是一个新定义的父类对象,即父类引用的对象是父类本身。父类对象不能确定dog是自己的子类。需要使用instanceof关键字避免此错误。改正:
classAnimal{voidshout(){System.out.println("动物叫!");}}classDogextendsAnimal{publicvoidshout(){System.out.println("汪汪......!");}publicvoidsleep(){System.out.println("狗狗睡觉......");}}publicclassTest{publicstaticvoidmain(Stringargs[]){Animalanimal=newDog();animal.shout();//animal.sleep();Dogdog=(Dog)animal;dog.sleep();Animalanimal2=newAnimal();if(animal2instanceofDog){ dog=(Dog)animal2; dog.shout();}}}运行结果:
汪汪......!狗狗睡觉......3.运行下列程序classPerson{privateStringname;privateintage;publicPerson(Stringname,intage){this.name=name;this.age=age;}}publicclassTest{publicstaticvoidmain(Stringargs[]){Personper=newPerson("张三",20);System.out.println(per);System.out.println(per.toString());}}(1)程序的运行结果如下,说明什么问题?
Person@166afb3Person@166afb3System.out.println(per);默认调用父类Object的toString方法。(2)那么,程序的运行结果到底是什么呢?利用eclipse打开println(per)方法的源码,查看该方法中又调用了哪些方法,能否解释本例的运行结果?
publicvoidprintln(Objectx){Strings=String.valueOf(x);synchronized(this){print(s);newLine();}}valueOf(x)//iftheargumentisnull,thenastringequalto"null";otherwise,thevalueofobj.toString()isreturned.如果参数为空字符串,则返回空,否则,返回toString()的返回值。toString()返回一个字符串用于描述当前对象,返回的具体内容:类名@对象的hash码十六进制表示。(3)在Person类中增加如下方法
publicStringtoString(){return"姓名:"+this.name+",年龄:"+this.age;}重新运行程序,程序的执行结果是什么?说明什么问题?可参考教材P229执行结果:
姓名:张三,年龄:20姓名:张三,年龄:20说明在Person类中完成了对父类Object的toString类的重写。
定义一个车辆接口包含三个属性:编号、名称、租金。对每个属性分别定义get,set方法。分别定义一个载客量和载货量接口,分别具有载客量和载货量属性并且定义get,set方法。客车类、货车类、皮卡类同时继承车辆接口,客车类继承载客量接口,货车类继承载货量接口,皮卡类再同是继承载客量和载货量接口。在测试类中完成可租车列表的创建。分别为客车类、货车类、皮卡类创建对象数组,每个类的对象个数表示可租车数量,每次租一辆车去掉一个对象,每进行一次租车重新显示一次可租车对象,用户每次从可租车对象中选择要租用的车辆。
interfaceAnimal{voidbreathe();voidrun();voideat();}classDogimplementsAnimal{publicvoidbreathe(){System.out.println("I'mbreathing");}voideat(){System.out.println("I'meating");}}publicclassTest{publicstaticvoidmain(String[]args){Dogdog=newDog();dog.breathe();dog.eat();}}不能通过编译。
interfaceAnimal{voidbreathe();voidrun();voideat();}classDogimplementsAnimal{publicvoidbreathe(){System.out.println("I'mbreathing");}publicvoidrun(){ }publicvoideat(){System.out.println("I'meating");}}publicclassTest{publicstaticvoidmain(String[]args){Dogdog=newDog();dog.breathe();dog.eat();}}运行结果:
I'mbreathingI'meating6.super键字和final关键字在子类重写父类方法后,要访问父类被重写的方法,需要用super关键字来引用当前类的父类。super的用法有两种情况:(1)访问的父类中的成员变量和成员方法super.变量名super.方法名([参数表])(2)调用父类的构造方法super([参数表])在Java中可以使用final关键字定义类、方法、属性:
覆盖实现多态:
重载实现多态:
publicclassTest{publicstaticvoidmain(String[]args){Personp=newStudent();//向上转型Students=(Student)p;//向下转型s.eat();s.study();Personp1=newPerson();if(p1instanceofStudent){s=(Student)p1;//向下转型s.eat();}}}9.接口接口与类的不同在于:
interfaceA{ StringAUTHOR="李兴华"; //定义全局常量 voidprint(); //定义抽象方法 StringgetInfo();//定义抽象方法}接口的实现:格式:
abstractclassDoor{publicabstractvoidopen();publicabstractvoidclose();}接口
interfaceDoor{publicabstractvoidopen();publicabstractvoidclose();}需要门具有报警alarm()的功能,怎么办?方案一:在类中或接口中增加alarm()方法,有问题吗?分析:open()和close()属于门本身固有的行为特性,而alarm()属于扩展的行为。方案二:将报警设计为一个接口,包含alarm()行为,Door设计为一个抽象类,包含open和close两种行为。设计一个报警门继承Door类和实现Alarm接口。
interfaceAlarm{voidalarm();}abstractclassDoor{publicabstractvoidopen();publicabstractvoidclose();}classAlarmDoorextendsDoorimplementsAlarm{publicvoidopen(){//......}publicvoidclose(){//......}publicvoidalarm(){//......}}(二)实验总结1.银行新用户现金业务办理设计思路:
2.定义员工类,具有姓名、年龄、性别属性,并具有构造方法和显示数据方法。设计思路:
3.按照下面要求完成类的设计设计思路:
4.饲养员小李设计思路:
5.宠物商店宠物种类有猫、狗,宠物信息包括:编号、种类、品种、单价、数量。要求实现以下功能:(1)展示所有宠物(2)购买宠物(3)展示购买清单:显示购买的宠物品种,数量,价格合计及购买宠物的总价钱
6.设计一个动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声。设计思路:
7.模拟物流快递系统设计思路:
运货人小张正在驾驶编号为zh1002的长城发送货物!京东快递运输中......货物当前坐标:193,485//运输中信息
货物运输已完成运货人小张所驾驶编号为zh1002的长城已归还!//运输后信息