Java程序设计基础 课件 第7章 OOP-p2_第1页
Java程序设计基础 课件 第7章 OOP-p2_第2页
Java程序设计基础 课件 第7章 OOP-p2_第3页
Java程序设计基础 课件 第7章 OOP-p2_第4页
Java程序设计基础 课件 第7章 OOP-p2_第5页
已阅读5页,还剩136页未读 继续免费阅读

下载本文档

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

文档简介

第7章面向对象程序设计(下)1教学目标(1) 理解父类和子类的关系,使用关键字extends扩展一个类(2) 理解protected访问权限,应用访问修饰符实现更好的信息隐藏(3) 理解子类构造方法的执行,掌握super的用法。(4) 理解在子类中重写父类方法,能应用方法重写(5) 使用final关键字防止类的继承和方法重写(6) 理解密封类的定义和用途(7) 理解Object类,能应用和重写其常用方法toString()、equals()(8) 掌握多态和动态绑定(9) 掌握对象的类型转换(10) 掌握抽象类的概念和应用,理解抽象类示例(11) 掌握接口的概念,掌握接口的声明和使用(12) 掌握父接口、子接口、默认方法及其冲突的解决(13) 理解密封接口和注解接口(14) 理解接口的示例(15) 理解抽象类与接口的区别(16) 理解面向对象程序设计的5个原则2引言(1/3)3假设要定义一个类,对圆、矩形、三角形建模。这些类有很多共同的特性(画线颜色、填充与否、创建时间等等)。引言(2/3)4设计这些类,如何避免冗余,还能使系统易于理解和易于维护?答案是:继承,可提炼公共属性和行为创建一个通用的几何对象类Shape软件重用:在扩展创建新的几何形状时,可以进一步重用Shape例如:正六边形、正五边形、梯形等引言(3/3)Stoptryingtoreinventthewheel,可能是每个程序员入行被告知的一条准则软件重用继承:一种基于源代码的重用机制多态:解决类的功能和行为在继承体系中的再抽象5内容7.1继承7.2super7.3方法重写7.4final7.5密封类67.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例内容7.1继承7.2super7.3方法重写7.4final7.5密封类77.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.1继承87.1.1父类与子类7.1.2protected数据和方法7.1.1父类与子类Java语言是一种单继承的语言,在父类的基础上定义其子类的一般语法形式为:publicclass子类名extends父类名{子类的新成员}需要说明的是:(1)子类名是一个合法的标识符,由用户自己定义。(2)关键字extends用在子类名之后,指定父类名,父类只允许有一个。(3)父类名必须是程序中已有的一个类的类名。(4)父类名之后是子类的类体,由一对花括号{}括起来,这对花括号中的内容是子类新定义的成员。97.1.1父类与子类银行账户类Account借记卡账户DebitCardAccount(不允许透支,具有余额)信用卡账户CreditCardAccount(允许透支,但有限额)这两种账户都共享银行账户Account的共同特征,并有新增功能。107.1.1父类与子类银行账户类Account、借记卡账户类DebitCardAccount、信用卡账户类CreditCardAccount的源代码分别在程序清单7-1、程序清单7-2、程序清单7-3中给出程序清单7-4TestCreditDebitAccount.java,对上述类进行测试117.1.1父类与子类基于上述示例,Java语言的继承机制需要注意的是:(1)Java语言是一种单继承语言,即子类继承父类使用关键字extends时,extends之后只能有一个父类名。(2)子类继承父类的内容,还可以新增内容和重写继承的内容。因此,子类不是父类的子集。(3)据Java语言官方文档,子类继承了父类中所有可被访问的成员(数据域和方法),但是构造方法不属于这类成员,父类构造方法不被能子类继承。然而,父类构造方法可以被子类调用,用于完成子类的初始化工作。例如,程序清单7-2第20行就是父类构造方法调用。(4)据Java语言官方文档,子类既不能继承父类的私有成员,也不能直接访问这些私有成员。如果父类定义了访问私有成员的公有或保护方法,那么子类可以通过这些父类的公有或保护方法间接访问这些私有成员。(5)不是所有“是一种(is-a)”关系都应该用继承来建模。例如,正方形是一种矩形,但是不应该定义一个正方形类继承自矩形类。127.1.1父类与子类注意:关于父类私有成员的继承问题辨析。从内存分配上讲,子类确实继承父类的私有成员。因为在实例化一个子类对象时,系统先为父类中定义的数据域(包括私有成员)分配内存,再为子类中定义的数据域分配内存,所有这些数据域都是属于这个新创建的对象,只不过子类对象不能直接访问其父类的私有成员。为了较为形象地说明这种情况,可以说子类“隐蔽”继承了父类的私有成员。因此,从继承的物理实现上讲,子类继承了其父类的所有成员,包括私有成员。这个说法,有助于我们理解为什么子类构造方法会先调用父类构造方法,父类构造方法是用于初始化父类自身的私有数据域。虽然父类私有数据域不能被子类直接访问,但是也被子类继承了。因此,在创建子类对象时,必须先调用父类构造方法初始化父类的私有数据域。然而,Java语言官方文档说明子类不能继承父类的私有成员,这个说法可从可访问性上来理解。由于父类私有成员不能像子类自身的私有成员一样被访问,所以父类私有成员可以被看做未被继承。这两个说法都可以接受。为了避免混淆,本书采纳了Java语言官方文档的说明。然而,程序员也应理解,从继承的物理实现(内存分配)上来讲,子类确实继承了父类的私有成员。13147-1一个子类是父类的子集,这句话是否正确()正确错误AB提交单选题1分157-2定义一个子类,使用关键字

