单元6 面向对象高级_第1页
单元6 面向对象高级_第2页
单元6 面向对象高级_第3页
单元6 面向对象高级_第4页
单元6 面向对象高级_第5页
已阅读5页,还剩122页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单元6面向对象高级类的继承抽象类接口对象类型转换

多态内部类Java语言提供了类的继承、接口和多态三大特性,本单元重点介绍类的继承、方法的重写、Object类、super关键字、final关键字、抽象类、接口、多态和内部类。单元6面向对象高级教学目标知识目标:技能目标:素养目标:掌握类的继承、抽象类和接口的使用理解方法的重写、Object类和内部类熟悉super关键字和final关键字的使用能够恰当运用类的继承和接口能够正确运用super关键字和final关键字能够独立完成拓展任务懂得知识是源泉,智慧是力量明白继承是财富,创新是开展6.1知识储备–类的继承继承的概念继承的关键字继承关系注意事项继承(inherit)是面向对象重要特性之一,Java中的继承与现实生活中的继承相似,现实生活中子女可以继承父母的财富,可以自己创造财富,同样,Java中的子类继承父类中可继承的属性和方法,子类可添加父类中没有的属性和方法,也可以重写父类中的某些方法,扩展或者强化子类所继承的各项功能。在程序中恰当地使用继承可以大大提高编程效率,减少代码的冗余。在Java中,使用extends关键字声明一个类继承另外一个类,基本语法格式如下:class父类名{……}class子类名extends父类名{……}6.1.1类的继承在Java类的继承中,需要注意如下几点:(1)父类也称为超类、基类和派生类。(2)在Java中的类,只有单继承,没有多继承,即一个子类只能有一个父类,一个父类可以有多个子类。(3)支持多层次继承,即一个类可以是某个类的子类,也可以是某个类的父类。例如:类A继承类B,类B继承类C。(4)子类继承父类,可以继承除构造方法外的全部属性和方法,但不能直接访问父类的私有属性和方法。6.1.1类的继承【例6-1】创建一个人类(Person),有姓名(name)和年龄(age)两个属性,有吃饭(eat)和睡觉(sleep)两个方法;再创建一个学生类(Student),继承人类,同时添加一学习(Student)方法,通过实例化学生类对象,设置其属性并调用相应的方法。操作步骤:(1)新建unit06工程,在工程unit06的src目录下创建包.cvit.example01,在包.cvit.example01下创建类Example01。(2)在example01.java文件中,创建Person类和Student类。(3)编写Example01测试类。(4)文本编辑器视图中,撰写代码如下:6.1.1类的继承Person类代码如下:package.cvit.example01;classPerson{

//定义name和age成员变量

privateStringname;

//姓名

privateintage;

//年龄6.1.1类的继承publicStringgetName(){

//私有化成员变量的公有化getterandsetter方法

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publicintgetAge(){

returnage;

}

publicvoidsetAge(intage){

this.age=age;

}6.1.1类的继承publicstaticvoideat(){

//定义eat方法

System.out.println("吃东西!!!");

}

publicstaticvoidsleep(){

//定义sleep方法

System.out.println("睡觉!!!");

}

}6.1.1类的继承继承Person类的Student类代码如下:classStudentextendsPerson{

Student(Stringname,intage){

//创建有参构造方法

this.getName();

this.getAge();

}

publicstaticvoidsleep(){

//重写父类中的sleep方法

System.out.println("正在午睡!!!");

}

publicstaticvoidstudy(){

//创建Student类中特有的study方法

System.out.println("学习Java!!!");

}

}6.1.1类的继承测试类代码如下:publicclassExample01{

publicstaticvoidmain(String[]args){

Studentstu1=newStudent("Tony",19);

//实例化一个stu1对象

//调用Student类中的各个方法

stu1.eat();

stu1.sleep();

stu1.study();

}

}6.1.1类的继承继承(inherit)是面向对象重要特性之一,Java中的继承与现实生活中的继承相似,现实生活中子女可以继承父母的财富,可以自己创造财富,同样,Java中的子类继承父类中可继承的属性和方法,子类可添加父类中没有的属性和方法,也可以重写父类中的某些方法,扩展或者强化子类所继承的各项功能。在程序中恰当地使用继承可以大大提高编程效率,减少代码的冗余。在Java中,使用extends关键字声明一个类继承另外一个类,基本语法格式如下:class父类名{……}class子类名extends父类名{……}6.1.1类的继承运行结果:

6.1.1类的继承提示:Student类中重写了Person类中的sleep方法,添加了study方法。在测试类中,实例化的stu1对象既调用了Person中的属性,又调用eat和sleep方法,但调用的是Student类中的重写的sleep方法,而不是父类中的sleep方法。子类对象不仅可以调用父类的属性方法,同样可调用子类自己的属性方法,当出现同名的属性或者方法时,以子类为主。6.1知识储备–方法的重写方法重写的前提方法重写需要满足的条件方法重写的注意事项在Java中子类可以继承父类中的方法,而不需要重新创建相同的方法,当父类中的方法无法满足子类需求或子类具有特定功能的时候,需要对方法重写。方法的重写(override)又称为方法的覆盖,要求子类中的方法与父类中的方法具有相同的方法名称、返回值类型和参数列表,方法体实现不同。方法的重写需要满足如下条件:(1)方法名称、参数列表相同(2)返回值类型子类小于等于父类(3)访问权限子类大于等于父类6.1.2方法的重写在例6-1中,Student类重写了Person类的sleep方法,子类对象调用sleep方法时,执行的是子类中的方法。方法的重写需要注意如下几点:(1)父类的成员方法只能被它的子类重写。(2)父类中声明为final的方法不能被重写。(3)父类中声明为static的方法不能被重写,但是能够再次声明。(4)构造方法不能被重写。6.1.2方法的重写6.1知识储备–Object类

Object类的特点equals方法toString方法Object类Object类是Java.lang包下的核心类,Object类是所有类的父类,所有类都默认继承了Object类。Object类提供了一些通用方法,可以在任何Java对象中使用。下面分别介绍Object类中常用的方法equals()和toString()。1. equals()方法equals()方法用于比较两个对象的内容是否相同,返回值类型为boolean,它不同于“==”运算符,“==”运算符用于比较两个对象的引用是否相同。6.1.3Object类【例6-2】比较两个字符串是否相同。操作步骤:(1)在包.cvit下创建包example02,在包.cvit.example02下创建类Example02。(2)在example02.java文件中,定义main方法。(3)文本编辑器视图中,撰写代码如下:6.1.3Object类package.cvit.example02;

/**

*分别比较两个字符串的内容和引用

*/

publicclassExample02{

publicstaticvoidmain(String[]args){

//分别定义4个字符串

Stringstr1=newString("tony");

Stringstr2=newString("tony");

Stringstr3="Alice";

Stringstr4;

str4=str1;

6.1.3Object类

//分别使用equals()方法和==比较运算符对字符串进行比较

booleanb1=str1.equals(str2);

booleanb2=(str1==str2);

booleanb3=str1.equals(str3);

booleanb4=(str1==str4);

//输出比较结果

System.out.println("str1与str2的内容是否相同:"+b1);

System.out.println("str1与str2是否为相同引用:"+b2);

System.out.println("str1与str3的内容是否相同:"+b3);

System.out.println("str1与str4是否为相同引用:"+b4);

}

}

6.1.3Object类运行结果:

6.1.3Object类提示:当两个对象同时指向同一引用时,使用“==”比较后,结果为true,说明两个对象完全相同。使用equals()方法比较的是两个对象存储的内容是否相同,如果相同,结果为true,它不关心是否是同一个对象。如果只需要判断两个对象内容是否相同使用equals()方法比较恰当。2.toString()方法toString()方法返回对象的字符串表示形式。toString()方法原型如下:publicStringtoString(){returngetClass().getName()+"@"+Integer.toHexString((hashCode()));}从toString()原型不难发现,其默认返回的字符串为“类名@十六进制的HashCode”,因为所有类均继承Object类,因此,在调用toString()方法,将输出默认字符串。若想输出其它内容需要重写toString()方法。6.1.3Object类【例6-3】重写toString()方法,输出需要的内容。操作步骤:(1)在包.cvit下创建包example03,在包.cvit.example03下创建类Example03。(2)在example03.java文件中,创建Student类。(3)文本编辑器视图中,撰写代码如下:6.1.3Object类package.cvit.example03;

/**

*重写toString()方法

*/

//创建Student类

classStudent{

//定义成员变量name和age并封装

privateStringname;

privateintage;

6.1.3Object类

//定义public修饰的getter和setter方法

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publicintgetAge(){

returnage;

}

publicvoidsetAge(intage){

this.age=age;

}

6.1.3Object类//定义有参构造方法

Student(Stringname,intage){

this.name=name;

this.age=age;

}

//重写toString()方法

publicStringtoString(){

return"姓名:"+name+"年龄:"+age;

}

}

