第6章类的继承.ppt

上传人:sccc 文档编号:4787131 上传时间:2023-05-15 格式:PPT 页数:87 大小:379.52KB
返回 下载 相关 举报
第6章类的继承.ppt_第1页
第1页 / 共87页
第6章类的继承.ppt_第2页
第2页 / 共87页
第6章类的继承.ppt_第3页
第3页 / 共87页
第6章类的继承.ppt_第4页
第4页 / 共87页
第6章类的继承.ppt_第5页
第5页 / 共87页
点击查看更多>>
资源描述

《第6章类的继承.ppt》由会员分享,可在线阅读,更多相关《第6章类的继承.ppt(87页珍藏版)》请在三一办公上搜索。

1、第6章 类的继承能力要求,理解继承的概念以及父类和子类的关系掌握关键字super和this的使用理解成员变量的继承,了解成员变量的隐藏掌握成员方法的继承与覆盖理解如何在父类和子类中使用构造方法掌握抽象方法的使用,6.1 类的继承,6.1.1 继承的概念 在面向对象程序设计中,可以从已有的类派生出新类,这叫做继承(inheritance)。派生出的新类称为已有类的子类。已有类称为父类(超类)。继承性很好地解决了软件的可重用性问题。通过继承,一个类可能拥有已有类的所有功能。因此,只须指明新类与现有类的不同,即增加自己的属性和方法即可。通过继承,可以提高软件的开发效率,增加程序的可维护性,并且可以利

2、用已有的类完成复杂的开发。Java不支持类的多重继承,Java只支持类的单继承,即每个子类只能有一个直接父类。,6.1.2 父类和子类在类声明时通过关键字 extends来声明一个类的子类。其格式如下:class 子类名 extends 父类名 implement 接口名/类体说明:在完成上面的定义后,子类中只能继承父类中访问权限定义为:public、protected、无修饰符的成员变量和成员方法。定义权限为private的成员变量和成员方法不能继承。,【例6.1】设计一个Person类,它包括编号(no)和姓名(name)两个成员变量。从Person类派生出一个Student类,增加班号(

3、classname)和成绩(score)两个成员变量。class Person/成员变量protected int no;/编号 protected String name;/姓名/成员方法略public class Student extends Person/成员变量private String classname;/班号private double score;/成绩,/成员方法略(1)保存程序:Student.java(2)编译程序:javac Student.java例题分析:子类Student不但继承了父类Person的用protected修饰的成员变量no和name,还增加了子类

4、自己的成员变量classname和score。,【例6.2】编写一个计算几何形状面积的程序,该几何形状可能是矩形、圆形或其他的形状。设计这些类,并创建一个测试类测试它们。,/*Shape类作为父类,它有两个成员变量(名称、面积)和两个成员方法(构造方法、显示方法)。为了能够实现继承性,这些成员都不能是私有的,因此把成员变量作为保护类型(protected),成员方法作为公有类型(public)。*/,class Shape/几何形状 protected String name;protected double area;public Shape()name=不确定的几何形状;area=0;,p

5、ublic void Display()System.out.println(几何形状:+name);System.out.println(面积:+area);/*当不知道具体的形状时,不能计算面积。矩形和圆形都是几何形状,我们把它作为Shape类的子类,两个类都在构造方法中初始化自己的成员变量,在成员方法中计算面积。*/,class Rectangle extends Shape/矩形 private double length,width;public Rectangle(double len,double wid)name=“矩形;/父类Shape的成员变量protected Strin

6、g name;length=len;width=wid;public void Area2()area=length*width;/父类Shape的成员变量protected String area,class Circle extends Shape/圆 private double radius;public Circle(double r)name=“圆;radius=r;public void Area2()area=Math.PI*radius*radius;,请思考:怎样定义一个子类“梯形”,并计算梯形的面积。“梯形”的父类是Shape。,class Tixing extends

7、Shape/梯形 private double a,b,h;public Tixing(double a1,double b1,double h1)name=梯形;a=a1;b=b1;h=h1;public void Area2()area=(a+b)*h/2;,怎样定义一个子类“梯形”,并计算梯形的面积。“梯形”的父类是Shape。,public class ShapeTester3 public static void main(String args)Shape s=new Shape();Rectangle rec=new Rectangle(2.0,3.0);Circle c=new