[填空1]

作答正常使用填空题需3.0以上版本雨课堂填空题1分7.1继承167.1.1父类与子类7.1.2protected数据和方法7.1.2protected数据和方法protected修饰符能修饰一个类的数据域和方法。一个public类的被保护数据域和方法可以被同一包中的任何类访问或任何子类访问(即使子类不在同一包中)可见性修饰符public、protected、private,指定了类和类的成员的可见性(或可访问性)。这些修饰符的可见性按下面顺序递增,如下图所示。177.1.2protected数据和方法在不同修饰符修饰一个public类(公有类)的成员时类中成员的可访问性187.1.2protected数据和方法197.1.2protected数据和方法关键字protected和private只能用于修饰类的成员,而关键字public既能用于修饰类的成员,也能用于修饰类。在继承机制下,为了实现更好的信息隐藏,最好是在父类中使用可见性修饰符protected。在父类中使用protected声明的成员,被继承后在子类中就像公有成员一样,可由子类方法直接访问。然而,在子类之外,父类的保护成员在其他包的类看来则像私有成员一样,不能被直接访问,从而实现了更好的信息隐藏。20217-3判断正误:protected的可见性低于包私有的可见性,()正确错误AB提交单选题1分227-4以下哪项陈述是错误的?()公有类可以被来自不同包的类访问。不同包中的类无法访问一个类的私有方法。受保护的方法可被不同包中的子类访问。没有可见性修饰符的方法可以被不同包中的类访问。ABCD提交单选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类237.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.2super关键字super主要用在继承机制中,它指向super所在类的直接父类,主要有两种使用方式:一是在子类构造方法中调用父类的构造方法;二是调用父类的普通方法。247.2.1调用父类构造方法7.2.2调用父类普通方法25父类构造方法不能被子类继承。父类构造方法必须被子类显式或隐式调用。显式调用需使用super关键字。隐式调用无须编写调用语句。

显式调用父类构造方法的语法是:

super();或者

super(实际参数列表);而且,super()或super(实际参数列表)必须出现在子类构造方法的第一行。这是显式调用父类构造方法的唯一形式。7.2.1调用父类构造方法26如果子类构造方法没有显式调用父类构造方法,那么编译器会将super()做为子类构造方法的第一条语句。例如,

7.2.1调用父类构造方法7.2.1调用父类构造方法子类构造方法在构建一个子类实例时被调用执行。子类构造方法在执行时,会沿着继承链从根类Object出发向下依次调用所有父类的构造方法,最后执行子类自身的初始化语句程序清单7-5ClsD.java27287-5下面的说法是否正确?()当从子类调用构造方法时,它父类的无参构造方法总是会被调用。正确错误AB提交单选题1分297-6一个子类对象被创建时,子类自身的构造方法先执行,再依次执行其父类的构造方法,最终完成对象的创建。这句话是否正确()正确错误AB提交单选题1分30publicclassAppleextendsFruit{}