//编写测试类

publicclassExample03{

publicstaticvoidmain(String[]args){

Studentstu=newStudent("张三",18);

//实例化Student对象stu

System.out.println(stu);

//输出stu的toString()的返回值

Example03example03=newExample03();

//实例化Example03类对象example03

System.out.println(example03);

//输出的example03toString()的返回值

}

}

6.1.3Object类运行结果:

6.1.3Object类提示:Student类中重写了toString方法,因此在输出对象时,直接输出了自定义后的内容,而Example03类中没有重写toString方法,输出的是全类名+@+Hashcode的值。在类的使用中,经常需要重写toString()方法。6.1知识储备–super关键字访问父类中的属性访问父类中的方法访问父类中的构造方法super关键字指向当前对象的父类,super关键字可以出现在实例方法和构造方法中,子类对象可以通过super关键字访问父类中已被覆盖的属性和方法。1. 访问父类中的属性和方法一般格式:super.属性名;或者,super.方法名([实参列表]);使用super关键字访问父类中的属性和方法时,没有位置限制,可放在子类中任意可调用的地方。6.1.4Super关键字【例6-4】使用super关键字访问父类中的属性和方法。操作步骤:(1)在包.cvit下创建包example04,在包.cvit.example04下创建类Example04。(2)在example04.java文件中,创建Person类和Student类,Student类继承Person类。(3)文本编辑器视图中,撰写代码如下:6.1.4Super关键字fpackage.cvit.example04;

/**

*使用super关键字访问父类中的属性和方法

*/

//创建Person类

classPerson{

//定义name和age成员变量

privateStringname="张三";

privateintage=10;

6.1.4Super关键字//定义getter和setter方法

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publicintgetAge(){

returnage;

}

publicvoidsetAge(intage){

this.age=age;

}

//定义eat方法

publicvoideat(){

System.out.println("在吃零食!!!");

}

}

//创建Student类,并继承Person类

classStudentextendsPerson{

//定义与父类同名的成员变量

Stringname="李四";

intage=15;

//重写父类中的eat方法

publicvoideat(){

//使用super调用父类中的方法

System.out.print(age+"岁的"+super.getName());

super.eat();

}

}

6.1.4Super关键字//编写测试类

publicclassExample04{

publicstaticvoidmain(String[]args){

Studentstu=newStudent();//实例化Student类对象

stu.eat();//调用Student类中eat方法

}

}

运行结果:

提示:在Student类的eat()方法中使用super.getName()调用父类中的name属性值,使用super.eat()方法调用父类中的eat()方法。没有使用super关键字获取的age属性值为子类中的初始值15,而不是父类中的10。在static修饰的方法中不能使用super关键字。6.1.4Super关键字2. 访问父类中的构造方法子类不可以重写父类的构造方法,但通过super关键字可以调用父类的构造方法。一般格式:super([实参列表]);super关键字调用父类构造方法需要注意如下几点:(1)super关键字必须放在子类构造方法体的首行。(2)super关键字不可以在多个构造方法之间进行互相调用。(3)无参构造方法调用时,缺省实参列表。6.1.4Super关键字【例6-5】super关键字调用父类的构造方法。操作步骤:(1)在包.cvit下创建包example05,在包.cvit.example05下创建类Example05。(2)在example05.java文件中,创建Person类和Student类,Student类继承Person类。(3)文本编辑器视图中,撰写代码如下:6.1.4Super关键字package.cvit.example05;

/**

*使用super关键字访问父类中构造方法

*/

//创建Person类

classPerson{

//定义name和age成员变量

privateStringname="张三";

privateintage=10;

//定义getter和setter方法

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publicintgetAge(){

returnage;

}

publicvoidsetAge(intage){

this.age=age;

}

6.1.4Super关键字//定义构造方法

Person(){}

//定义无参构造方法

Person(Stringname,intage){

//定义有参构造方法

this.name=name;

this.age=age;

}

}

6.1.4Super关键字//创建Student类,并继承Person类

classStudentextendsPerson{

privateStringgender;

//定义gender性别成员变量

//定义gender成员变量的getter和setter方法

publicStringgetGender(){

returngender;

}

publicvoidsetGender(Stringgender){

this.gender=gender;

}

6.1.4Super关键字

//定义无参构造方法和有参构造方法

Student(){

super();

//super语句可缺省,默认调用了父类无参构造方法

}

Student(Stringname,intage,Stringgender){

super(name,age);

//调用父类有参构造方法,此语句若缺省,则使用父类中的参数

this.gender=gender;

}

//重写toString()方法

publicStringtoString(){

returnthis.getName()+","+gender+","+this.getAge()+"岁。";

}

}