8、 Circle(5.0);s.Display();rec.Area2();rec.Display();/思考:输出结果是什么?,/*子类的对象rec调用父类Shape的public Display()(因为子类继承了父类的公有成员方法),name是从父类继承过来的成员变量,name=矩形,area是从父类继承过来的成员变量,通过前面的rec.Area2();计算出area的值,area=2.0*3.0=6.0*/,几何形状:矩形面积:6.0,c.Area2();c.Display();,运行结果如下:几何形状:不确定的几何形状面积:0.0几何形状:矩形面积:6.0几何形状:圆面积:78.539

9、81633974483,Tixing t=new Tixing(2,3,4);t.Area2();t.Display();,输出:几何形状:梯形面积:10.0,请思考:在ShapeTester3中,怎样创建Tixing类的对象,计算一个具体的梯形的面积并显示面积?,编程实践 习题六 6.5 题 设计一个父类Base,再从Base派生出工程师类Engineer。然后,采用一些数据进行测试。(1)Base类的成员变量有:name:String型,代表姓名。age:int型,代表年龄。(2)Base类的成员方法有:Base():无参数的构造方法。void SetName(String na):用na

10、对成员变量name进行设置。void SetAge(int a):用a对成员变量age进行设置。String GetName():返回name的值。int GetAge():返回age的值。,(3)Engineer类的成员变量有:major:String型,代表专业。prof:String型,代表职称。(4)Engineer类的成员方法有:void SetMajor(String maj):用maj对成员变量major进行设置。void SetProf(String pr):用pr对成员变量prof进行设置。String GetMajor():返回major的值。String GetProf(

11、):返回prof的值。,(5)在Engineer2的main()中:创建Engineer类的对象eng,分别调用SetName()、SetAge()、SetMajor()、SetProf()分别对姓名、年龄、专业、职称进行设置。分别调用GetName()、GetAge()、GetMajor()、GetProf(),输出eng的姓名、年龄、专业、职称。,看 Engineer2.java,启发式教学法,模仿已有的程序,引导学生完成需要添加代码的地方。,/Engineer2.java。启发式教学法。引导学生编写部分代码。class Base private String name;private i

12、nt age;public Base()public void SetName(String na)name=na;/添加 SetAge(int a),public String GetName()return name;/添加 GetAge()class Engineer extends Base private String major,prof;public void SetMajor(String maj)major=maj;/添加 SetProf(String pr),public String GetMajor()return major;/添加 GetProf()public c