classFruit{publicFruit(Stringname){System.out.println("Fruit'sconstructorisinvoked");}}寻找下面这段代码的错误讨论题:讨论父类没有无参构造方法的影响设计指南:一般情况下,最好能为每个类提供一个无参构造方法,以便于对该类进行扩展,同时避免错误。7.2super关键字super主要用在继承机制中,它指向super所在类的直接父类,主要有两种使用方式:一是在子类构造方法中调用父类的构造方法;二是调用父类的普通方法。317.2.1调用父类构造方法7.2.2调用父类普通方法7.2.2调用父类普通方法32关键字super可调用父类的方法,所用语法如下:super.方法名();或super.方法名(参数);内容7.1继承7.2super7.3方法重写7.4final7.5密封类337.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例子类继承父类,子类可以增加新的属性、增加新的方法方法重写(MethodOverriding):重新定义从父类继承而来的方法347.3方法重写7.3方法重写:重写标注@Override重写标注(overrideannotation):@Override表示被标注的方法必须重写父类的一个方法。如果具有该标注的地方没有重写父类的方法,编译器将报告一个错误。357.3方法重写子类中重写的方法必须和父类中被重写的方法具有相同的方法签名,具有一样或兼容的返回类型。兼容的含义是指子类中重写方法的返回类型可以是父类中被重写方法的返回类型的子类型。举例说明36PersonStudentABPersonf(inti)Personf(inti)ORStudentf(inti)注意事项(1)7.3方法重写仅当实例方法是可访问时,它才能被重写。父类的私有方法不能被子类重写如果子类定义的方法在父类存在同名私有方法,这两个方法完全没有关系37注意事项(2)387-7下面说法是否正确?()

可以重写父类中定义的私有方法。正确错误AB提交单选题1分7.3方法重写重写方法时,不能降低方法的可访问性。具体来说,父类中被重写方法的可见性修饰符是public,那么子类中重写方法的可见性修饰符必须是public。父类中被重写方法的可见性修饰符是protected,那么子类中重写方法的可见性修饰符可以是protected或public。。39注意事项(3)7.3方法重写静态方法能够被继承,但不能被重写。如果子类重新定义父类中的静态方法,那么父类的静态方法会被隐藏。如果需要调用父类被隐藏的静态方法,可以使用语法“父类名.静态方法名(实际参数列表)”调用。40注意事项(4)417-8下面说法是否正确?()

可以重写父类中定义的静态方法。正确错误AB提交单选题1分7.3方法重写方法重写与方法重载的区别:方法重写发生在具有继承关系的不同类中;方法重载既可以发生在同一个类中,也可以发生在不同类中。方法重写要求方法签名相同;而方法重载要求方法名相同而方法签名不同。42注意事项(5)7.3方法重写:重写vs.重载重载:同样的方法名,方法签名不同重写:方法签名相同,在子类中提供一个对方法的新的实现。举例说明:4344重载重写457-9如果子类中的方法具有和它父类中的方法相同的签名,且返回值类型也相同,那么这是方法重载还是方法重写?()方法重载方法重写AB提交单选题1分467-10如果子类中的方法具有和它父类中的方法相同的名字,但参数类型不同,那么这是方法重载还是方法重写?()方法重载方法重写AB提交单选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类477.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.4final有时候,可能希望防止类扩展。在这种情况,使用final修饰符表明一个类是最终的,不能作为父类。String、StringBuilder、StringBuffer就是最终类。例:publicfinalclassClsA{}当希望一个方法不被子类重写时,也可以定义一个方法是最终的。例:48publicclassClsB{ publicfinalvoidm1(){}}最终类不能被扩展:

finalclassMath{...}最终变量是一个常量:

finalstaticdoublePI=3.14159;最终方法不能被子类重写497.4final507-11下面哪个类不能被扩展?()classA{}classA{privateA(){}}finalclassA{}classA{protectedA(){}}ABCD提交单选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类517.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.5密封类Java17的新特性之一是正式引入了密封类(Sealedclass)。为什么引入密封类呢?这是为了对继承能力进行限制。在面向对象程序设计语言中,继承可以用来实现代码复用。然而,有时候我们不希望继承被滥用,不希望一个类被继承后去做一些不可预知的扩展,或者不希望一个类任意被扩展(一个类的子类可能需要限于其开发者所知的那些子类)。如果一个类被声明为密封类,那么该类的所有直接子类都是已知的,并且不能再有其他直接子类。这种方式对一个类的所有直接子类进行显式和详尽的控制。直接子类也可以被声明为密封的,以进一步控制类的层次结构。因此,密封类有助于在继承中创建有限且可确定的类层次结构。527.5密封类Java语言使用sealed关键字声明密封类,使用permit关键字声明哪个类可以是直接子类。而继承密封类的子类必须被声明为sealed或non-sealed或final。下面以一个示例来说明密封类的声明。该示例有一个抽象形状类Shape,是密封类。允许Shape类三个子类(圆类Circle、矩形类Rect、三角形Triangle),不允许有其他子类。53packageedu.example.Chapter7;publicabstractsealedclassShape

permitsCircle,Rect,Triangle{…}547-12Java语言使用

[填空1]

关键字声明密封类,使用

[填空2]