6.1.4Super关键字d//编写测试类

publicclassExample05{

publicstaticvoidmain(String[]args){

Studentstu=newStudent("张三",19,"男");

//实例化Student类对象stu

System.out.println(stu);

//输出stu对象基本信息

}

}

6.1.4Super关键字运行结果:

提示:子类调用父类的无参构造方法时,可缺省super();语句,系统默认已添加。子类有参构造方法参数值与父类不同数时,可先调用父类有参构造方法,再重新赋值,该语句必须放在方法体首行,放在其它位置将报错。6.1.4Super关键字6.1知识储备–super关键字

super关键字修饰类super关键字修饰成员变量super关键字修饰成员方法在Java中,final关键字可以用来修饰类、成员变量和成员方法。final修饰的类为最终类,不能被任何其它类继承;final修饰类中的成员变量为常量,不能被改变;final修饰类中的方法为最终方法,不能被重写。6.1.5Super关键字【例6-6】final关键字的演示。操作步骤:(1)在包.cvit下创建包example06,在包.cvit.example06下创建类Example06。(2)在example06.java文件中,创建A类、B类和C类,final分别修饰A类、B类中的成员变量和C类中的成员方法。(3)文本编辑器视图中,撰写代码如下:6.1.5Super关键字package.cvit.example06;

/**

*final关键字

*/

//final修饰的类

finalclassA{

publicvoidinfo(){

System.out.println("final修饰的类,不能被继承。");

}

}

6.1.5Super关键字//final修饰的成员变量

classB{

finalStringSCHOOL="中山大学";

publicvoidinfo(){

System.out.println("final修饰的变量是常量,不能被更改。");

}

}

//final修饰的成员方法

classC{

publicfinalvoidinfo(){

System.out.println("final修饰的方法,不能被重写。");

}

}

6.1.5Super关键字//测试类

publicclassExample06{

publicstaticvoidmain(String[]args){

//实例化各类对象,并调用类中的info方法

Aa=newA();

Bb=newB();

Cc=newC();

a.info();

b.info();

c.info();

}

}

6.1.5Super关键字运行结果:

提示:(1)如果创建一个类继承A类,将报错,错误信息为“MakeAnotfinal”,也就是被final修饰的A类不能被继承。(2)如果想修改B类中的SCHOOL,将报错,错误信息为“MakeB.SCHOOLnotfinal”,即被final修饰的成员变量SCHOOL不能被修改。(3)如果创建一个类继承C类,且在子类中重写C类中的info()方法,将报错,错误信息为“MakeC.infonotfinal”,即被final修饰的成员方法info()不能被重写。6.1.5Super关键字提示:如果创建一个类继承A类,将报错,错误信息为“MakeAnotfinal”,也就是被final修饰的A类不能被继承。如果想修改B类中的SCHOOL,将报错,错误信息为“MakeB.SCHOOLnotfinal”,即被final修饰的属性值不能被修改。如果创建一个类继承C类,若在子类中重写C类中的info方法,将报错,错误信息为“MakeC.infonotfinal”,即被final修饰的方法不能被重写。6.1.5Super关键字6.1知识储备–抽象类抽象方法抽象类的使用抽象类的注意事项在一个类中的方法无法确定具体实现方式时,使用抽象方法(Abstractmethod)和抽象类(Abstractclass)。1.抽象方法使用abstract关键字修饰的方法称为抽象方法,抽象方法没有方法体,只有方法声明部分,它是一种“规则”,告知子类必须实现该方法。抽象方法定义的一般格式:权限修饰符abstract返回值类型方法名称([参数]);例如:abstractvoidf();6.1.6抽象类2.抽象类含有一个或者多个抽象方法的类为抽象类,它是一种特殊的类,使用abstract关键字修饰,不能直接实例化对象,只有通过继承才能被使用。一个抽象类可以被多个子类继承,每个子类均需要实现父类中的所有抽象方法,方法的具体实现功能可以不同。抽象类定义一般格式:abstractclass类名{

成员变量

普通方法

抽象方法}6.1.6抽象类3.使用抽象类需要注意如下几点:(1)抽象类和抽象方法必须使用abstract关键字修饰。(2)抽象类中可以一个或者多个抽象方法。(3)抽象方法只有声明,没有实现。(4)抽象方法所在的类必须是抽象类。(5)继承抽象类的子类,需要实现抽象类中的所有抽象方法。6.1.6抽象类3.使用抽象类需要注意如下几点:(1)抽象类和抽象方法必须使用abstract关键字修饰。(2)抽象类中可以一个或者多个抽象方法。(3)抽象方法只有声明,没有实现。(4)抽象方法所在的类必须是抽象类。(5)继承抽象类的子类,需要实现抽象类中的所有抽象方法。6.1.6抽象类6.1.6抽象类【例6-7】抽象类的使用。操作步骤:(1)在包.cvit下创建包example07,在包.cvit.example07下创建类Example07。(2)在example07.java文件中,创建Computer抽象类,在类中创建usb()抽象方法。(3)在example07.java文件中,分别创建MyComputer、HerComputer和HisComputer类实现Computer类,在子类中分别实现usb()方法,具体实现功能各不相同。(4)文本编辑器视图中,撰写代码如下:package.cvit.example07;

