《面向对象程序设计高级篇.pptx》由会员分享,可在线阅读,更多相关《面向对象程序设计高级篇.pptx(86页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、会计学1面向对象程序设计高级篇面向对象程序设计高级篇目目 录录4.1 4.1 继承和多态性的概念继承和多态性的概念4.2 4.2 继承机制继承机制4.3 4.3 多态性多态性4.4 4.4 抽象类抽象类4.5 4.5 包与接口包与接口4.6 4.6 内部类内部类4.7 4.7 匿名类匿名类第1页/共86页4.14.1继承和多态性的概念继承和多态性的概念 4.1.1 4.1.1 继承的概述继承的概述继承,就是新的类从已有类那里得到已有的特性。已有的类称为基类或父类,继承,就是新的类从已有类那里得到已有的特性。已有的类称为基类或父类,产生的新类称为派生类或子类。派生类同样也可以作为基类再派生新的产
2、生的新类称为派生类或子类。派生类同样也可以作为基类再派生新的类,这样就形成了类的层次结构。类,这样就形成了类的层次结构。类间的继承关系是软件复用的一种形式。子类类间的继承关系是软件复用的一种形式。子类(派生类派生类)可以沿用父类(基类)可以沿用父类(基类)的某些特征,并根据自己的需要对性能加以修改,添加新的属性和操作。的某些特征,并根据自己的需要对性能加以修改,添加新的属性和操作。第2页/共86页由于巴士、卡车和出租车作为交通工具,特将它们的共同特性抽取出来,形成一个父类(也称超类),代表一般化属性,而巴士、卡车和出租车转化为子类,继承父类的一般特性包括父类的数据成员和行为如外观颜色和刹车等特
3、性,有产生自己独特的属性和行为如巴士的最大载客数和报站,区别于父类的特性。第3页/共86页 继承的方式包括单一继承和多重继承。单一继承(继承的方式包括单一继承和多重继承。单一继承(single single inheritanceinheritance)是最简单的方式:一个派生类只从一个基类派生。)是最简单的方式:一个派生类只从一个基类派生。多重继承(多重继承(multiple inheritancemultiple inheritance)是一个派生类有两个或多个基类。)是一个派生类有两个或多个基类。这两种继承方式如图这两种继承方式如图4.14.1所示。请注意图中箭头的方向,本书约所示。请注
4、意图中箭头的方向,本书约定,箭头表示继承的方向,由子类指向父类。定,箭头表示继承的方向,由子类指向父类。第4页/共86页 4.1.2 4.1.2 多态性的概述多态性的概述多态性(多态性(PolymorphismPolymorphism)是面向对象程序设计的重要特性之一,它与封装性和继承性)是面向对象程序设计的重要特性之一,它与封装性和继承性一起构成了面向对象程序设计的三大特性。一起构成了面向对象程序设计的三大特性。多态性主要体现在:向不同的对象发送同一个消息,不同的对象在接收时会产生不多态性主要体现在:向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为同的行为(即方法即方法)。也就
5、是说,每个对象可以用自己的方式去响应共同的消息。也就是说,每个对象可以用自己的方式去响应共同的消息。在在JavaJava语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(也称动态联编)。和方法重写实现的动态多态性(也称动态联编)。(1 1)编译时多态)编译时多态在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。用相应的方法。(2 2)动态联编)动态联编程序中凡是使用父类对
6、象的地方,都可以用子类对象来代替。在程序运行期间可以程序中凡是使用父类对象的地方,都可以用子类对象来代替。在程序运行期间可以通过引用子类的实例来调用子类的方法。通过引用子类的实例来调用子类的方法。第5页/共86页4.2 继承机制4.2.1继承的定义 编程中遇到下面的情况:定义教师类。public class DotNetTeacher/教师分为.Net教师 private String name;/教师姓名 private String school;/所在学校 public DotNetTeacher(String myName,String mySchool)name=myName;sch
7、ool=mySchool;public void giveLession()System.out.println(启动VS2010);System.out.println(知识点讲解);System.out.println(总结提问);public void introduction()System.out.println(大家好!我是 +school+的+name+.);第6页/共86页定义教师类。public class JavaTeacher/教师分为Java教师 private String name;/教师姓名 private String school;/所在学校 public J
8、avaTeacher(String myName,String mySchool)name=myName;school=mySchool;public void giveLession()/授课方法的具体实现 System.out.println(启动 MyEclipse);System.out.println(知识点讲解);System.out.println(总结提问);public void introduction()/自我介绍方法的具体实现 System.out.println(大家好!我是 +school+的+name+.);第7页/共86页在程序处理中,发现两个类的定义非常相似,
9、有很多相同点,如教师的属性姓名、所属部门类似,类的方法也基本相同。针对这种情况,将java教师类和.net教师类的共性抽取出来,形成父类Teacher类,使得.net教师和java教师成为Teacher类的子类,则子类继承父类的基本属性和方法,就简化了子类的定义。上述代码修改如下:父类Teacher:public class Teacher private String name;/教师姓名 private String school;/所在学校 public Teacher(String myName,String mySchool)name=myName;school=mySchool;p
10、ublic void giveLesson()/授课方法的具体实现 System.out.println(知识点讲解);System.out.println(总结提问);public void introduction()/自我介绍方法的具体实现 System.out.println(大家好!我是“+school+的+name+。);第8页/共86页子类JavaTeacher:public class JavaTeacher extends Teacher public JavaTeacher(String myName,String mySchool)super(myName,mySchoo
11、l);public void giveLesson()System.out.println(启动 MyEclipse);super.giveLesson();子类NetTeacher:public class DotNetTeacher extends Teacher public DotNetTeacher(String myName,String mySchool)super(myName,mySchool);public void giveLesson()System.out.println(启动 VS2010);super.giveLesson();第9页/共86页子类自动继承父类的属
12、性和方法,子类中不再存在重复代码,从而实现代码的重用。完整的代码如下:【例4-1】自定义父类Teacher,创建其两个子类JavaTeacher和DotNetTeacher。/*本程序的功能是定义一个教师类Teacher,并声明该类的两个子类,并进行调试。*/文件名:test_teacher.java第10页/共86页4.2.2继承的传递性类的继承是可以传递的。类b继承了类A,类c有继承了类b,这是c包涵a和b的所有成员,以及c自身的成员,这称为类继承的传递性。类的传递性对java语言有重要的意义。下面的代码体现这一点。public class Vehicle void vehicleRun(
13、)System.out.println(汽车在行驶!);第11页/共86页public class Truck extends Vehicle /直接父类为Vehicle void truckRun()System.out.println(卡车在行驶!);public class SmallTruck extends Truck/直接父类为Truck protected void smallTruckRun()Console.WriteLine(微型卡车在行驶!);pbulic static void main(String args)SmallTruck smalltruck=new Sma
14、llTruck();smalltruck.vehicleRun();/祖父类的方法调用 smalltruck.truckRun();/直接父类的方法调用 smalltruck.smallTruckRun();/子类自身的方法调用 第12页/共86页4.2.3 类中属性的继承与隐藏1.属性的继承子类可以继承父类的所有非私有属性。见下面代码:public class Person public String name;public int age;public void showInfo()System.out.println(“尊敬的”+name+”,您的年龄为:”+age);public cl
15、ass Student extends Person public string school;public int engScore;public int javaScore;public void setInfo()name=“陈冠一”;/基类的数据成员 age=20;/基类的数据成员 school=“郑州轻工业学院”;第13页/共86页2.属性的隐藏 子类也可以隐藏继承的成员变量,对于子类可以从父类继承的成员变量,只要子类中定义的成员变量和父类中的成员变量同名时,子类就隐藏了继承的成员变量。当子类执行它自己定义的方法时,所操作的就是它自己定义的数据成员,从而覆盖父类继承来的数据成员。子类
16、通过成员变量的隐藏可以把父类的状态变为自身的状态。第14页/共86页4.2.4 类中方法的继承、覆盖与重载1.方法的继承父类中非私有方法都可以被子类所继承。下面的程序实现这点,详见程序中的注释。class Person/基类 private String name;private int age;public void initInfo(String n,int a)name=n;age=a;public void showInfo()System.out.println(尊敬的+name+,您的年龄为:+age);第15页/共86页public class SubStudent extend
17、s Person/子类 private String school;private int engScore;private int javaScore;public void setScores(String s,int e,int j)school=s;engScore=e;javaScore=j;public static void main(String args)SubStudent objStudent=new SubStudent();objStudent.initInfo(王烁,22);/来自父类继承的方法 objStudent.showInfo();/来自父类继承的方法 ob
18、jStudent.setScores(情话大学,79,92);第16页/共86页1.在子类继承父类的成员方法时,应注意:子类不能访问父类的private(私有)成员方法,但子类可以访问父类的public(公有)、protected(保护)成员方法。protected访问时,子类和同一包内的方法都能访问父类的protected成员方法,但其他方法不能访问。2.方法的覆盖子类通过方法的覆盖可以隐藏继承的方法,方法覆盖是指:子类中定义一个方法,并且这个方法的名字、返回类型、参数列表与从父类继承的方法完全相同。【例4-2】自定义父类Person,创建其子类SubStudent。/*本程序的功能是定义一
19、个Person类和它的子类SubStudent,测试父子类具有同名方法时子类的方法覆盖父类的同名方法*/文件名:SubStudent.java 第17页/共86页3.3.方法的重载方法的重载与方法的覆盖(与方法的覆盖(overridingoverriding)不同,方法的重载)不同,方法的重载(overloading)(overloading)不是父子类之间的同名方法的调用,而不是父子类之间的同名方法的调用,而是在一个类中允许同名的方法存在,是类对自身同名方法的重新定义。是在一个类中允许同名的方法存在,是类对自身同名方法的重新定义。如如javajava系统提供的输出命令的同名方法的使用如下:系
20、统提供的输出命令的同名方法的使用如下:System.out.printlnSystem.out.println();();/输出一个空行输出一个空行System.out.printlnSystem.out.println(double salarydouble salary););/输出一个双精度类型的变量后换行输出一个双精度类型的变量后换行System.out.printlnSystem.out.println(String nameString name););/输出一个字符串对象的值后换行输出一个字符串对象的值后换行由于重载发生在同一个类里,不能再用类名来区分不同的方法了,所以一般采用不
21、同的形式参数列由于重载发生在同一个类里,不能再用类名来区分不同的方法了,所以一般采用不同的形式参数列表,包括形式参数的个数、类型、顺序的不同,来区分重载的方法。只需简单地调用表,包括形式参数的个数、类型、顺序的不同,来区分重载的方法。只需简单地调用printprint方法并把一个参方法并把一个参数传递给数传递给printprint,由系统根据这个参数的类型来判断应该调用哪一个,由系统根据这个参数的类型来判断应该调用哪一个printprint方法。方法。方法重载有不同的表现形式,如基于不同类型参数的重载:方法重载有不同的表现形式,如基于不同类型参数的重载:class Addclass Add p
22、ublic String Sum(String para1,String para2)public String Sum(String para1,String para2)public int Sum(int para1,int para2)public int Sum(int para1,int para2)第18页/共86页如相同类型不同参数个数的重载:如相同类型不同参数个数的重载:class Addclass Add public int Sum(int para1,int para2)public int Sum(int para1,int para2)public int Sum(
23、int para1,int para2,int para3)public int Sum(int para1,int para2,int para3)【例例4-34-3】自定义父类自定义父类AreaArea,创建其携带不同参数及返回类型的同名方法。,创建其携带不同参数及返回类型的同名方法。/*/*本程序的功能是定义一个本程序的功能是定义一个AreaArea类和它的同名方法,测试类中同名方法的重载类和它的同名方法,测试类中同名方法的重载*/文件名:TestArea.java 第19页/共86页4.4.构造方法的重载构造方法的重载构造方法也可以重载,它是指同一个类中存在着若干个具有不同参数列表的构
24、造方法。如构造方法也可以重载,它是指同一个类中存在着若干个具有不同参数列表的构造方法。如EmployeeEmployee类中构造方法的重载。类中构造方法的重载。class Employee /class Employee /定义父类定义父类:员工类员工类 /忽略类中属性,值保留重载的构造方法忽略类中属性,值保留重载的构造方法 Employee()/Employee()/无参的构造方法,仅仅初始化员工的编号无参的构造方法,仅仅初始化员工的编号 employeeNo=employeeNextNo+;employeeNo=employeeNextNo+;Employee(String name)Em
25、ployee(String name)/有一个参数的构造方法,仅仅初始化员工的编号和姓名有一个参数的构造方法,仅仅初始化员工的编号和姓名 employeeNo=employeeNextNo+;employeeNo=employeeNextNo+;employeeName=name;employeeName=name;Employee(String name,double initSalary)Employee(String name,double initSalary)/有两个参数的构造方法,仅仅初始化员工的编号、姓名和工资有两个参数的构造方法,仅仅初始化员工的编号、姓名和工资 employe
26、eNo=employeeNextNo+;employeeNo=employeeNextNo+;employeeName=name;employeeName=name;employeeSalary=initSalary;employeeSalary=initSalary;第20页/共86页4.2.54.2.5在子类中使用构造方法在子类中使用构造方法子类不能继承父类的构造方法。子类不能继承父类的构造方法。子类在创建新对象时,依次向上寻找其基类,直到找到最初的基类,然后开始执行最子类在创建新对象时,依次向上寻找其基类,直到找到最初的基类,然后开始执行最初的基类的构造方法,再依次向下执行派生类的构造方
27、法,直至执行完最终的扩充类的构造初的基类的构造方法,再依次向下执行派生类的构造方法,直至执行完最终的扩充类的构造方法为止。方法为止。注:对于无参数的构造方法,执行不会出现问题。如果是带参数的构造方法,还需要注:对于无参数的构造方法,执行不会出现问题。如果是带参数的构造方法,还需要做相应的处理。做相应的处理。如果基类中没有默认构造方法或者希望调用带参数的基类构造方法,就要使用关键字如果基类中没有默认构造方法或者希望调用带参数的基类构造方法,就要使用关键字supersuper来显式调用基类构造方法。来显式调用基类构造方法。使用关键字使用关键字supersuper调用基类构造方法的语句,必须是子类构
28、造方法的第一个可执行语句。调用基类构造方法的语句,必须是子类构造方法的第一个可执行语句。调用基类构造方法时传递的参数不能是关键字调用基类构造方法时传递的参数不能是关键字thisthis或当前对象的非静态成员。或当前对象的非静态成员。第21页/共86页【例例4-44-4】子类中使用构造方法的实例。子类中使用构造方法的实例。/*/*程序功能描述:在程序中声明了父类程序功能描述:在程序中声明了父类EmployeeEmployee和子类和子类CommonEmployee CommonEmployee,子类继承了父类的非私有的属性和方法,但父子类计算各自的工资的方法不同,如子类继承了父类的非私有的属性和
29、方法,但父子类计算各自的工资的方法不同,如父类对象直接获取工资,而子类在底薪的基础上增加奖金数为工资总额,通过子类父类对象直接获取工资,而子类在底薪的基础上增加奖金数为工资总额,通过子类的构造方法中的构造方法中supersuper的调用类初始化父类的对象,并调用继承父类的方法的调用类初始化父类的对象,并调用继承父类的方法toStringtoString()()输出员工的基本信息。输出员工的基本信息。*/文件名:test_constructor.java第22页/共86页4.3.1 4.3.1 多态性的体现多态性的体现在在javajava语言中,多态性体现在两个方面:由方法重载实现的静态多态性(
30、编译时多态)语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法覆盖实现的动态多态性(运行时多态)。和方法覆盖实现的动态多态性(运行时多态)。静态多态性是在编译的过程中确定同名操作的具体操作对象的,而动态多态性则是在静态多态性是在编译的过程中确定同名操作的具体操作对象的,而动态多态性则是在程序运行过程中动态地确定操作所针对的具体对象的。这种确定操作具体对象的过程就是联程序运行过程中动态地确定操作所针对的具体对象的。这种确定操作具体对象的过程就是联编编(binding)(binding),也称为动态绑定。,也称为动态绑定。4.3 多态性第23页/共86页4.3.2 4.3
31、.2 静态多态性静态多态性静态多态性是在编译的过程中确定同名操作的具体操作对象的。下面的代码体现了编译时的多态性。静态多态性是在编译的过程中确定同名操作的具体操作对象的。下面的代码体现了编译时的多态性。public class Personpublic class Person private String name;private String name;private int age;private int age;public void initInfo(String n,int a)/public void initInfo(String n,int a)/同名方法同名方法 name=
32、n;name=n;age=a;age=a;public void initInfo(String n)/public void initInfo(String n)/同名方法同名方法 name=n;name=n;public void showInfo()public void showInfo()System.out.println(“System.out.println(“尊敬的尊敬的”+name+”,+name+”,您的年龄为您的年龄为:”+age);:”+age);第24页/共86页4.3.34.3.3动态多态性动态多态性 和静态联编相对应,如果联编工作在程序运行阶段完成,则称为动态和
33、静态联编相对应,如果联编工作在程序运行阶段完成,则称为动态联编。在编译、连接过程中无法解决的联编问题,要等到程序开始运行之联编。在编译、连接过程中无法解决的联编问题,要等到程序开始运行之后再来确定。后再来确定。如果父类的引用指向一个子类对象时,当调用一个方法完成某个功能如果父类的引用指向一个子类对象时,当调用一个方法完成某个功能时,程序会动态地(在执行时)选择正确的子类的同样方法去实现该功能,时,程序会动态地(在执行时)选择正确的子类的同样方法去实现该功能,就称为动态方法绑定。就称为动态方法绑定。第25页/共86页下面动态方法调用的简单例子。下面动态方法调用的简单例子。class Parent
34、class Parent public void function()public void function()System.out.println(I am in Parent!);System.out.println(I am in Parent!);class Child extends Parent class Child extends Parent public void function()public void function()System.out.println(I am in Child!);System.out.println(I am in Child!);pub
35、lic class test_parent public class test_parent public static void main(String args)public static void main(String args)Parent p1=new Parent();Parent p1=new Parent();Parent p2=new Child();Parent p2=new Child();p1.function();p1.function();p2.function();p2.function();程序的输出结果为:程序的输出结果为:I am in Parent!I
36、am in Parent!I am in Child!I am in Child!第26页/共86页 4.3.4 4.3.4父类对象与子类对象间的指代使用和转化父类对象与子类对象间的指代使用和转化thisthis和和supersuper关键字是常用来指代父类对象与子类关键字是常用来指代父类对象与子类 对象的关键字。对象的关键字。1.this1.this关键字关键字thisthis表表示示的的是是当当前前对对象象本本身身,更更准准确确地地说说,thisthis代代表表了了当当前前对对象象的的一一个个引引用用。对对象象的的引引用用可可以以理理解解为为对对象象的的另另一一个个名名字字,通通过过引引用
37、用可可以以顺顺利利地访问对象,包括修改对象的属性、调用对象的方法。地访问对象,包括修改对象的属性、调用对象的方法。2.super2.super关键字关键字 supersuper表表示示的的是是当当前前对对象象的的直直接接父父类类对对象象,是是当当前前对对象象的的直直接接父父类类对对象的引用。所谓直接父类是相对于当前对象的其他象的引用。所谓直接父类是相对于当前对象的其他“祖先祖先”而言的。而言的。第27页/共86页 通过通过supersuper关键字访问父类中被隐藏的成员变量关键字访问父类中被隐藏的成员变量 class Father class Father int x=0;int x=0;cl
38、ass Child extends Father class Child extends Father int x=1;int x=1;public Child()public Child()System.out.println(super.x);System.out.println(super.x);public static void main(String args)public static void main(String args)new Child();/super.x=0 new Child();/super.x=0 子类的构造方法中,通过子类的构造方法中,通过supersup
39、er关键字调用父类的构造方法关键字调用父类的构造方法 public class Student extends Person public class Student extends Person public Student(String myName,int myAge)public Student(String myName,int myAge)super(myName,myAge);/super(myName,myAge);/调用父类的构造方法,完成对属性值的初始化调用父类的构造方法,完成对属性值的初始化 第28页/共86页 方法覆盖后,通过方法覆盖后,通过supersuper关键字调
40、用父类的方法关键字调用父类的方法 public class Student extends Person public class Student extends Person public void showInfo()public void showInfo()super.showInfo();super.showInfo();System.out.println(,System.out.println(,你的英语成绩是:你的英语成绩是:+engScore+,JAVA+engScore+,JAVA成绩是:成绩是:+javaScore);+javaScore);3.3.父类对象与子类对象的转
41、化父类对象与子类对象的转化 假假设设B B类类是是A A类类子子类类或或间间接接子子类类,当当我我们们用用子子类类B B创创建建一一个个对对象象,并并把把这这个个对对象象的的引引用用赋赋给给A A类类的的对对象象:A a;A a;B b=new B();B b=new B();a=b;a=b;称这个称这个A A类对象:类对象:a a是子类对象是子类对象b b的上转型对象的上转型对象.子类对象可以赋给父类对象,但指向子类的父类对象子类对象可以赋给父类对象,但指向子类的父类对象第29页/共86页不能操作子类新增的成员变量,不能使用子类新增的方法。不能操作子类新增的成员变量,不能使用子类新增的方法。
42、上转型对象可以操作子类继承或隐藏成员变量,也可以使用子类继承的或重写的方法。上转型对象可以操作子类继承或隐藏成员变量,也可以使用子类继承的或重写的方法。可可以以将将对对象象的的上上转转型型对对象象再再强强制制转转换换到到一一个个子子类类对对象象,该该子子类类对对象象又又具具备备了了子子类类所所有有属属性性和和功功能。能。如如果果子子类类重重写写了了父父类类的的方方法法,那那么么重重写写方方法法的的调调用用原原则则如如下下:JavaJava运运行行时时系系统统根根据据调调用用该该方方法法的的实例,来决定调用哪个方法。实例,来决定调用哪个方法。对对子子类类的的一一个个实实例例,如如果果子子类类重重
43、写写了了父父类类的的方方法法,则则运运行行时时系系统统调调用用子子类类的的方方法法;如如果果子子类类继继承了父类的方法(未重写),则运行时系统调用父类的方法。承了父类的方法(未重写),则运行时系统调用父类的方法。总之,父类对象和子类对象的转化需要注意如下原则:总之,父类对象和子类对象的转化需要注意如下原则:子类对象可以被视为是其父类的一个对象。子类对象可以被视为是其父类的一个对象。父类对象不能被当作是其某一个子类的对象。父类对象不能被当作是其某一个子类的对象。如果一个方法的形式参数定义的是父类对象,那么调用这个方法时,可以使用子类对象作为如果一个方法的形式参数定义的是父类对象,那么调用这个方法
44、时,可以使用子类对象作为实际参数。实际参数。第30页/共86页JavaJava语言中,用语言中,用abstractabstract关键字来修饰一个类时,这个类叫做抽象类。抽象类关键字来修饰一个类时,这个类叫做抽象类。抽象类只关心它的子类是否具有某种功能只关心它的子类是否具有某种功能,并不关心该功能的具体实现并不关心该功能的具体实现,功能的具体行为由功能的具体行为由子类负责实现的。一个抽象类中可以有一个或多个抽象方法。子类负责实现的。一个抽象类中可以有一个或多个抽象方法。4.4.1 4.4.1 抽象类的定义抽象类的定义 抽象类的一般格式:抽象类的一般格式:abstract class Class
45、Name abstract class ClassName /类实现类实现 如如abstract class ClassOne abstract class ClassOne /类实现类实现 4.4 抽象类第31页/共86页一旦一旦ClassOneClassOne类声明为抽象类,则它不能被实例化,只能用作派生类的基类而存类声明为抽象类,则它不能被实例化,只能用作派生类的基类而存在。下面的语句会产生编译错误:在。下面的语句会产生编译错误:ClassOne a=new ClassOne()ClassOne a=new ClassOne();抽象方法的一般格式:抽象方法的一般格式:abstract
46、abstract 返回值类型返回值类型 抽象方法抽象方法(参数列表参数列表 ););如语句如语句public abstract void Method();public abstract void Method();抽象方法的一个主要目的就是为所有子类定义一个统一的接口,抽象方法必须被抽象方法的一个主要目的就是为所有子类定义一个统一的接口,抽象方法必须被重写。重写。抽象类必须被继承,抽象方法必须被重写。抽象方法只需声明,无需实现;抽象抽象类必须被继承,抽象方法必须被重写。抽象方法只需声明,无需实现;抽象类不能被实例化,抽象类不一定要包含抽象方法。若类中包含了抽象方法,则该类必须类不能被实例化,
47、抽象类不一定要包含抽象方法。若类中包含了抽象方法,则该类必须被定义为抽象类。被定义为抽象类。第32页/共86页抽象类有以下的定义规则:抽象类有以下的定义规则:抽象类必须用抽象类必须用abstractabstract关键字来修饰;抽象方法也必须用关键字来修饰;抽象方法也必须用abstractabstract来来修饰。修饰。抽象类不能被实例化,也就是不能用抽象类不能被实例化,也就是不能用newnew关键字去产生对象。关键字去产生对象。抽象方法只需声明,而不需实现。抽象方法只需声明,而不需实现。含有抽象方法的类必须被声明为抽象类,抽象类的子类必须覆盖含有抽象方法的类必须被声明为抽象类,抽象类的子类必
48、须覆盖所有的抽象方法后才能被实例化,否则这个子类还是个抽象类。所有的抽象方法后才能被实例化,否则这个子类还是个抽象类。第33页/共86页具体实现可参考下面两段的代码。具体实现可参考下面两段的代码。(1 1)抽象类的基本实现方法)抽象类的基本实现方法 abstract class Baseabstract class Base int basevar;/int basevar;/成员变量成员变量 public abstract void M1();/public abstract void M1();/抽象的成员函数,只有声明,没有集体的实现,、抽象的成员函数,只有声明,没有集体的实现,、/必必
49、须在该类的子类实现方法须在该类的子类实现方法 .class Derived extends Baseclass Derived extends Base int derivedvars;/int derivedvars;/成员变量成员变量 public void M1()/public void M1()/子类必须重写父类的抽象成员函数子类必须重写父类的抽象成员函数M1M1 /实际实现的语句体实际实现的语句体.第34页/共86页(2 2)继承于抽象类的类一般应该实现抽象类中的所有抽象方法(重写)。如果没有,)继承于抽象类的类一般应该实现抽象类中的所有抽象方法(重写)。如果没有,那么该派生类也应
50、该声明为抽象类。那么该派生类也应该声明为抽象类。abstract class A abstract class Apublic abstract void MethodA();public abstract void MethodA();class B extends A class B extends A /错误,子类错误,子类B B没有实现对象父类没有实现对象父类A A中抽象方法中抽象方法MethodAMethodA /的重写,一次的重写,一次B B类应声明为抽象类应声明为抽象类类 public void MethodB()public void MethodB()class C exte