关键声明哪个类可以是直接子类。作答填空题2分7.5密封类如果Shape类的子类位于同一命名模块的不同包中,那么在permits之后要指明子类的完整路径。例如:55packageedu.example.Chapter7;publicabstractsealedclassShapepermitsedu.example.geometry.Circle,edu.example.shape1.Rect,edu.exmaple.shape2.Triangle{…}7.5密封类当一个密封类与其数量不多的子类声明在相同的源文件时,可以省略permits语句,Java编译器会从源文件的声明中推断出permits的子类。例如,56publicabstractsealedclassClsRoot{… finalclassClsAextendsClsRoot{…} finalclassClsBextendsClsRoot{…} finalclassClsCextendsClsRoot{…}}7.5密封类密封类对其允许的子类有三个约束:(1)密封类及其允许的子类必须属于同一个模块。另外,如果密封类及其允许的子类在未命名的模块中声明,那么它们必须属于同一个包。(2)每个允许的子类都必须直接继承密封类。(3)每个允许的子类都必须使用三个修饰符(final、sealed、non-sealed)之一来描述它如何传播由其父类发起的密封:①允许的子类可以被声明为final,以防止其在类层次结构中的一部分被进一步扩展(允许的子类无法再扩展)。②允许的子类可以再次被声明为密封类(sealed),这样允许的子类能以一种受限制的方式进一步扩展。③允许的子类可以声明为非密封的(non-sealed),这样允许的子类可以被任意的扩展(未知的子类也可以被扩展)。密封类不能阻止其允许的子类声明为non-sealed。577.5密封类下面对前面的示例进行扩充和改写展示子类修饰符的使用,如下所示:[1]行: packageedu.example.Chapter7;[2]行: publicabstractsealedclassShapepermitsCircle,Rect,Triangle,OddShape{…}[3]行: publicfinalclassCircleextendsShape{…}[4]行: publicsealedclassRectextendsShapepermitsFilledRect,TransparentRect{…}[5]行: publicfinalclassFilledRectextendsRect{…}[6]行: publicfinalclassTransparentRectextendsRect{…}[7]行: publicnon-sealedclassOddShapeextendsShape{…}58597-13密封类及其允许的子类必须属于同一个

[填空1]

作答填空题1分607-14一个允许的子类只能使用三个修饰符(

[填空1])中的一个来进行修饰,不能同时使用多个进行修饰。(多个修饰符之间用顿号、分隔)作答填空题1.5分内容7.1继承7.2super7.3方法重写7.4final7.5密封类617.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.6ObjectJava中的所有类都继承自java.lang.Object类。如果在定义一个类时没有指定继承性,那么这个类的父类被默认为是Object.类Object提供了一个无参构造方法:publicObject()。类Object的子类的构造方法会默认调用类Object的无参构造方法。