/**

*抽象类

*/

//计算机类

abstractclassComputer{

//1.连接显示器--普通方法

publicvoiddisplay(){

System.out.println("连接显示器!!!");

}

//连接USB--抽象方法

publicabstractvoidusb();

}

//MyComputer类,继承Computer类

classMyComputerextendsComputer{

//重写usb方法

@Override

publicvoidusb(){

System.out.println("连接U盘!!!");

}

}

6.1.6抽象类//HerComputer类,继承Computer类

classHerComputerextendsComputer{

//重写usb方法

@Override

publicvoidusb(){

System.out.println("连接鼠标!!!");

}

}

//5.测试类

publicclassExample07{

publicstaticvoidmain(String[]args){

MyComputermyComputer=newMyComputer();

HerComputerherComputer=newHerComputer();

HisComputerhisComputer=newHisComputer();

myComputer.usb();

herComputer.usb();

hisComputer.usb();

}

}

6.1.6抽象类运行结果:

6.1.6抽象类提示:Computer类为抽象类,其中,usb()为抽象方法,MyComputer、HerComputer和HisComputer分别继承了Computer类,需要重写usb()方法。IDEA开发工具中,光标放在子类处,单击图6-8左上角的红色小灯泡,在弹出的下拉菜单中选择“Implementmethods”实现方法命令。6.1.6抽象类或者将光标放在Computer类名处,按下Alt+Enter快捷键,在弹出的下拉菜单中选择“Implementmethods”实现方法,如图6-9所示。

