1、继承,2,为什么需要继承 4-1,开发教师类,其中教师分为Java教师以及.NET教师,各自的要求如下: Java教师 属性:姓名 方法:授课(步骤:打开Eclipse、实施理论课授课)、自我介绍 .NET教师 属性:姓名 方法:授课(步骤:打开Visual studio 2005、实施理论课授课)、自我介绍,3,请问:以下这个解决方案中存在着什么问题?,为什么需要继承 4-2,代码存在重复,违背了“write once, only once”的原则,4,为什么需要继承 4-3,如何改进?有没有可能建立继承关系,让子类自动继承父类的属性和方法?,Java教师是教师吗? .NET教师是教师吗?,
2、public class Teacher private String name; / 教师姓名 public Teacher(String myName) name = myName; public void giveLesson() System.out.println(“知识点讲解“); System.out.println(“总结提问“); public void introduction() System.out.println(“大家好!我是“+ name + “。“); ,现在,所有子类中相同的代码都抽取到父类中了,5,为什么需要继承 4-4,public class JavaT
3、eacher2 extends Teacher public JavaTeacher2(String myName) super(myName); public void giveLesson() System.out.println(“启动 Eclipse“); super.giveLesson(); ,public class DotNetTeacher2 extends Teacher public DotNetTeacher2(String myName) super(myName); public void giveLesson() System.out.println(“启动 Vi
4、sual Studio .NET“); super.giveLesson(); ,使用继承,可以有效实现代码复用,子类自动继承父类的属性和方法,子类中不再存在重复代码,6,如何实现继承 3-1,在Java语言中,用extends关键字来表示一个类继承了另一个类,例如:,public class JavaTeacher2 extends Teacher /其余代码省略 ,在父类中只定义一些通用的属性与方法,例如:,public class Teacher private String name; / 教员姓名 public Teacher(String myName) /初始化属性值 publi
5、c void giveLesson() /授课方法的具体实现 public void introduction() /自我介绍方法的具体实现 ,7,如何实现继承 3-2,子类自动继承父类的属性和方法,子类中可以定义特定的属性和方法,public class Teacher private String name; / 教员姓名 public Teacher (String myName) /初始化属性值 public void giveLesson() /授课方法的具体实现 public void introduction() /自我介绍方法的具体实现 ,public class JavaTe
6、acher2 extends Teacher public JavaTeacher2(String myName) super(myName); public void giveLesson() System.out.println(“启动Eclipse“); super.giveLesson(); ,由于giveLesson()方法与父类的实现有所不同,因此重写了该方法,方法重写:子类和父类的方法具有相同的名称、参数列表、返回类型,父类中的属性和方法可以被子类继承,8,public class JavaTeacher2 extends Teacher public JavaTeacher2(
7、String myName) super(myName); ,如何实现继承 3-3,子类的构造方法中,通过super关键字调用父类的构造方法,方法重写后,通过super关键字调用父类的方法,public class JavaTeacher2 extends Teacher public void giveLesson() System.out.println(“启动 Eclipse“); super.giveLesson(); ,通过调用父类的构造方法,完成对属性值的初始化,9,一切类的“祖先”Object,在Java 中,所有的Java类都直接或间接地继承了java.lang.Object类
8、,public class MyObject / ,public class MyObect extends Object / ,在Eclipse中调用MyObject对象的成员,会自动弹出继承自Object的所有方法,10,小结 1,请编码实现动物世界的继承关系: 动物(Animal)具有行为:吃(eat)、睡觉(sleep) 动物包括:兔子(Rabbit),老虎(Tiger) 这些动物吃的行为各不相同(兔子吃草,老虎吃肉);但睡觉的行为是一致的。 请通过继承实现以上需求,并编写测试类AnimalTest进行测试。,完整代码实现,11,继承,继承性是面向对象程序设计语言的一个基本特征,通过继
9、承可以实现代码的复用。继承而得到的类为子类,被继承的类为父类,父类包括所有直接或间接被继承的类。Java中不支持多重继承。通过在类的声明中加入extends子句来创建一个类的子类: class SubClass extends SuperClass 如果省略extends子句,则该类为Object的子类。 子类可以继承父类中访问权限设定为public、protected和default的成员变量和方法,但是不能继承访问权限为private的成员变量和方法。,12,考察以下例子,货车: 属性:车牌号、车类型、购车价格、出租单价、出租里程数、吨位数、租金。 方法:租金计算等。 大客车: 属性:车牌
10、号、车类型、购车价格、出租单价、出租里程数、出租小时数、坐位数、租金。 方法:租金计算等。 小轿车: 属性:车牌号、车类型、购车价格、出租单价、出租里程数、出租天数、租金。 方法:租金计算等。,13,各类车之间的关系图示,父类(或基类、超类),子类(或派生类),14,继承的例子,何时选择继承? 一个很好的经验:“B是一个A吗?” 如果是则让B做A的子类.,15,成员变量的隐藏,如果子类声明了与父类同名的变量,那么当子类执行继承自父类的方法时,处理的是继承父类的变量,而当子类执行自己定义的方法时,处理的就是自己定义的变量。父类的变量只是被隐藏起来,在子类对象中仍占用内存空间,在子类自己定义的方法
11、中可以通过super(实例方法中)或父类名(静态方法中)来访问。,16,子类对父类属性的隐藏,如果子类声明了一个与父类的成员变量同名的成员变量,则称父类的该成员变量被隐藏(hiding) 下面代码段的输出结果是?,class Aprotected int x=10; class B extends Aprivate int x=20;void print()System.out.println(“x=“+x);public static void main(String args)B b=new B();b.print(); ,1.输出x=20还是x=10?2.如何访问从父类继承下来的x值?,
12、17,this与super,每个类中有两个隐含的对象this与super: this是代表本类的一个对象,可以通过this.属性的形式来引用本类的属性; super是代表父类的一个对象,可以通过super.属性的形式来引用父类的属性; 使用this与super可以解决父类属性被隐藏的情况; 如果在方法内部也有与类成员属性同名的变量,可以这样来区分它们(以变量名为x为例): x:代表方法的局部变量 this.x:代表本类的成员属性值 super.x:代表从父类继承下来的但被隐藏的x值,18,子类对父类方法的覆盖,如果子类声明了一个与父类的成员方法同名的成员方法,则称父类的该成员方法被重写或覆盖(
13、overriding) 方法覆盖是Java实现多态性机制的另一种方式。 出现方法覆盖时,同样可通过this和super来区分是父类方法还是子类方法。 方法覆盖规则: 1.方法名、参数个数、对应参数类型一样,也称为方法签名一样; 2.返回值类型一样; 3.子类方法的访问控制较父类方法访问控制修饰更松;,19,类方法的重载,方法重载即指多个方法可以享有相同的名字。但是这些方法的参数必须不同,或者是参数个数不同,或者是参数类型不同。 例如,要打印不同类型的数据,int, float, String, 如果不利用重载,需要定义不同名的方法:printInt(int); printFloat(float
14、); printString(String) 利用方法重载,只需要定义一个方法名:println(),接收不同的参数:println(int); println(float); println(String);,20,为什么需要多态 5-1,在教师类的基础上,开发一个类代表院部,负责对各教师进行评估,评估内容包括:1、教师的自我介绍2、教师的授课,21,为什么需要多态 5-2,public class HQ1 public void judge(JavaTeacher2 t) t.introduction(); t.giveLesson(); public void judge(DotNetT
15、eacher2 t) t.introduction(); t.giveLesson(); public static void main(String args) HQ1 hq = new HQ1(); hq.judge(new JavaTeacher2(“李明“); hq.judge(new DotNetTeacher2(“张明“); ,第一种解决方案,大家好!我是李明. 启动 Eclipse 知识点讲解 总结提问大家好!我是张明. 启动 Visual Studio 2005 知识点讲解 总结提问,控制台输出,22,为什么需要多态 5-3,现在,升级教师类,增加一种新类型:DBTeacher
16、,该类型的教师专门负责教授数据库,要求如下: 属性:姓名 方法:授课(启动Sql Server、实施理论课授课)、自我介绍同时,院部也负责对这类教师进行评估,23,为什么需要多态 5-4,如果在第一种解决方案的基础上去解决,我们需要如下两个步骤: 建立DBTeacher类 修改院部类,增加方法: judge(DBTeacher t),每增加一种新的教员类型,都要修改院部类,增加相应的judge(评估)方法,代码的可扩展性及可维护性极差,能找到这个解决方案的弊端吗?,完整代码实现,院部类完整代码实现,24,为什么需要多态 5-5,第二种解决方案使用多态,public class HQ3 publ
17、ic void judge(Teacher t) t.introduction(); t.giveLesson(); public static void main(String args) HQ3 hq = new HQ3(); hq.judge(new JavaTeacher2(“李明“);hq.judge(new DotNetTeacher2(“张明“);hq.judge(new DBTeacher(“李岚“); ,可以接收子类类型,根据实际创建的对象类型调用相应方法,大家好!我是李明. 启动 Eclipse 知识点讲解 总结提问大家好!我是的张明. 启动 Visual Studio 2
18、005 知识点讲解 总结提问大家好!我是李岚. 启动 Sql Server 知识点讲解 总结提问,控制台输出,使用多态之后,当需要增加新的子类类型时,无需更改院部类,程序的可扩展性及可维护性增强,25,什么是多态,简单来说,多态是具有表现多种形态的能力的特征 同一个实现接口,使用不同的实例而执行不同操作,彩色打印机,打印机,黑白打印机,打印效果:彩色,打印效果:黑白,打印,打印,26,public class Teacher public void giveLesson()System.out.println(“知识点讲解“);System.out.println(“总结提问“); ,如何实现
19、多态,1、子类重写父类的方法 2、编写方法时,使用父类定义的方法 3、运行时,根据实际创建的对象类型动态决定使用哪个方法,27,实现运行时多态的条件,实现运行时多态技术的条件: 有一个继承(或实现接口的)层次关系; 在子类中重写父类的(实现接口的)方法; 通过父类的引用对子类对象进行调用; 思考:除了使用数组,还有其它的使用多态性技术进行编程的方法吗?,28,小结 2,请编码实现如下需求: 乐器(Instrument)分为:钢琴(Piano)、小提琴(Violin) 各种乐器的弹奏( play )方法各不相同。 编写一个测试类InstrumentTest,要求: 编写方法testPlay,对各
20、种乐器进行弹奏测试。要依据乐器的不同,进行相应的弹奏。 在main方法中进行测试,完整代码实现,29,总结 2-1,class Base public String name; public Base() name = “Base“; public Base(String pName) name = pName; public void method() System.out.println(name); ,class Child extends Base public Child() super(“Child1“); name=“Child2“; ,给定如下Java代码,编译运行后,输出结果
21、是什么?,public class Sample public static void main(String args) Child c = new Child();c.method(); ,Child2,控制台输出,1,2,3,30,总结 2-2,给定如下Java代码,编译运行后,输出结果是什么?,public class Teacher public void giveLesson() System.out.println(“知识点讲解“); ,public class DBTeacher extends Teacher public void giveLesson() System.o
22、ut.println(“启动 SqlServer“); ,1,2,public class Test public static void main(String args) Teacher t = new DBTeacher (); t.giveLesson(); ,控制台输出,启动 SqlServer,31,抽象类,抽象类:用abstract关键字来修饰一个类时,该类叫做抽象类; 抽象类必须被继承。 抽象类不能被直接实例化。它只能作为其它类的超类,这一点与最终类(final类)正好相反。 抽象方法:用abstract来修饰一个方法时,该方法叫做抽象方法。 抽象方法必须被重写 抽象方法只有声
23、明,不能有实现。 定义了抽象方法的类必须是抽象类。 abstract returnType abstractMethod ( paramlist );,32,4. 抽象类(例子),Employee,Boss,HourlyWorker,PieceWorker,CommissionWorker,33,4. 对象初始化,Java对象的初始化发生在两个阶段:创建类的对象和创建类的实例。 在命令行中输入“java 类名” 命令后,JVM被启动,进入类载入阶段。 (1)JVM首先装载由类名指定的类,如果发现extends关键字,递归载入父类,直到Object类,以创建类的对象。 (2)按照“先基类后派生类”的顺序依次初始化静态成员变量和静态块。程序的主流程转到main方法,等待静态方法的调用或创建类的实例,以便调用非静态方法。当创建一个类的实例时,要在堆中分配足够的空间以容纳实例并将其值清零(初始化),过程如下: (3)按照“由派生类到基类”的顺序依次绑定构造方法的参数。 (4)再按照“先基类后派生类”的顺序:先完成基类的定义初始化非静态成员变量和非静态块,然后执行基类的构造方法体;接下来再完成派生类的定义初始化非静态成员变量和非静态块,然后执行派生类的构造方法体。,