627.6Object类Object常见方法clone:对象之间的拷贝方法,默认实现是浅拷贝。equals:默认实现比较两个对象的引用值而不是内容。finalize:由垃圾回收机制调用的protected方法。getClass:在运行时刻返回对象的类类型。toString:返回一个对象的字符串表示其他方法:hashCode,wait,notify,notifyAll637.6.1方法toString()调用一个对象的toString()会返回一个描述该对象的字符串。默认情况下,它返回一个字符串:该对象所属类名、@、该对象16进制形式的内存地址组成的字符串。64Loanloan=newLoan();System.out.println(loan.toString());输出结果:Loan@15037e5演示1:程序清单7-6SimpleCircle.java演示2:程序清单7-7SimpleCircle1.java7.6.2方法equals()在Object类中,equals方法的缺省实现如下:65publicbooleanequals(Objectobj){returnthis==obj;}equals方法的默认实现与==功能一样,判断两个对象是否具有相同的引用。方法equals()在JavaAPI的许多类中被重写,其功能不再是比较两个引用变量是否指向同一个对象,而是比较两个对象的内容是否相同。例如,java.lang.String对方法equals()进行了重写,用于比较两个字符串对象的内容是否相等。Strings1=newString("Hello");Strings2="Hello";Strings3="Hello";7.6.2方法equals()比较运算符==用来比较两个基本数据类型的值是否相等,或判断两个对象是否具有相同的引用。如果比较两个对象的内容,需重写equals方法。重写equals方法,应使用equals(Objectobj)。而不应该使用equals(SomeClassNameobj)。程序演示:程序清单7-8Circle1.java66677-15Object类的equals()方法默认实现的功能与==操作符功能是一样,用于两个对象的引用是否相等。这句话是否正确()正确错误AB提交单选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类687.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.7多态性一个父类引用变量既可以引用一个父类类型的对象,又可以引用其任何一个子类类型的对象多态性存在的三个必要条件:第一要有继承第二要有方法重写第三父类引用变量指向其子类对象示例:程序清单7-9、程序清单7-10、程序清单7-11、程序清单7-12分别展示Shape、Circle、Rect、TestShapes的代码,其继承层次图如上69707-16多态性存在的3个必要条件()有继承有方法重写有方法重载父类变量指向子类变量ABCD提交子类变量指向父类变量E多选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类717.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.8动态绑定动态绑定(dynamicbinding)是实现多态性的关键技术,是指在运行期间判断所引用对象的实际类型,根据其实际类型调用相应的方法。例如,在7.6节的示例中,程序清单7-12中的方法display根据父类引用变量s所引用的实际类型,调用相应的方法。publicstaticvoiddisplay(Shapes){ System.out.println(s.toString()+".面积:"+s.getArea());}当父类引用变量s指向圆对象c时,被调用的方法是类Circle的方法toString和方法getArea。当父类引用变量s指向矩形对象r时,被调用的方法是类Rect的方法toString和方法getArea。727.8动态绑定为了更好地理解动态绑定的概念,引入两个概念:声明类型和实际类型。声明类型(declaredtype):一个变量被声明为某种类型实际类型(actualtype):被变量引用的对象的实际类型。如:s的声明类型是Shape,实际类型可能是Circle或Rect调用哪个对象的toString方法和getArea方法,由对象s的实际类型决定。737.8动态绑定首先,假设C1类是Object类的直接子类,C2类是C1类的直接子类,C3类是C2类的直接子类,依次类推,Cn是Cn-1的直接子类。其次,假设对象obj的声明类型是Object类,那么对象obj的实际类型可以是类C1、C2、…、Cn中的任何一个。这时,如果对象obj调用了一个方法func(),那么在编译阶段,编译器根据对象obj的声明类型匹配方法的签名,完成编译,这个过程也被称为方法匹配。在运行阶段,JVM会根据对象obj的实际类型绑定具体的方法实现。747.8动态绑定下面分两种情况进行说明。情况1,方法func()在Object的所有子类中进行了重写,那么在运行阶段,JVM会根据对象obj的实际类型Ci绑定Ci类的方法实现。情况2,方法func()只是在部分子类中进行了重写,那么JVM在进行方法绑定时,会从对象obj的实际类型Ci开始,沿着继承链向Object方向寻找一个最近的方法实现。例如,假设对象obj的实际类型是Cn,而Cn、Cn-1、Cn-2没有对方法p进行重写,而Cn-3、…、C2、C1对方法func()进行了重写,那么在进行方法绑定时,会绑定Cn-3类的方法实现。程序演示:程序清单7-13Cuboid.java75767-17以下哪项陈述是错误的?()始终可以将子类的实例传递给其超类类型的参数。这个特性被称为多态性。A编译器根据参数类型、参数数量和编译时参数的顺序来查找匹配方法。B一个方法可以在几个子类中实现,Java虚拟机在运行时动态绑定方法的实现。C动态绑定可以应用于静态方法。D动态绑定可以应用于实例方法。E提交单选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类777.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例对象转换:一类对象的引用可以类型转换为对另一类对象的引用。例:Shapes=c;//c是Circle类的一个实例,隐式转换Circlec2=s;//子类对象的引用指向父类的一个对象,编译器会报错显式转换:Circlec2=(Shape)s;//向下转换向上转换(upcasting):总是可以将一个子类的实例转换为一个父类的变量。向下转换(downcasting):当把一个父类的实例转换为它的子类变量时,必须使用转换记号“(子类名)”进行显式转换。为了使向下转换成功,必须确保父类变量引用的对象是子类的一个实例。当父类变量引用的对象不是子类的实例时,向下转换会导致一个运行异常ClassCastException。787.9对象转换Shapes=newCircle();//合法正确,s指向一个Circle的实例Rectr2=(Rect)s;//产生运行时错误797-18给定下面的类和对象: classC1{}; classC2extendsC1{}; classC3extendsC1{}; C2c2=newC2(); C3c3=newC3();分析如下语句:c2=(C2)((C1)c3);c3成功转换为c2你将遇到一个运行时错误,因为你不能将对象转换为兄弟对象你将遇到一个运行时错误,因为Java运行时系统不能以嵌套形式执行多个类型转换语句是正确的ABCD提交单选题2分807.9对象转换在进行向下转换时,为了避免编译时正确而运行时出现错误,一个好的、惯用的做法是在进行向下转换之前,利用instanceof运算符判断父类引用变量的实际类型。例如,下面的一段代码改写方法display的实现:voiddisplay(Shapes){if(sinstanceofCircle)//判断s是否指向类Circle的一个实例