6.1.6抽象类单击“Implementmethods”实现方法命令后,在弹出的窗口中选择usb()方法,单如OK按钮,如图6-10所示。6.1.6抽象类在系统提示下重写的抽象方法上方会添加一行注解@Override,如图6-11所示。6.1.6抽象类6.1知识储备–接口定义接口抽象类与接口的区别实现接口在Java中,如果一个抽象类中所有的方法均为抽象方法,可以将该类定义为接口(interface),接口相当于定义一系列的标准,例如,你想做教师就要会说普通话,你想做律师就要懂法律,你想做厨师就要会炒菜一样。接口与类不同,接口的关键字是interface,类的关键字是class;接口可以多继承,即一个子接口可以继承多个父接口,类只能单继承。接口无法被实例化,但可以被其它类实现。接口中所有的成员变量默认被publicstaticfinal修饰,即为常量。接口中所有的方法默认被publicstaticabstract修饰,接口中所有的方法必须是抽象方法,JDK8之后接口中可以使用default关键字修饰的非抽象方法。6.1.7接口1. 接口定义格式[权限修饰符]interface接口名称[extends其他的接口名]{[publicstaticfinal] 数据类型常量名称=常量值;publicdefault返回值类型方法名([参数列表]){ //方法体}[publicabstract]返回值类型方法名([参数列表]);}6.1.7接口2. 抽象类与接口的区别(1)抽象类中可以有普通方法,接口中不可以,只能有抽象方法和default修饰的方法。(2)抽象类中的成员变量类型不限制,而接口中的成员变量只能是publicstaticfinal类型的常量。(3)抽象类属于类,一个类只能继承一个父类,接口不属于类,一个类可以实现多个接口,同时,一个接口可以继承多个父接口。6.1.7接口6.1.7接口3. 实现接口的一般格式[修饰符]class类名implements接口1,接口2,……,接口n{ ……}6.1.7接口【例6-8】接口的实现。操作步骤:(1)在包.cvit下创建包example08,在包.cvit.example08下创建类Example08。(2)在example08.java文件中,创建Person接口,在Person接口中定义两个常量,分别为学号(NUMBER)和姓名(NAME),定义一个基本信息(info)抽象方法。(3)在example08.java文件中,创建Action接口,在Action接口中定义两个抽象方法,分别为读书(read)和睡觉(sleep)。(4)在example08.java文件中,创建Student类,分别实现Person和Action接口。(5)文本编辑器视图中,撰写代码如下:6.1.7接口6.1.7接口package.cvit.example08;

interfacePerson{

//Person接口

//定义常量NUMBER和NAME,其中的修饰符publicstaticfinal可缺省

publicstaticfinalintNUMBER=22571301;

StringNAME="李明";

//定义抽象方法info(),其中的publicabstract可缺省

publicabstractvoidinfo();

}

interfaceAction{

//Action接口

//定义抽象方法read()和sleep()

voidread();

voidsleep();

}6.1.7接口classStudentimplementsPerson,Action{

//Student类,实现了Person和Action接口

@Override

publicvoidinfo(){

System.out.println("学号"+NUMBER+","+NAME+"。");

}

@Override

publicvoidread(){

System.out.println("在读三国演义!!!");

}

@Override

publicvoidsleep(){

System.out.println("在睡午觉!!!");

}

}

//测试类

publicclassExample08{

publicstaticvoidmain(String[]args){

//实例化Student类对象,并调用所有方法

Studentstu=newStudent();

stu.info();

stu.read();

stu.sleep();

}

}

6.1.7接口运行结果:

提示:Student类分别实现了Person接口和Action接口,实现了两个接口中所有方法。接口中常量前面的publicstaticfinal修饰符可缺省。接口中方法前面的publicabstract修饰符可缺省。6.1.7接口6.1知识储备–对象类型转换对象类型转换的前提向上转型向下转型对象类型转换与基本数据类型转换不同,对象类型转换前提是存在继承关系,当对不存在继承关系的对象进行强制类型转换时,会抛出Java强制类型转换(java.lang.ClassCastException)异常。对象类型转换分为两种,一种是向上转型(upcasting),一种是向下转型(downcasting)。1. 向上转型向上转型是父类对象指向子类引用,向上转型系统自动完成,无需强制转换。使用向上转型可以调用父类类型中的所有成员,不能调用子类类型中特有成员,最终运行效果看子类的具体实现。向上转型一般格式:父类名称对象名称=new子类名称();其中,父类名称可以是类也可以是接口。6.1.8对象类型转换2. 向下转型向下转型与向上转型相反,指的是子类对象指向父类引用,向下转型的前提是已发生向上转型,否则,会出现运行时异常。向上转型主要目的是减少代码的冗余,提高代码简洁性,同个继承链的类可以用同个顶层类型表示参数。如将子类对象作为实参,传递给父类形参,可以不必为每一个子类都写一个子类形参的方法。向下转型一般格式:子类名你对象名称=(子类名称)父类名称6.1.8对象类型转换【6-10】对象类型转换的使用。操作步骤:(1)在包.cvit下创建包example10,在包.cvit.example10下创建类Example10。(2)在example10.java文件中,创建Animal类,定义成员变量name,成员方法eat()和think()方法。(3)在example10.java文件中,创建一个Cat类,继承Animal类,定义成员变量name,重写eat()方法,创建特有的方法play()。(4)文本编辑器视图中,撰写代码如下:6.1.8对象类型转换6.1.8对象类型转换package.cvit.example10;

/**

*对象类型转换

*/

//Animal类

classAnimal{

Stringname="动物";

publicvoideat(){

System.out.println("动物吃东西!!!");

}

publicvoidthink(){

System.out.println("不是所有动物都会思考!!!");

}

}

//Cat类,继承Animal类

classCatextendsAnimal{

Stringname="小花猫";

//重写Animal类中的eat()方法

publicvoideat(){

System.out.println(name+"爱吃鱼!!!");

}

//Cat类中特有方法

publicvoidplay(){

System.out.println(name+"喜欢玩线球!!!");

}

}

6.1.8对象类型转换//测试类

publicclassExample10{

publicstaticvoidmain(String[]args){

Animalanimal=newCat();

//向下转型,Animal对象指向Cat引用

animal.think();

//调用父类中没被子类重写的方法

animal.eat();

//调用eat方法,实现Cat子类功能

Catcat=(Cat)animal;

//向下转型,将animal对象强制转换为Cat类型

cat.play();

//调用Cat类中特有的方法

}

}

6.1.8对象类型转换【6-10】对象类型转换的使用。操作步骤:(1)在包.cvit下创建包example10,在包.cvit.example10下创建类Example10。(2)在example10.java文件中,创建Animal类,定义成员变量name,成员方法eat()和think()方法。(3)在example10.java文件中,创建一个Cat类,继承Animal类,定义成员变量name,重写eat()方法,创建特有的方法play()。(4)文本编辑器视图中,撰写代码如下:6.1.8对象类型转换运行结果:

提示:向上转型所实例化的对象可以调用父类所有方法,如果父类中的方法被子类重写,则实现子类中相应功能,例如:animal对象无法调用Cat类中的play方法。要想调用Cat类中的play方法,需要将animal对象向下转型,即强制转换为Cat类型。6.1.8对象类型转换6.1知识储备–多态静态多态动态多态多态的使用多态(polymorphic)是面向对象三大特征之一,具有十分重要的意义。多态从字面意义上讲就是多种形态,之前学习的方法重载、继承中子类对父类方法的重写以及对象类型转换都是多态的表现形式。方法的重载是通过参数类型、参数个数或参数顺序不同,体现出不同的方法形态;方法的重写是指子类继承父类后,子类可以重新定义方法体,表现出与父类不同的行为,即同一方法在父类及子类中具有不同的形态;对象类型转换可以让父类对象指向子类引用,使父类对象具有了多种形态。6.1.9多态在Java中,多态分为静态多态和动态多态,静态多态也称编译时多态,动态多态也称为运行时多态。静态多态指的是方法的重载,在编译过程中体现出了多态,在运行时不具有多态性,动态多态是通过动态绑定来实现的,也是我们常说的多态性。动态多态需要满足继承、重写和向上转型三必要条件。继承可以提供父类和子类;通过子类重写父类的方法对父类方法重新定义,在调用这些方法时就可以直接调用子类的方法;向上转型需要将父类对象指向子类引用,该对象可以调用父类中所有方法,同样可以调用子类中重写的方法。6.1.9多态【例6-11】多态的使用。操作步骤:(1)在包.cvit下创建包example11,在包.cvit.example11下创建类Example11。(2)在example11.java文件中,创建Animal接口,定义抽象方法。(3)在example11.java文件中,创建Cat类和Dog类,分别实现Animal接口。(4)编辑测试类Example11,定义一animalEat(Animalanimal)方法,通过animal对象调用eat()方法。(5)文本编辑器视图中,撰写代码如下:6.1.9多态package.cvit.example11;

interfaceAnimal{

//Animal接口

voideat();

}

classCatimplementsAnimal{

//Cat类实现Animal接口

publicvoideat(){

System.out.println("小猫爱吃鱼!!!");

}

}

classDogimplementsAnimal{

//Dog类实现Animal接口

publicvoideat(){

System.out.println("小狗爱啃骨头!!!");

}

}6.1.9多态

publicclassExample11{

//测试类

publicstaticvoidanimalEat(Animalanimal){

//animalEat(Animalanimal)方法

animal.eat();

}

publicstaticvoidmain(String[]args){

//主方法

animalEat(newCat());

//调用animalEat()方法,参数为Cat对象

animalEat(newDog());

}

}

6.1.9多态运行结果:

提示:Cat类和Dog类实现了Animal接口,并重写了eat()方法,分别满足了多态的前两个条件。在测试类中,定义的方法参数的Animal类型,调用时传递的实参分别为Cat和Dog类型,完成了向上转型,满足了多态的第三个必要条件。6.1.9多态6.1知识储备–内部类成员内部类静态内部类局部内部类匿名内部类6.1.10内部类内部类顾名思义就是在一个类内部定义类,这样的类被称为内部类,内部类所在的类被称为外部类。内部类具有如下特性:内部类属于独立类,在编译后都可生成独立的字节码文件,但内部类字节码文件前面冠以外部类的类名和$符号。内部类是外部类的成员,因此,内部类可以访问外部类的成员变量,包括私有变量,但如果内部类被声明为静态的,就只能访问外部类中静态变量。内部类按照其位置、修饰符和定义方式的不同,分为成员内部类、静态内部类、局部内部类和匿名内部类4种。6.1.10内部类1.成员内部类成员内部类是指内部类所在的位置与类的成员同级,例如,publicclassOutter{classinner{}}其中Otter为外部类,Inner为内部类。6.1.10内部类【例6-12】成员内部类的演示。操作步骤:(1)在包.cvit下创建包example12,在包.cvit.example12下创建类Example12。(2)文本编辑器视图中,撰写代码如下:6.1.10内部类package.cvit.example12;classOutter{

//定义外部类

intx=10;

//定义外部类成员变量

publicvoidshowOutter(){

//定义外部类成员方法showOutter

System.out.println("外部类...");

System.out.println("外部类成员变量:x="+x);

}

6.1.10内部类

classInner{

//定义内部类

inty=x+10;

//定义内部类成员变量

publicvoidshowInner(){

//定义内部类成员方法showInner

System.out.println("内部类...");

}

publicvoidmethod(){

//定义内部类成员方法method

System.out.println("内部类变量:y="+y);

}

}

publicvoidtestInner(){

//定义外部类成员方法testInner

Innerinner=newInner();

//实例化内部类对象

inner.method();

//调用内部类方法

}

}6.1.10内部类//编写测试类

publicclassExample12{

publicstaticvoidmain(String[]args){

Outteroutter=newOutter();

//实例化外部类对象

Outter.Innerinner=outter.newInner();

//实例化内部类对象

inner.showInner();

//调用内部类方法

outter.testInner();

//调用外部类方法

outter.showOutter();

}

}

6.1.10内部类运行结果:

提示:实例化内部类对象可以在外部类方法中,也可以在测试类中。在测试类中实例化内部类有两种格式。

格式1:外部类名.内部类名内部类对象名=外部类对象名.new内部类();

格式2:外部类名.内部类名内部类对象名=new外部类名().new内部类名();在外部类中可以调用外部类成员变量。6.1.10内部类2. 静态内部类使用static修饰的成员内部类为静态内部类,静态内部类只能访问外部类的静态成员。创建静态内部类对象的格式与成员内部类不同,其格式如下:外部类名.静态内部类名内部类对象=new外部类名.静态内部类名();【例6-13】静态内部类演示。操作步骤:(1)在包.cvit下创建包example13,在包.cvit.example13下创建类Example13。(2)文本编辑器视图中,撰写代码如下:6.1.10内部类package.cvit.example13;

classOutter{

//定义外部类

staticclassInner{

//定义静态内部类

publicvoidshowInner(){

System.out.println(“静态内部类...”);

}

}

}

publicclassExample13{

//编写测试类

publicstaticvoidmain(String[]args){

Outter.Innerinner=newOutter.Inner();

//实例化内部类对象

inner.showInner();

//通过内部类对象调用showInner()方法

}

}6.1.10内部类运行结果:

提示:静态内部类具有static关键字修饰成员的特点,可直接通过类调用。静态内部类中可以定义静态成员,也可以定义非静态成员。运行结果:

6.1.10内部类3.局部内部类将内部类放在外部类的方法内,称为局部内部类或者方法内部类,只能在方法内实例化对象。【例6-14】局部内部类演示。操作步骤:(1)在包.cvit下创建包example14,在包.cvit.example14下创建类Example14。(2)文本编辑器视图中,撰写代码如下:6.1.10内部类package.cvit.example14;

classOutter{

//定义外部类

publicvoidfun(){

//定义外部类方法

classInner{

//定义内部类

publicvoidshowInner(){

//定义内部类方法

System.out.println(“局部内部类...”);

}

}

Innerinner=newInner();

//实例化内部类对象

inner.showInner();

//调用内部类方法

}

}

publicclassExample14{

//编写测试类

publicstaticvoidmain(String[]args){

Outteroutter=newOutter();

//实例化外部类对象

outter.fun();

//调用外部类方法

}

}6.1.10内部类运行结果:

提示:局部内部类可以有成员变量和成员方法,但只能在所定义的方法内部使用。在同一个外部类的成员方法中,不能定义同名的内部类。在同一外部类的不同成员方法中,可以定义同名的内部类,因局部内部类作用范围在方法内。6.1.10内部类4. 匿名内部类没有名字的内部类称为匿名内部类,这种类只被使用一次,通过匿名内部类所在的外部类的成员方法来创建。匿名内部类创建的一般格式如下:new类名/接口名(){//内部类实现代码}6.1.10内部类【例6-14】内部类的演示。操作步骤:(1)在.cvit下创

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论