13、lass Engineer3 public static void main(String args)Engineer eng=new Engineer();,eng.SetName(高山);/添加代码,调用SetAge()、SetMajor()、SetProf()System.out.println(姓名:+eng.GetName();/*添加代码,调用GetAge()、GetMajor()、GetProf(),输出eng的年龄、专业、职称输出*/,6.5 题 完整代码 class Base private String name;private int age;public Base()p

14、ublic void SetName(String na)name=na;public void SetAge(int a)age=a;,public String GetName()return name;public int GetAge()return age;class Engineer extends Base private String major,prof;public void SetMajor(String maj)major=maj;public void SetProf(String pr)prof=pr;,public String GetMajor()return

15、major;public String GetProf()return prof;public class Engineer2 public static void main(String args)Engineer eng=new Engineer();eng.SetName(高山);,eng.SetAge(28);eng.SetMajor(计算机软件技术);eng.SetProf(“工程师”);System.out.println(姓名:+eng.GetName();System.out.println(年龄:+eng.GetAge();System.out.println(专业:+eng

16、.GetMajor();System.out.println(职称:+eng.GetProf();,6.1.3 使用关键字super super用来代表当前操作的子类的父类。1.调用父类的构造方法调用父类的构造方法的语法是:super();或者:super(参数);语句super()调用父类的默认构造方法,语句super(参数)调用与参数匹配的父类构造方法。语句super()和super(参数)必须出现在子类的构造方法的第一条可执行语句。,2.调用父类的成员变量和成员方法 当我们在当前操作的子类中想引用父类的一些成员变量或成员方法时,可以直接使用super代替父类名称来调用父类的成员变量或成员

17、方法。调用格式为:super.成员变量名或者:super.成员方法名(),6.1.4 使用关键字this this用来代表当前操作的对象。当正在操作一个对象时,我们调用对象方法或成员变量的方式可以为:对象名.变量名(或:对象名.方法名(),也可以用this直接代替对象名来使用,形式为:this.变量名或者:this.方法名(),【例6.3】this,super 举例。class Student int number;String name;Student(int number,String name)/形式参数与成员变量同名 this.number=number;this.name=name;

18、System.out.println(姓名:+this.name+,学号:+this.number);,如果写成以下形式(成员变量名与形式参数名不同),则不用this关键字。Student(int num,String na)number=num;name=na;System;,class Univer_Student extends Student boolean 婚否;Univer_Student(int number,String name,boolean b)super(number,name);/调用超类Student的Student(number,name),婚否=b;System

19、.out.println(婚否:+婚否);public class Stu/Stu.java public static void main(String args)Univer_Student zhang=new Univer_Student(9902,牛得草,false);,运行结果如下:姓名:牛得草,学号:9902 婚否:false,6.1.5 成员变量的继承和隐藏 子类在继承其超类(父类)时,可以继承超类中访问权限定义为:public、protected、无修饰符的成员变量。定义权限为private的成员变量不能继承。如果在子类中调用了父类的private成员变量,该操作将是非法。成员

20、变量的隐藏是指在子类中重新定义了另外一个与其所继承的超类(或父类)中同名的成员变量。这样,在子类中就有两个同名的成员变量:一个是继承父类的;另一个是自己定义的。当子类执行继承自父类操作时,处理的是继承自父类的变量。当子类执行自己的操作时,处理的是自己的变量。,【例6.4】成员变量的继承和隐藏。class Fatherint age;/父类中的无修饰符的成员变量 public Father()age=47;System.out.println(父类的构造方法);void Display()System.out.println(父亲的年龄是:+age);,class Son extends Fat

21、herint age;/子类中与父类同名的成员变量,成员变量的隐藏/子类的age和父类的age占用不同的内存单元public Son()super();/调用父类的构造方法Father()age=20;/调用的是子类的age,此处隐藏了父类的ageSystem.out.println(子类的构造方法);void Display2()System.out.println(儿子的年龄是:+age)/输出子类的age,public class Testpublic static void main(String args)/创建Father类的对象Father fa=new Father();/创建

22、Son类的对象Son s=new Son();/调用父类的Display()方法fa.Display();/调用子类的Display2()方法s.Display2();,运行结果如下:父类的构造方法,父类的构造方法子类的构造方法,父亲的年龄是:47,儿子的年龄是:20,6.1.6 成员方法的继承与覆盖 子类可以继承其父类(超类)中除private类型以外的所有方法。如果子类觉得从父类继承来的方法的功能不适合于子类,则可以声明自己的方法。在声明的时候,使用相同的方法名及参数表,但执行不同的功能。这种情况称为方法覆盖(method overriding)。一般在下面几种情况下需要使用方法覆盖:(1

23、)子类中实现与父类相同的功能,但采用不同的算法或公式。(2)在名字相同的方法中,要做比父类更多的事情。在方法的覆盖中,由于同名方法隶属于不同的类,那么,调用时如何区分它们呢?只须在方法名前面使用不同的类名或不同类的对象名即可。,【例6.5】设计一个Person类,它包括编号和姓名的输出,从它派生一个Student类,增加性别和班级的输出。class Personprotected int no;/编号protected String name;/姓名public Person()public Person(int num,String name1)no=num;name=name1;,publ

24、ic void displayData()System.out.println(编号:+no+,姓名:+name);/end of Personclass Student extends Personprivate String sex;/性别private String className;/班级 public Student(),public Student(int new_no,String new_name,String s,String c)super(new_no,new_name);sex=s;className=c;public void displayData()/子类覆盖了

25、父类的同名方法super.displayData();System.out.println(性别:+sex+,班级:+className);,public class StuTestpublic static void main(String args)String name2=鱼得水;Person onePerson=new Person(1,name2);Student oneStudent=new Student(2,“马千里”,“男”,“软件 02306);/*在方法名前面使用不同类的对象名onePerson、oneStuden,来区分同名方法dispData()*/onePerson

26、.displayData();/调用父类的方法displayData()oneStudent.displayData();/调用子类的方法displayData(),运行结果如下:编号:1,姓名:鱼得水编号:2,姓名:马千里性别:男,班级:软件02306,【例6.6】举例:成员方法的覆盖。编写一个计算几何形状面积的程序,该几何形状可能是矩形或圆形。class Shape/几何形状 protected String name;protected double area;public Shape()name=不确定的几何形状;area=0;public void Display()System.o

27、ut.println(name+,面积:+area);,class Rectangle extends Shape/矩形 private double length,width;public Rectangle(double len,double wid)name=矩形;length=len;width=wid;public void computeArea()area=length*width;public void Display()/覆盖Shape 中的Display 方法 super.Display();/调用Shape 的Display(),/Shape.Display(),Syst

28、em.out.println(长:+length);System.out.println(宽:+width);,class Circle extends Shape/圆 private double r;public Circle(double r2)name=圆;r=r2;public void computeArea()area=Math.PI*r*r;,请思考:请试着在Circle类中增加一个成员方法Display(),在该方法中调用父类的Display()方法,然后在Circle类的Display()中输出圆的半径。,class Circle extends Shape/圆 prote

29、cted double radius;public Circle(double r)name=Circle;radius=r;public void computeArea()area=Math.PI*radius*radius;public void Display()/增加的方法 super.Display();System.out.println(半径:+radius);,public class ShapeTester/ShapeTester.java public static void main(String args)Shape s=new Shape();Rectangle r

30、ec=new Rectangle(2.0,3.0);Circle c=new Circle(4.0);puteArea();puteArea();rec.Display();,rec.display()输出:矩形,面积:6.0长:2.0宽:3.0,c.Display();/圆,面积:50.26548245743669 s.Display();/不确定的几何形状,面积:0.0,运行结果如下:矩形,面积:6.0长:2.0宽:3.0圆,面积:50.26548245743669不确定的几何形状,面积:0.0,简言之:应尽量避免覆盖成员变量。如果有需要(例如:父类中的方法不适合子类),则覆盖成员方法。小

31、结:成员变量、成员方法的覆盖遵循以下的原则:(1)有时父类的方法和变量不一定适合子类,在这种情况下,子类可以对这些变量和方法进行重新定义,即覆盖原来的定义。(2)成员变量和成员方法的覆盖:如果在子类中重新定义了一个与它的父类完全相同的一个变量(或方法),子类的变量(或方法)将覆盖超类中的同名变量(或方法)。此时,父类中该变量(或方法)仍可在子类中使用,但要加上关键字super和圆点操作符。例如:super.display();,(3)通常的规则是覆盖成员方法比重载方法更普遍,但是应尽量避免覆盖成员变量。(4)如果一个父类中的方法不适合子类,可以在子类中使用与父类中一样的方法头部进行覆盖。如果继

32、承过来的方法还能使用,可以通过使用super关键字避免代码重复。(5)如果重定义的方法的参数列表与父类中该方法的列表不一致,那么应该在父类中重载,而不是在子类中覆盖。(6)尽量避免覆盖成员变量,它会使代码难于理解。覆盖一个类的基本功能可能会造成一些问题,所以在覆盖前一定要了解所有继承来的方法。,6.1.7 有继承时的构造方法 子类可以继承父类的构造方法,构造方法的继承遵循以下的原则:(1)子类无条件地继承父类的不含参数的构造方法。(2)如果子类自己没有构造方法,则它继承父类的无参数构造方法作为自己的构造方法;(3)如果子类自己定义了构造方法,则在创建新对象时,它将先执行继承自父类的无参数构造方

33、法,然后再执行子类自己的构造方法。(4)对于父类的含参数构造方法,子类可以通过在自己的构造方法中使用super关键字来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句。,【例6.7】举例:构造方法的继承。class ParentParent()/无参数的构造方法System.out.println(Parent1);Parent(int i)/带参数的构造方法System.out.println(Parent2);,public class Child extends Parent/Child.java Child()/子类的构造方法/super();System.out.print

34、ln(Child1);Child(int i)/子类的构造方法/super();System.out.println(Child2);Child(int x,int y)/子类的构造方法 super(x);/Parent(x)System.out.println(Child3);,public static void main(String args)/Child child11=new Child();/原则(2),Parent1/*先将Child(),Child(int i),Child(int x,int y)方法 作为注释,然后运行Child child11=new Child();。

35、*/Child child12=new Child();/原则(3),Parent(),Child()/*Parent1Child1*/,Child child2=new Child(2);/原则(3),Parent(),Child(2)/*Parent1Child2*/Child child3=new Child(6,7);/原则(4),Child(6,7)/*Parent2 Child3*/,运行结果如下:Parent1Child1Parent1Child2Parent2Child3,编程技巧:避免隐蔽地调用超类的构造方法,可使用下面的两种解决方法。(1)每个子类的构造方法都应当明确地调用

36、父类的一个构造方法,而且必须在第一行调用。(2)为每个可能成为父类的类提供一个无参数构造方法,如果还有其他需要,则重载构造方法,提供带参数的构造方法。,6.2 final类有时可能不希望类被扩展,在这种情况下,用final修饰符说明一个类是终极的(final),不能做父类。final类是终极类,即不能被继承的类。它不能够产生子类,只能直接使用。例如,Java中的Math类、String类都是终极类。final类的最大优点是:(1)可以提高系统安全性。黑客常用的一种技术是设计一个子类,然后用它替换原来的父类以达到盗取或破坏他人信息的目的。最终类可以避免该种情况的发生。(2)在编程过程中,程序员可

37、以把一个编写的无懈可击的类声明为最终类,防止其他人通过继承改动程序等等。,【例6.8】最终类举例。public final class FinalExpublic static void main(String a)/代码略,6.3 抽象类和抽象方法1.抽象类(abstract class)abstract修饰符用于定义抽象类。抽象类是不能被实例化的类,即这种类不能直接产生对象,使用这种类的唯一方式是用它产生子类,然后用其子类来产生对象达到使用的目的。Java规定:抽象类不一定含有抽象方法,但有抽象方法的类一定是抽象类。抽象类中的抽象方法不需要写具体实现(在子类中必须重写该方法且给出具体实现,

38、这一点与接口相同);抽象类中的非抽象方法可以写具体实现也可不写。,2.抽象方法(abstract method)抽象类中一般定义一些在本类中不能实现的方法(抽象方法),抽象方法没有方法体,主要作用是可以定义一个统一的编程接口,在子类中产生多态(同名方法在不同的子类中具有不同的实现)。抽象类中可以没有抽象方法,但有抽象方法的类一定是抽象类,否则定义将会出错。在前面的内容中我们讲过,抽象的类不能直接产生对象,只能通过继承来使用。,【例6.9】抽象类和抽象方法举例。求多种规则图形的面积。abstract class Graph/图形 public abstract double Area();/抽象

39、方法Area public void printArea()System.out.println(面积是:+Area();class Circle extends Graph/圆形 private double r;public Circle(double r2)r=r2;,public double Area()return 3.14159*r*r;class Tixing extends Graph/梯形 private double a,b,h;public Tixing(double A,double B,double H)a=A;b=B;h=H;,public double Area

40、()return(a+b)*h/2;public class AreaTest/文件名:AreaTest.java public static void main(String args)Circle c1=new Circle(3);Tixing v1=new Tixing(2,3,4);c1.printArea();v1.printArea();,运行结果如下:面积是:28.274309999999996面积是:10.0,例题分析:父类Graph(图形)是一个抽象类,因为图形不同,计算面积的公式也不同,所以在父类Graph(图形)中定义了一个抽象方法Area()。在子类Circle(圆形)

41、、Tixing(梯形)中实现计算具体图形的面积的功能,编程实战 习题六 6.8题(参考:例6.9)6.8 定义一个动物Animal类,再由此派生出狗Dog类、猫Cat类。都定义了Speak()成员方法,在父类中Speak()定义为抽象方法。测试类DogCat中,分别定义一个Dog类的对象、Cat类的对象,分别调用Speak(),输出狗和猫的叫声。,6.8 题 abstract class Animal public abstract void Speak();class Dog extends Animalpublic void Speak()System.out.println(小狗:汪汪汪

42、);,class Cat extends Animal public void Speak()System.out.println(“小猫:喵喵喵”);public class DogCat public static void main(String args)Dog d=new Dog();Cat c=new Cat();d.Speak();c.Speak();,编程实战 习题六 6.9 题6.9 计算立方体、球体和圆柱体的体积。父类container类为抽象类(该抽象类没有体积可言),其中,定义了成员变量r,此数据可作为立方体的边长、球体的半径、圆柱体底面圆半径,还定义了求体积的抽象方法

43、volume()。由container抽象类派生出三个子类:cube(立方体)、sphere(球体)和cylinder(圆柱体)。在这三个类中具体实现求体积的功能,覆盖父类的volume()方法。在Tiji类的main()中,创建cube(立方体)、sphere(球体)和cylinder(圆柱体)类的对象,并利用各自的构造方法分别对立方体的边长、球体的半径、圆柱体底面圆半径、圆柱体的高进行初始化。最后,输出具体的立方体、球体和圆柱体的体积。,先看 Tiji.java,启发式教学法,模仿已有的程序,引导学生完成需要添加代码的地方。,abstract class container/抽象类prot

44、ected double r;public container(double r)this.r=r;public abstract double volume();class cube extends container/立方体 public cube(double r)super(r);public double volume()return r*r*r;,/添加代码,写出子类球体sphere/*添加代码,写出子类圆柱体cylinder 在圆柱体中增加私有的成员变量h(圆柱体的高),并利用构造方法对h进行初始化。*/public class Tiji public static void m

45、ain(String args)cube c=new cube(2.0);/添加代码,创建sphere类的对象、cylinder类的对象 System.out.println(立方体体积=+c.volume();/添加代码,输出球体的体积、圆柱体的体积,6.9 题 完整程序abstract class container/抽象类protected double r;public container(double r)this.r=r;public abstract double volume();class cube extends container/立方体 public cube(doub

46、le r)super(r);public double volume()return r*r*r;,class sphere extends container/球体public sphere(double r)super(r);public double volume()return 3.1416*r*r*r*4/3;class cylinder extends container/圆柱体 private double h;public cylinder(double r,double h)super(r);this.h=h;public double volume()return 3.14

47、16*r*r*h;,public class Tiji public static void main(String args)cube c=new cube(2.0);sphere s=new sphere(3.0);cylinder cy=new cylinder(2.0,3.0);System.out.println(立方体体积=+c.volume();System.out.println(球体体积=+s.volume();System.out.println(圆柱体体积=+cy.volume();,编程实践:6.6 设计一个父类建筑物类Building,由它派生出教学楼类Classro

48、om。然后,采用一些数据进行测试。(1)Building类的成员变量有:bname:String型,代表建筑物的名称。floors:int型,代表总层数。area:double型,代表总面积。(2)Building类的构造方法有:public Building():无参数的构造方法。public Building(String b,int f,double a):带参数的构造方法。分别用三个形式参数b、f和a对成员变量bname、floors和area进行初始化。(3)Classroom类的私有成员变量有:rooms:int型,代表教室数 es:int型,代表灭火器数,(4)Classroom

49、类的成员方法有:public Classroom():无参数的构造方法。public Classroom(String b2,int f2,double a2,int rs,int es2):带参数的构造方法。分别用五个形式参数b2、f2、a2、rs和es2对父类或子类的成员变量bname、floors、area、rooms和es进行初始化。void Display():输出bname、floors、area、rooms和es的值。(5)在ClassroomTest类的main()中:创建Classroom类的对象c,利用构造方法对教学楼名称、总层数、总面积、教室数和灭火器数进行初始化。调用D

50、isplay()方法,输出教学楼名称、总层数、总面积、教室数和灭火器数。,class Building protected String bname;protected int floors;protected double area;public Building()public Building(String b,int f,double a)bname=b;floors=f;area=a;,class Classroom extends Buildingprivate int rooms,es;public Classroom()public Classroom(String b2,in

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号