System.out.println(“这是一个圆,半径为:”+((Circle)s).getRadius());…}在这个例子中,类Shape没有方法getRadius,只有类Circle有getRadius(),因此,如果没有将s向下转换指向一个圆对象,那么使用s.getRadius()会引起编译错误。通过向下转换,s被转换成Circle的一个实例,再调用方法getRadius就没有问题了。817-19给定下面的代码:classC1{}classC2extendsC1{}classC3extendsC2{}classC4extendsC1{}c1instanceofC1c2instanceofC1c3instanceofC1c4instanceofC2ABCD提交C1c1=newC1();C2c2=newC2();C3c3=newC3();C4c4=newC4();下列哪个表达式的值是false?()单选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类827.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.10抽象类83现实世界存在一些抽象的概念。水果车动物植物抽象概念书比赛这些抽象概念没有具体实例抽象概念可由抽象类表示,抽象类是没有具体实例的类7.10抽象类84在Java语言中,使用关键字abstract修饰抽象类的定义。例如,定义一个公有抽象类的一般形式如下:publicabstractclass类名{….}//一个公有抽象类的定义抽象方法是没有具体实现的方法,即无需定义方法体。定义抽象方法时,需要在方法头的返回值类型之前使用关键字abstract进行修饰定义一个公有抽象方法的一般形式如下:

