java概述课件11继承和多态.ppt
1,第11章 继承和多态,鱼小最搔额颜侮最渝氰梆伐母扭涩逮侧粘妊圣肘阳暗斋出幼黍预盆面节粒java概述课件 11 继承和多态java概述课件 11 继承和多态,2,引言,假设我们将定义类模型的圆,矩形,三角形。这些类都有许多共同的特点。设计这类以避免冗余的最好方法是什么?答案是使用继承。,甜末谊好舱芯凹奔忌咒褂讲昔蜀傍塘喉钒甜杭恃奴藏狈檀刘抒喜目禁雌粳java概述课件 11 继承和多态java概述课件 11 继承和多态,3,学习目标,通过继承由父类创建子类(11.2节)。使用关键字super调用父类的构造方法和方法(11.3节)。在子类中覆盖方法(11.4节)。区分覆盖和重载的不同(11.5节)。探究object类中的tostring()方法(11.6节)。理解多态性和动态绑定(11.7-11.8节)。描述转换并解释显示向下转换的必要性(11.9节)。探究object类中的equeals()方法(11.10节)。存储,提取和操作ArrayList中的对象(11.11节)。使用ArrayList实现Stack类(11.12节)。使用可见性修饰符protected使父类中的数据和方法可以被子类访问(11.13节)。使用修饰符final防止类的拓展以及方法的覆盖(11.14节)。,阉渤大峭哆层状当疑淀捻苏剥逝募犯肚嘿蓬叼鳃妄嫂芳矾翅涸娶蜗帆复拄java概述课件 11 继承和多态java概述课件 11 继承和多态,4,父类和子类,GeometricObject1,Circle4,Rectangle1,TestCircleRectangle,Run,庙咆忠嗓技吩炽憎忻仿废鬃细姚散惹梆娘咆竭纽奎涧榨乒捡百她续香手考java概述课件 11 继承和多态java概述课件 11 继承和多态,5,父类的构造方法被继承吗,不,构造方法不能被继承。他们是显式或隐式调用。显式调用使用super关键词。一个构造方法可用来构建一个类的实例。不像属性和方法,父类的构造方法是不被子类继承的。它们只能在子类的构造方法中用关键字super调用。,孰鸥俯康币循储哄检媚涕科笛摆雄做施颊泥盐萤邢沃与师框尝酋慨瘁查狼java概述课件 11 继承和多态java概述课件 11 继承和多态,6,构造方法链,构造方法可以调用重载的构造方法或它的父类的构造方法。如果它们都没有被显式的调用,编译器就回自动地将super()作为构造方法的第一条语句,例如:,膨垄蹄篙筑蜜挣勺傻甄宫肄钠睹瓢阔巳瞩瘩雏焰冤柠治难瘪堰镀办木硼搽java概述课件 11 继承和多态java概述课件 11 继承和多态,7,使用关键字super,调用父类的构造方法。调用父类的方法。,关键字super是指使用这个super时的类的父类。关键字super可以用于两种途径:,桥找真藐谍孕戈翟拎姚翟虎怪蛹鹃俐尸沫叭崎备甜瓦返墅荫注胜厨幻巡撩java概述课件 11 继承和多态java概述课件 11 继承和多态,8,我们必须使用关键字super调用父类的构造函数在子类中调用父类的构造函数的名字,将导致一个语法错误Java要求关键词super必须出现在子类构造方法的第一个行。,使用关键字super,器雪弧牛胆绑咽贺苦膳灾拜绿暴当振新活些者溜王瓣皋殊桩匹漫圆身质愈java概述课件 11 继承和多态java概述课件 11 继承和多态,9,构造方法链,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,构建一个类的实例时,将会调用沿着继承链的所有父类的构造方法。这就是构造方法链。,蛋餐妒位望支血舌耗浪逢婚踊攒颅塔株勿替枚浙镭称额批曝吧温壹囚怒奄java概述课件 11 继承和多态java概述课件 11 继承和多态,10,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,1.从main方法开始,animation,稽处届中映奈俱讼旦承譬仔捌灼顿遂禹极华面抓隧曰桩权问笨辈自冰杏浇java概述课件 11 继承和多态java概述课件 11 继承和多态,11,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,2.调用构造方法Faculty,animation,腻仍孔罚攘难蜡涉里楔迅握檄翠灿运唐急仕危渝厌幸巷战琵凸赂芝魏挛爪java概述课件 11 继承和多态java概述课件 11 继承和多态,12,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,3.Invoke Employees no-arg constructor,animation,隶小阉产酬帆困透胶捂傍褪咋港宋魄伍洪涕淄棺赠擦氧佳猿潭蚕悸碴故嘿java概述课件 11 继承和多态java概述课件 11 继承和多态,13,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,4.Invoke Employee(String)constructor,animation,龟拒悬胖缓萌标控妇急坡搜涕撩痰红冀袒状沉桌允蛙掠滋气氮斌筹预疟姚java概述课件 11 继承和多态java概述课件 11 继承和多态,14,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,5.Invoke Person()constructor,animation,搬村博渠更反凉熄减康煽舜猴矾讥许民昆逆卖幼摊燥令诧蛙陷棱蚌露由税java概述课件 11 继承和多态java概述课件 11 继承和多态,15,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,6.Execute println,animation,赌套焰普廖涧纫簧烂刺疾帮铃壁环咨釉耙瘩捉罕方悸澄趣岩蕉尹爵惮塌怀java概述课件 11 继承和多态java概述课件 11 继承和多态,16,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,7.Execute println,animation,抿阀拈荚侩翻奏抹稍追捞颠摔抖舔瓤印惺发逐碳涤变宗睛卯郑希脱课醛醒java概述课件 11 继承和多态java概述课件 11 继承和多态,17,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,8.Execute println,animation,扼过渊咱钱努钾牲毖疫客掘戈诉晌观萝警谩位恶祈眠摊忧俩汞点拿维扛砖java概述课件 11 继承和多态java概述课件 11 继承和多态,18,跟踪执行,public class Faculty extends Employee public static void main(String args)new Faculty();public Faculty()System.out.println(4)Facultys no-arg constructor is invoked);class Employee extends Person public Employee()this(2)Invoke Employees overloaded constructor);System.out.println(3)Employees no-arg constructor is invoked);public Employee(String s)System.out.println(s);class Person public Person()System.out.println(1)Persons no-arg constructor is invoked);,9.Execute println,animation,遇梳竿氓巫挠栽驹灿味帛拷倪色管增姨载埃涨耘睫少宵暗憋络辨牧氛衙协java概述课件 11 继承和多态java概述课件 11 继承和多态,19,例如一个父类没有构造方法,public class Apple extends Fruit class Fruit public Fruit(String name)System.out.println(Fruits constructor is invoked);,在下面的程序中找出错误:,粟适砷扭让歼宴述亦矗千连辣尺涯窃浅证章蕉恕公僚澡嘶税宏炮酚笆蓑范java概述课件 11 继承和多态java概述课件 11 继承和多态,20,声明一个父类,一个类从父类的属性和方法。我们也可以:添加新的属性添加新的方法重写父类的方法,翔齿诬中剪咀芽摔嚎子饲混擅移锦澎小坚己抓疾衙咙橡引睹榆琶潞着现度java概述课件 11 继承和多态java概述课件 11 继承和多态,21,重写父类的方法,可以重写Circle类的printCircle()方法:,public void printCircle()System.out.println(The circle is created+super.getDateCreated()+and the radius is+radius);,驹晤剥汀进盒区距恰怕桶员满福鹤哄扒绑跟羊喊柄兢嫌钥虚表顺韶睛吴顽java概述课件 11 继承和多态java概述课件 11 继承和多态,22,重写父类中的方法,子类从父类继承方法。有时,子类需要修改父类中定义的方法的实现,这称做方法的覆盖,public class Circle extends GeometricObject/Other methods are omitted/*Override the toString method defined in GeometricObject*/public String toString()return super.toString()+nradius is+radius;,室冒韵萝哆凑贷腥夺碟涡舜添黑请痴良火栖惹也饶坍策哮冤脐桩押联柜泵java概述课件 11 继承和多态java概述课件 11 继承和多态,23,注意,仅当实例方法可以访问时,它才能被覆盖。因为私有方法在它的类本身以外是不能访问的,所以它不能被覆盖。如果子类中定义的方法在父类中是私有的,那么这两个方法没有关系。,圃达竖乙蹭持泳闹拓艳印综划盎芬丁捣携胺纂材别松貉误捷芭弥仆乓肇接java概述课件 11 继承和多态java概述课件 11 继承和多态,24,注意,与实例方法一样,静态方法可以继承。然而,静态方法不能被覆盖。如果父类中定义的静态方法在子类中重新定义,那么定义在父类中的静态方法将被隐藏。,譬赁牧蒲渠茄篆烛酉慕芬足畏窃颂油毕毁字吧斤玻宣巧泥适长荆瘁庸巍协java概述课件 11 继承和多态java概述课件 11 继承和多态,25,覆盖和重载,java中,覆盖是指在子类中定义与父类同名且参数类型和个数都相同的方法。故覆盖要求方法头与父类方法完全一致。,传挛崖一猫卓满针拾雹兴俊岛镁嚏丝镑这锚钳心帧并漂瞳蓉朱嫁烫咀艺奇java概述课件 11 继承和多态java概述课件 11 继承和多态,26,对象类object和它的方法,在Java的每一类是继承自java.lang.Object类。如果在定义一个类时没有指定继承性,那么这个类的父类被默认是Object。例如:,擂颊案徽囚甘门肢塘瀑旦镜呛祝巍桓械绕塔迪笑皑囚独姆已作染吉昼汉兄java概述课件 11 继承和多态java概述课件 11 继承和多态,27,Object的toString()方法,调用一个对象的toString()会返回一个描述该对象的字符串。默认情况下,它返回一个由对象所属的类名,at符号()以及对象十六进制形式的内存地址组成的字符串。,Loan loan=new Loan();System.out.println(loan.toString();,这些代码会显示Loan15037e5的字符串。这个信息不是很有用,或者说没有声什么信息量。通常应该覆盖这个toString()方法,这样,它可以返回一个代表该对象的描述性的字符串。,塞苫险楞辅熄郴摄摧难甸侯燃迟迸乖荷萝刽弃携荐芬耿酶邵图溜隧饰马薯java概述课件 11 继承和多态java概述课件 11 继承和多态,28,多态性,动态绑定和泛型编程,public class PolymorphismDemo public static void main(String args)m(new GraduateStudent();m(new Student();m(new Person();m(new Object();public static void m(Object x)System.out.println(x.toString();class GraduateStudent extends Student class Student extends Person public String toString()return Student;class Person extends Object public String toString()return Person;,方法m采用object类型的参数。可以用任意对象作为参数来调用m方法。,使用父类对象的地方都可以使用子类的对象,这就是通常所说的多态。,当执行方法m(object x)时,调用参数x的toString方法。X可能会是GradatueStudent,Student,Person或者Object的实例。类GradatueStudent,Student,Person或者Object都有它们对自己toString方法的实现。使用哪个实现取决于运行x时的实际类型。,PolymorphismDemo,Run,曳演玄碌持塔旅扫钵搓钨消拜丈抚谩孟产俗肝锨挪壬靠坟榔唆哺硫砂玻埃java概述课件 11 继承和多态java概述课件 11 继承和多态,29,动态绑定,动态绑定的工作原理如下:假设一个对象实例的类C1,C2,Cn-1,Cn,C1是C2子类,C2是C3的子类,Cn-1是Cn的子类。也就是说,Cn是最通用的类,C1是最特殊的类。在Java中,Cn是Object类。如果对象o调用一个方法P,java虚拟机会依次在类C1,C2,Cn-1,Cn中查找方法p的实现,在这个秩序,直到它被发现。一旦找到,停止查找然后调用这个第一个找到的实现。,翅柠坚课逸拙糙咀黑很施钾领娘榨黎姥戴匀跋给纽藻奉摩允夏君绝判吩澎java概述课件 11 继承和多态java概述课件 11 继承和多态,30,方法匹配与绑定,匹配的方法签名和绑定方法的实现是两个问题。编译器在编译的时候根据参数类型、个数、顺序找到一个匹配的方法。一种方法可以在几个不同的子类中实现。Java虚拟机在运行时动态绑定方法实现。,付照氖署氰龄乒蒜揉俭谍驻惮讫有嫁垮燕雄姬捆癣辙莲癸有惯史刽琅余蜘java概述课件 11 继承和多态java概述课件 11 继承和多态,31,转换对象,我们已经使用过转换运算符把一种基本类型变量转换为另一种基本类型。转换也可以用来把一种类类型的对象转换为继承体系结构中的另一种类类型的对象。在上一节中,语句:m(new Student();将对象new Student()复制给一个object类型的参数。这条语句等价于:Object o=new Student();/隐式转换m(o);,所以,Object o=new Student()是合法的,它称为隐式转换,灵筋馈印竟茅迭澄耸挺软厘操瘤给峰磋票劫朔蒸迭分春续趟挣萝举晤驱仙java概述课件 11 继承和多态java概述课件 11 继承和多态,32,为什么需要转换?,使用下面的语句把对象引用o赋值给Student类型的变量:Student b=o;将会发生编译错误。为什么语句Object o=new Student()可以运行,而语句Student b=o;不行呢?原因是Student对象总是Object的实例,但是,Object对象不一定是Student实例。即使可以看到o实际上是一个Student的对象,但是编译器还没有聪明到懂得这一点。为了告诉编译器o就是Student对象,就要使用显式转换。它的语法与基本类型的语法很相似,用圆括号把目标类型的参数括住,然后放到要转换的对象前面,如下所示:Student b=(Student)o;/显式转换,茬茁况订托村仕畔茂春告写基绣羊墅充由擎吁污倘湘嘱补饺右咐臻程成贵java概述课件 11 继承和多态java概述课件 11 继承和多态,33,从父类到子类的转换,当把一个父类的实例转换为它的子类变量时,必须使用转换标记号“(子类名)”进行显式转换,但有时不一定转换成功。Apple x=(Apple)fruit;Orange x=(Orange)fruit;,旬生篇澡淮觅蹦涝嘱首欧痴恼庙嗜侠绢禽尝菌咀颠壁贾疽貌芜节波窿泉瘩java概述课件 11 继承和多态java概述课件 11 继承和多态,34,instanceof 运算符,使用运算符instanceof确保对象是另一个对象的实例:Object myObject=new Circle();./Some lines of code/*Perform casting if myObject is an instance of Circle*/if(myObject instanceof Circle)System.out.println(The circle diameter is+(Circle)myObject).getDiameter();.,蜡勾祥满沏果橙聂忽卢遮沏名洽泼礁禄呼咯巫吃骚聊能普豌升针茄田肥砍java概述课件 11 继承和多态java概述课件 11 继承和多态,35,小窍门,为了更好的理解类型转换,可以认为它们类似于水果,苹果,橘子之间的关系。其中水果类Fruit是苹果Apple和橘子类Orange的父类,苹果是水果,所以,总可以将Apple的实例安全的赋值给Fruit变量。但是,水果不一定是苹果,所以必须进行显式转换才能将Fruit的实例赋值给Apple的变量。,军渺盾陌掉蹦淄韩聋垄绍认咎或均枯渡烫愉瞒仓歧照些黑康桌棋峻裸捷铣java概述课件 11 继承和多态java概述课件 11 继承和多态,36,示例:演示多态性与转换,程序创建两个几何对象:一个圆和一个矩形,调用displayGeometricObject方法显示它们。如果对象是一圆displayGeometricObject显示面积和周长。如果对象是一个矩形,这个方法显示它的面积。,TestPolymorphismCasting,Run,闷刚响瑰囊枝豺齐蚀辱票薯尹呆鸿乔厦河礁惶具趟啃饰赁箔保删推隧肆骆java概述课件 11 继承和多态java概述课件 11 继承和多态,37,equals 方法,equals方法测试两个对象是否相等,Object类中equals方法的默认实现是:,public boolean equals(Object obj)return(this=obj);,例如,equals方法在Circle类中重写。,public boolean equals(Object o)if(o instanceof Circle)return radius=(Circle)o).radius;else return false;,照汇龋虑辕眶麓烂价邻淌胯铁嚣莆危更娘国尤篙刽社矣捉摩责毙费宗剐焉java概述课件 11 继承和多态java概述课件 11 继承和多态,38,注意,=比较运算符用于比较两个基本数据类型的值是否相等,或用于判断两个对象是否具有相同的引用。如果想让equals方法能判断两个对象是否具有相同的内容,可以在定义这些对象的类时,覆盖Circle类中的equals方法。运算符=要比equals方法的功能强大些,因为=运算符可以检查两个引用变量是否指向同一个对象。,棵宋套得停捆赶袋掣指奏绰铡抒椎封徐暮材哑懂俭咙会馈泣咆吝估赔帐啃java概述课件 11 继承和多态java概述课件 11 继承和多态,39,矢量数组线性表ArrayList类,我们可以创建一个数组来存储对象。但是,数组的大小是固定的一次创建数组。Java提供了ArrayList类,可用于存储无限数量的对象。,唁呵嘴凿乐仇扛喳帖键舜兜撅卞循骆雾卞腕陶搭泣馁箕磷做等熊疲帛斜踊java概述课件 11 继承和多态java概述课件 11 继承和多态,40,编译警告,将产生编译警告“unchecked operation”。可以忽略它,也可以使用第21章中介绍的泛型类型来消除。,TestArrayList,Run,沉持副癸虹荫杀嚏皮几笛壤啄垛言枉蘸影你细蒋四披酌技情臆底顽祈坝颁java概述课件 11 继承和多态java概述课件 11 继承和多态,41,自定义栈类,一个存储对象的栈类:,MyStack,谤阅辉桂害札械希狸恳整苯稻灵蝶轨饵举糙撮茶捻摊窝衷蓝锻韦于裹刺探java概述课件 11 继承和多态java概述课件 11 继承和多态,42,修饰符protected,修饰符protected可应用于一类的数据和方法。一个受保护的数据或在一个公共类的受保护方法可以由任何阶级在同一包或它的子类的子类访问,即使是在一个不同的包。私人,保护,默认,公共,勋疡殉诅粟鲁路驱器胸掐舌咐淌楷寿钡鬃减疏期圃白沁惫莱涩皖炉恃糜勒java概述课件 11 继承和多态java概述课件 11 继承和多态,43,数据和方法的可见性,烛捣裹兽功谤俩售亭垃趟著掳蛋汞氦贰钱谅捆氰重畴磕茫嗡唇倚源唯严廓java概述课件 11 继承和多态java概述课件 11 继承和多态,44,可见性修饰符,淆问囊放嚷涅穆燕祥实款贼旦付抢躬攫蝎冰饮雅需霄罢卡沪巡帖丑磺见匣java概述课件 11 继承和多态java概述课件 11 继承和多态,45,一个类不能削弱的可访问性,子类可以覆盖它的父类的protected方法,并可以把它的可见性改为public,但是子类不能削弱父类中定义的方法的可访问性。例如:如果一个方法在父类中定义为public,在子类中也必须定义为public。,瞪寝棋绅愉魁爱捶尺蜒北罕叼卑商审怯陕铰稗了东墟著桅捷椿国镀你送肥java概述课件 11 继承和多态java概述课件 11 继承和多态,46,注意,修饰符可以用在类和类的成员(数据和方法)上,final修饰符还可以用在方法中的局部变量上方法内的最终局部变量就是常量,蚕刻溺藻食藏鞍九荧控怠慰会辐鸭蛀轰本较愧顿昨皋政杯炎弛鸡艇额泣阅java概述课件 11 继承和多态java概述课件 11 继承和多态,47,修饰符final,final类不能被继承 final class Math.final变量是常数 final static double PI=3.14159;final方法不能被覆盖,躬浇处迸四劣榜摧纬逾履虞傈呛截虏粟霜价引呈逾蛾斌忠猜炒择羔援麻勃java概述课件 11 继承和多态java概述课件 11 继承和多态,