publicabstract返回值类型方法名(形式参数列表);//一个公有抽象方法定义示例:ShapeObj类、CircleObj类、RectObj类、TestShapeObjs类。这些类的代码分别如程序清单7-14、程序清单7-15、程序清单7-16、程序清单7-17所示。857-20抽象类定义时,必须使用[填空1]关键字修饰类的定义。作答填空题1分7.10抽象类86关于抽象类,下面几点需要注意:(1)抽象类定义时,使用abstract关键字修饰类的定义。(2)抽象类不能使用new关键字创建自己的实例,例如,抽象类ShapeObj类不能创建自己的实例。具体来说,下面语句:ShapeObjobj=newShapeObj();//在编译时,会产生编译错误但可声明一个ShapeObj类型的引用变量,让其指向一个子类实例,如下所示:ShapeObjsObj=newCircleObj(3);//抽象父类变量sObj指向一个子类实例还可以使用new关键字定义抽象类的数组,如下所示:ShapeObj[]shapes=newShapeObj[10];shapes[0]=newRect(2,3);877-21抽象类不能使用new关键字创建自己的实例和对象数组,这句话是否正确?()正确错误AB提交单选题1分887-22假定A是一个抽象类,B是继承A类的一个具体子类,A和B均有无参构造方法,下列语句正确的是()Aa=newA();Aa=newB();Bb=newA();Bb=newB();ABCD提交多选题1分7.10抽象类89关于抽象类,下面几点需要注意:(3)通常,抽象类的构造方法应被设计成protected权限,仅被其子类调用。(4)抽象方法没有方法体的定义,在方法头中使用abstract关键字。(5)一个具体子类继承了抽象类,该具体子类必须实现抽象父类中定义的所有抽象方法。(6)如果一个类继承了抽象类,但没有实现抽象父类中定义的所有抽象方法,那么该类也会成为一个抽象类。907-23一个抽象类必须含有至少一个抽象方法,这句话是否正确?()正确错误AB提交单选题1分7.10抽象类91关于抽象类,下面几点需要注意:(7)含有抽象方法的类必须被定义为抽象类,然而,一个抽象类可以没有抽象方法。(8)抽象方法是非静态的。静态方法不能被定义为抽象的。这是因为抽象方法是没有实现的,而静态方法在一个类加载到JVM时,就可以被调用和使用,静态方法是必须要有方法实现的。(9)子类可以重写父类的方法并将它们定义为抽象的,在这种情况下,子类由于存在抽象方法,所以必须被定义为抽象类。这种做法虽然很少见,但是在希望父类的某个方法实现在子类中变得无效时,这种做法还是有用的。927-24下列关于抽象方法的描述,哪些是正确的()抽象类可以使用抽象类的构造方法创建实例。抽象类可以被扩展。非抽象超类的子类可以是抽象的。子类可以重写超类中的具体方法来声明它是抽象的。ABCD提交抽象方法可以是静态方法E多选题1分内容7.1继承7.2super7.3方法重写7.4final7.5密封类937.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.11抽象类示例947.11.1抽象类Calendar和子类GregorianCalendar7.11.2抽象类Number及其子类7.11.1抽象类Calendar和子类GregorianCalendarjava.util.Calendar是一个抽象类,可用于表示详细的日历信息,例如,年、月、日、时、分、秒等。Calendar类的具体子类可以实现特定的日历系统。Java语言内建支持公历日历系统的实现。95抽象类Calendar的常量数据域7.11.1抽象类Calendar和子类GregorianCalendar96抽象类Calendar的常量数据域7.11.1抽象类Calendar和子类GregorianCalendar97抽象类Calendar的构造方法与部分常用方法7.11.1抽象类Calendar和子类GregorianCalendar98抽象类Calendar的构造方法与部分常用方法7.11.1抽象类Calendar和子类GregorianCalendar99抽象类Calendar的构造方法与部分常用方法1007-25Java语言的日历系统中,每周的第一天,美国是Monday,法国是Sunday,这句话是否正确?()正确错误AB提交单选题1分此题未设置答案,请点击右侧设置按钮7.11.1抽象类Calendar和子类GregorianCalendar101java.util.GreGorianCalendar(公历类)继承了抽象类Calendar,其数据域具有默认值。7.11.1抽象类Calendar和子类GregorianCalendar102GreGorianCalendar构造方法7.11.1抽象类Calendar和子类GregorianCalendar程序演示:程序清单7-18TestCalendar.java方法getMaximum(Calendar.DAY_OF_MONTH)可获得当月的实际天数1037.11抽象类示例1047.11.1抽象类Calendar和子类GregorianCalendar7.11.2抽象类Number及其子类7.11.2抽象类Number及其子类1054个方法各子类实现调用intValue()实现程序演示:程序清单7-19TestNumberClasses.java内容7.1继承7.2super7.3方法重写7.4final7.5密封类1067.6Object类7.7多态性7.14抽象类与接口7.8动态绑定7.9对象转换7.10抽象类7.11抽象类示例7.12接口7.13接口示例7.12接口1077.12.1普通接口声明7.12.2接口实现7.12.3父接口与子接口7.12.4默认方法、静态和私有方法7.12.5默认方法冲突7.12.6密封接口7.12.7注解与注解接口7.12.1普通接口声明普通接口声明的简单形式:[接口修饰符]interface接口名{ /**常量声明*/ /**抽象方法声明*/}接口名通常是形容词示例:接口体中定义的常量,都是公有的static常量,允许省略public、final、static修饰符。108publicinterfaceComputable{finalintMAX=1000;finalintMIN=1;voidadd(Computableobj);voidsubstract(Computableobj);}publicinterfaceComputable{intMAX=1000;voidadd(Computableobj);voidsubstract(Computableobj);}publicinterfaceComputable{publicstaticfinalintMAX=1000;publicabstractvoidadd(Computableobj);publicabstractvoidsubstract(Computableobj);}等价1097-26下列哪个是一个正确的接口?()interfaceA{voidprint(){};}abstractinterfaceA{print();}abstractinterfaceA{abstractvoidprint(){};}interfaceA{voidprint();}ABCD提交单选题1分7.12接口1107.12.1普通接口声明7.12.2接口实现7.12.3父接口与子接口7.12.4默认方法、静态和私有方法7.12.5默认方法冲突7.12.6密封接口7.12.7注解与注解接口7.12.2接口实现接口与实现该接口的类之间的关系称为接口实现或接口继承接口实现使用关键字implements,其一般形式如下:[修饰符]class类名[extends父类名]implements接口1[,接口2][,接口3][,…]{ …}该类需要实现这些接口中的所有抽象方法虽然接口不是类,但是Java语言把接口看做一种特殊的类。与类一样,每个接口被编译为独立的字节码文件。1117.12.2接口实现接口可将一组不相关的类组织在一起。示例:这些类的代码分别如程序清单7-20~7-26当传递给接口类型变量的对象的实际类型不同时,就会回调不同类实现的接口方法,这也被称为接口回调。1121137-27接口与实现该接口的类之间的关系称为

[填空1]

[填空2]。

作答填空题2分7.12接口1147.12.1普通接口声明7.12.2接口实现7.12.3父接口与子接口7.12.4默认方法、静态和私有方法7.12.5默认方法冲突7.12.6密封接口7.12.7注解与注解接口7.12.3父接口与子接口一个接口可以通过关键字extends扩展多个接口,一般形式如下:publicinterface接口名extends接口名1[,接口名2][,…][,接口名n]{…}被声明的接口是子接口,被扩展的接口是父接口(或超级接口)子接口会继承所有父接口的成员。一个实现了某个接口的类必须实现该接口及其所有父接口中定义的抽象方法。115publicinterfaceI1extendsI2,I3{…}I1obj1;/*obj1既是子接口I1的引用变量,也是父接口I2、I3的引用变量*/7.12接口1167.12.1普通接口声明7.12.2接口实现7.12.3父接口与子接口7.12.4默认方法、静态和私有方法7.12.5默认方法冲突7.12.6密封接口7.12.7注解与注解接口7.12.4默认方法、静态和私有方法自Java8开始,接口中的方法是允许有默认实现的,称为默认方法。使用关键字default定义默认方法。例如,interfaceTop{defaultStringname(){return"unnamed";}}默认方法在实现该接口的类中可以被重写,也可以无须进行重写。1171187-28接口中定义默认方法必须使用的关键字是

[填空1]

作答填空题1分7.12.4默认方法、静态和私有方法从Java8开始,允许在接口中定义公有静态方法。公有静态方法可以通过接口名直接调用,与类中公有静态方法的使用是一样的。从Java9开始,允许在接口中定义私有方法。这些私有方法的用法有限,只能作为接口中其他方法的辅助方法。119publicinterfaceDemoInterface1{//公有静态方法publicstaticintgetObjCount(){return0;}…}interfaceDemoInterface2{//私有静态方法privatestaticvoiddislay(){System.out.println

("defaultprivateimplementation!");}//私有实例方法privateintgetAttribute(){return1;}…}7.12接口1207.12.1普通接口声明7.12.2接口实现7.12.3父接口与子接口7.12.4默认方法、静态和私有方法7.12.5默认方法冲突7.12.6密封接口7.12.7注解与注解接口7.12.5默认方法冲突问题:一个类可以继承一个类,实现多个接口。如果一个被实现的接口中定义了一个默认方法,而在父类或另一个实现的接口中存在同样的方法,这种冲突,该如何解决?Java语言的处理规则如下:(1)接口与父类冲突。如果父类提供了一个具体方法,那么接口中具有相同方法签名的默认方法会被忽略,即采取父类优先的原则。(2)接口冲突。如果一个接口提供了一个默认方法,另一个接口提供了一个方法签名相同的方法,那么必须重写这个方法来解决冲突。示例:程序清单7-27Student.java-规则1程序清单7-28Teacher.java-规则21211227-29当被实现的接口与被继承的父类存在方法冲突时,如果父类提供了一个具体方法,那么接口中具有相同方法签名的默认方法会被忽略,即采取

[填空1]

的原则。作答填空题1分1237-30当被实现的两个接口存在方法冲突时,如果一个接口提供了一个默认方法,另一个接口提供了一个方法签名相同的方法,那么必须

[填空1]

这个方法来解决冲突。作答填空题1分7.12接口1247.12.1普通接口声明7.12.2接口实现7.12.3父接口与子接口7.12.4默认方法、静态和私有方法7.12.5默认方法冲突7.12.6密封接口7.12.7注解与注解接口7.12.6密封接口如果一个接口的所有直接子类或子接口是已知的,那么该接口可以被声明为密封的(sealed),即密封接口。与密封类相似,Java语言可以使用关键字sealed对接口进行密封,使用关键字permits指定允许的实现类和子接口125sealedinterfaceEatablepermitsFruit,Vegetable,egg,Cooked{…}abstractsealedclassFruitimplementsEatablepermitsApple,Orange{…}finalclassAppleextendsFruit{…}finalclassOrangeextendsFruit{…}abstractnon-sealedclassVegetableimplementsEatable{…}finalclasseggimplementsEatable{…}non-sealedinterfaceCookedextendsEatable{…}接口Eatable是密封接口,它有三个直接子类Fruit、Vegetable、egg和一个子接口Cooked。子类Fruit是一个密封的抽象类,限定了两个子类Apple、Orange。子类Vegetable是一个非密封的抽象类,可以任意扩展。子类egg是一个最终类,不允许被扩展。一个非密封的子接口Cooked扩展了密封接口Eatable7.12.6密封接口关于密封接口的几点说明。(1)当一个接口的所有直接超级接口都不是密封接口,自身也不是密封的,该接口是可以被任意扩展的。(2)一个具有直接密封超级接口的子接口当且仅当它被声明为非密封(non-sealed)时,它才是可以被任意扩展的。(3)如果一个接口没有密封的超级接口,那么该接口不能被声明为non-sealed,否则,会产生编译错误。(4)如果一个接口继承了一个密封的超级接口,那么该子接口必须被声明为sealed或non-sealed,否则,会产生编译错误。(5)如果一个密封接口在一个命名模块中,那么在permits语句中指定的类或接口,也必须在同一个模块中。(6)如果一个密封接口在一个未命名模块中,那么在permits语句中指定的类或接口,也必须在同一个包中。1261277-31如果一个接口没有密封的超级接口,那么该接口不能被声明为non-sealed,否则,会产生

[填空1]

作答填空题1分1287-32如果一个接口继承了一个密封的超级接口,那么该子接口必须被声明为

[填空1]

[填空2]

,否则,会产生编译错误。作答填空题2

温馨提示

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

评论

0/150

提交评论