面向对象编程进阶1.ppt_第1页
面向对象编程进阶1.ppt_第2页
面向对象编程进阶1.ppt_第3页
面向对象编程进阶1.ppt_第4页
面向对象编程进阶1.ppt_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

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

文档简介

LOGO 第5章 面向对象编程进阶 主要内容 类的继承 1 多态性2 静态初始化块 3 final修饰符 4 面向对象编程的三大特征:封装、继承和多态。 主要内容 5 抽象类 6接口 7 内部类 8匿名类 5.1 类的继承 人是哺乳动物,因为人都具有哺乳动物的所有特征,但 哺乳动物却不一定是人。哺乳动物类和人类之间就存在继承 关系(IS-A)。 mammals dogscatshumans lionstigersleopards 5.1 类的继承 继承是面向对象三大特征之一,也是实现软件复用的 重要手段。 继承的特点 通过继承,在已有类型基础之上进行扩充或改造 ,得到新的数据类型。 已有的类型称为父类或超类。 得到的新数据类型,称为子类或派生类 类的继承提高了程序代码的重用性和可扩充性, 缩短了软件开发的周期。 5.1 类的继承 继承的分类 单继承-子类只能有一个直接父类 多重继承-子类可以有多个直接父类 类A类B 类C 类A 类B Java不支持多重继承 5.1 类的继承 子类继承父类的语法格式 修饰符 class 子类名 extends 父类名 /子类代码部分 例5.1 编写程序示范子类继承父类的特点。 public class Animal public double weight; public void eat() System.out.println(“动物在吃东西“); 扩展(继承) 5.1 类的继承 public class Dog extends Animal public void say() System.out.pringln(“狗叫:汪汪汪”); public static void main(String args) Dog d= new Dog(); d.weight = 150; d.eat(); d.say(); Dog类中没有定义weight属性和eat方法,是从父类 Animal中继承下来,并且访问权限没有发生变化 如果定义Java类时并未显示指定这个类的直接 父类,则这个类默认扩展java.lang.Object类 5.1 类的继承 重写父类的方法 子类扩展父类-总是以父类为基础,额外增加新的属性和 方法。但有一种情况例外:子类需要重写父类的方法。 例5.2 子类重写父类的方法 public class Bird public void fly() System.out.println(“我在飞“); 5.1 类的继承 public class Ostrich extends Bird /重写Bird类的fly方法-方法覆盖(override) public void fly() System.out.println(“我只能在地上奔跑“); public static void main(String args) Ostrich os = new Ostrich(); os.fly(); /调用的是Bird的fly还是Ostrich的fly? 重写 父类 方法 5.1 类的继承 方法重写时要遵循的规则:“两同两小一大”规则 “两同”即方法名相同,形参列表相同; “两小”指的是子类方法返回值类型应比父类方法返 回值类型更小或相等,子类方法声明抛出的异常类应 比父类方法声明抛出的异常类更小或相等; “一大”指的子类方法的访问权限应比父类方法更大 或相等; 覆盖方法和被覆盖方法要么都是类方法,要么都是 实例方法,不能一个是类方法,一个是实例方法。 5.1 类的继承 方法重写和方法重载的区别 覆盖是子类和父类之间的关系;而重载是同一类内 部多个方法之间的关系。 覆盖一般是两个方法间的,而重载可能有多个重载 的方法。 覆盖的方法有相同的方法名和形参表;而重载的方 法只能有相同的方法名,不能有相同的形参表。 覆盖时根据调用它的对象来区分方法;而重载是根 据形参表来决定调用的是哪个方法。 5.1 类的继承 父类实例的super引用 如果需要在子类方法中调用父类被覆盖的实例方法,可以用 super作为调用者来调用父类被覆盖的实例方法。 public class Ostrich extends Bird /子类中原有的内容 public void callOverridedMethod() super.fly(); /输出“我在飞” 在子类中想调用父类被覆盖的方法 fly可以通过super关键字实现 5.1 类的继承 注意: super是Java提供的一个关键字,它是直接父类对 象的默认引用。 正如this不能出现在static修饰的方法中一样, super也不能出现在static的方法中 如果子类定义了和父类同名的属性,也会发生子类 属性覆盖父类属性的情形。子类的方法直接访问该属 性时,都会访问到覆盖属性,无法访问父类被覆盖的 属性-通过super来访问父类被覆盖的属性 例5.3 子类属性覆盖父类属性的实例。 如果我们在某个方法中访问名为a的属性,但没有显示 指定调用者,系统查找a的顺序为: 查找该方法中是否有名为a的局部变量 查找当前类中是否包含名为a的属性 查找a 的直接父类中是否包含名为a的属性,依次 上溯a的父类,直到java.lang.Object类,如果最 终不能找到名为a的属性,则系统出现编译错误。 5.1 类的继承 调用父类构造方法 子类不会继承父类的构造方法,但有的时候子类构造方法 里需要调用父类构造方法的初始化代码。 例 写出下面程序的执行结果。 class Base protected double size; public Base() size=0; System.out.println(“Base类无参构造”); public Base(double s) size=s;System.out.println(“Base类有参构造”); 5.1 类的继承 public class Sub extends Base private String color; public Sub() color=“blue”;System.out.println(“Sub类无参构造 ”); public Sub(String c) color=c;System.out.println(“Sub类有参构造”); public static void main(String args) Sub s1=new Sub(); Sub s2=new Sub(“red”); 当通过子类构造方法创建子类对象时,默认的先执行父 类不含参数的构造方法,再执行子类类构造方法。 5.1 类的继承 要在子类中显式调用直接父类带参数的构造方法 ,可通过super()调用来实现。例如, public Sub(double s,String c) super(s); /调用Base类中带一个参数的构造方法 color=c; System.out.println(“Sub类有参构造”); 注意:super调用和this调用很像,区别在于super调用的是其 父类的构造方法,而this调用的是同一个类中重载的构造方法 。因此,使用super调用父类构造也必须出现在子类构造执行 体的第一行,所以this调用和super调用不会同时出现。 5.1 类的继承 子类构造方法调用父类构造方法分如下几种情况: 子类构造方法执行体的第一行代码使用super显示调 用父类构造方法,系统将根据super调用里传入的实参 列表调用父类对应的构造方法。 子类构造方法执行体的第一行代码使用this显示调用 本类中重载的构造方法,系统将根据this调用里传入的 实参列表调用本类另一个构造方法。执行本类中另一 个构造方法时即会调用父类的构造方法。 子类构造方法执行体中既没有super调用,也没有 this调用,系统将会在执行子类构造方法之前,隐式调 用父类无参数的构造方法。 例5.5 构造方法的调用顺序。 上机实践 1.请按如下要求定义两个A和B: 类A中定义一个int类型变量z(将其赋值为16)、一 个char类型变量x(将其赋值为65)和一个方法 myPrint(),该方法的功能是在屏幕上输出z的值和x的 值。 类B是类A的子类,其中定义了一个double类型的变 量y(将其赋值为16.0)和String类型的对象s(将其赋 值为java program!),还定义了两个方法myPrint() 和printAll(),方法myPrint()的功能是在屏幕上输出y和 s的值,方法printAll()的功能是分别调用父类和子类的 myPrint()方法。 编写应用程序,创建B类的对象b,调用printAll()方 法用来显示z、x、y、s的值。 上机实践 2.阅读下面程序,回答问题。 public class A public static void main(String args) A a=new A(); A() System.out.println(“A”); A(int i) this(); System.out.println(“AA”); class B extends A B() super(); System.out.println(“B”); B(int i) super(i); System.out.println(“BB”); 上机实践 (1)程序输出的结果是什么? (2)若将main()方法中的语句改为:B b=new B(),程序 输出的结果是什么? (3)若将main()方法中的语句改为:B b=new B(1),程 序输出的结果是什么? 5.2 多态性 多态机制是面向对象技术的精华之一,它是建立在继承 基础之上的。所谓多态(polymorphism),子类的对象可以 代替父类的对象使用。 思想基础 在类的继承中,子类在父类的基础上进行扩充和改造, 父类拥有的成员子类中都有,因而可以认为子类比父类的功 能强,或者说子类的对象应该比父类的对象功能强,因而子 类的对象应可以替代父类的对象被使用。 例5.6 多态性使用举例1 源文件:Person.java、Student.java 5.2 多态性 public class Test public static void main(String args) Person p=new Student(); / System.out.println(p.getInfo(); 变量p声明为父类Person的类型,但实 际指向的却是子类Student类型的对象 5.2 多态性 一个对象只能属于一种确定的数据类型,该类型自 对象创建直至销毁不能改变。 一个引用类型变量可能引用(指向)多种不同类型 的对象既可以引用其声明类型的对象,也可以引用 其声明类型的子类的对象。 Object o=new String(“hello”); Person p1=new String(“hello”); Student s=new Person(); Object是所有类的父类 Person类和String类之间 不存在继承关系 子类变量不能引用父类对象 注意:由于父类对象未包含子类中添加的成员,因而功 能较弱,也就无法替代子类对象使用。p.getSchool() 5.2 多态性 例5.7 多态性使用举例2 public class Test public void show(Person p) System.out.println(p.getInfo(); public static void main(String args) Person p=new Person(); Student s=new Student(); Test t=new Test(); t.show(p); t.show(s); 方法的形参声明为Person类型 调用时实参既可以是Person类型 ,也可以是其子类Student类型 注意:show方法既可以处理Person类型的数据,也可以 处理Student类型的数据,乃至未来定义的任何Person子 类类型的数据,这样就不必为相关的每一种类型单独声 明一个处理方法,提高了代码的通用性。 5.2 多态性 在多态情况下,一个引用类型的变量如果声明为父类的 类型,但实际引用的是子类对象,则该变量就不能访问子类 中添加的属性和方法。可是如果此时调用的是父类中声明过 ,且在子类中又重写过的方法,情况又将如何? 例5.8 多态性示例3 name、price setName() getName() setPrice() getPrice() show() Book类 author setAuthor() getAuthor() show() Novel类 5.2 多态性 public class TestNovel public void process(Book b) b.show(); public static void main(String args) TestNovel t=new TestNovel(); Book b=new Book(); b.setName(“English Language”); b.setPrice(34); cess(b);/方法体中的b.show()输出结果? B既可引用Book类对象,又可引用Novel对象,则这时调用的 到底是Book类中的show方法还是Novel类中的show方法? 5.2 多态性 若增加如下代码: Novel n=new Novel(); n.setName(“the Great Wall”); n.setPrice(46.7); n.setAuthor(“Zhangsan”); cess(n); /方法体中的b.show()的输出结果? 结论:系统依据运行时对象的真正类型来确定具体调用哪 一个方法父类对象调用父类中的show方法,子类对象调 用子类中重写过的show方法。 5.2 多态性 对象造型 在多态的情况下,由于对象以其父类的身份出现,对子 类中新添加成员的访问受到限制,有时我们可能需要恢复一 个对象的本来面目造型(Casting),以发挥其全部潜力。 例5.9 多态性示例4。 Public class Test public void cast(Person p) /System.out.println(p.getSchool(); 非法 Student st=(Student)p; /造型 System.out.println(st.getSchool(); /正确 在main方法中:Test t=new Test(); Student s=new Student(); s.setSchool(“THU”); t.cast(s); 5.2 多态性 所谓的造型其实就是引用类型数据值之间的强制类型转换 。 注意: 从子类到父类的类型转换可以自动进行; 在多态的情况下,从父类到子类转换必须通过造型 (强制类型转换)实现; 无继承关系的引用类型间的转换是非法的。 String str=“hello,world”;Person p=(Person)str; 5.2 多态性 特别强调:从父类到子类的造型也不是都能成功只有当对 象的真正类型本就是子类类型,只是在多态的情况下,被一 个声明为父类类型的变量所引用,才可以进行造型处理,即 再恢复该对象的本来面目,而一个对象如果其真正类型就是 父类类型,是不能被造型为子类类型的。 例如,Person p1=new Person(); Student stu=(Student)p1; /编译编译 没错错,但运行出错错 5.2 多态性 instanceof运算符 再看例5.9中Test类的cast方法: public void cast(Person p) /System.out.println(p.getSchool(); 非法 Student st=(Student)p; /造型 System.out.println(st.getSchool(); /正确 调用方法时如果实参是子类Student的对象,则造型是正 确的,若实参是父类Person的对象,则造型失败! if(p instanceof Student) Student st=(Student)p; st.getSchool(); 5.2 多态性 运算符instanceof用于检测一个对象的真正类型。 格式: instanceof 功能:如果instanceof操作符左侧的变量当前时刻所 引用对象的真正类型是其右侧给出的类型、或是其子类 ,则整个表达式结果为true,否则结果为false。 例5.10 多态性示例5。在Test类中的cast方法可改写 为: public void cast(Person p) if(p instanceof Graduate) . else if(p instanceof Student) Person Student Graduate 上机实践 1.定义类A和类B如下: class A float var=1.1f; float method()return var; class B extends A float var=2.2; float method() return var; (1)类A和类B是什么关系? (2)类A和类B中都定义了变量var和 方法method(),这种现象称为什么? (3)若定义A a=new A(),则a.var和a.method()的值是多少? (4)若定义A a=new B(),则a.var和a.method()的值是多少? (5)若定义A a=new B(),B b=(B)a,则b.var和b.method()的 值是多少? 5.3 静态初始化块 Java使用构造方法来对单个对象进行初始化操作。与构 造方法作用非常类似的是初始化块,它也可以对对象进行初 始化操作。 使用初始化块 初始化块是Java类里可以出现的第四种成员。语法格式 : class 类名 修饰符 /初始化块的可执行代码 初始化块 一个类里可以有多个初始化块; 相同类型的初始化块之间有顺序,前面定义的 初始化块先执行,后面定义的初始化块后执行 。 只能是static, 静态初始化块 可以定义局部变量、调用其他对象 的方法、使用分支、循环语句等 5.3 静态初始化块 例5.7 初始化块的使用。 分析: 当创建Java对象时,系统总是先调用该类里定义的 初始化块; 如果一个类里定义了两个普通初始化块,则前面定 义的初始化块先执行,后面定义的初始化块后执行。 初始化块虽然也是Java类里的一种成员,但它没有 名字,也就没有标识,因此无法通过类、对象来调用 初始化块; 初始化块只能在创建对象时自动执行而且在执行构 造方法之前执行。 5.3 静态初始化块 例5.8 初始化块的使用。 注意:初始块和声明实例属性时所指定的初始值都是该实例 的初始化代码,它们的执行顺序与源程序中排列顺序相同。 初始化块和构造方法的不同:初始化块是一段固定的执 行代码,它不能接受任何参数。因此初始化块对同一个类内 的属性所进行的初始化处理完全相同。 用法:如果多个构造方法里有相同的初始化代码,这些 代码无需接受参数,那就可以把他们放在初始化块中定义。 能更好的提高初始化块的复用,提高整个应用的可维护性。 创建一个Java对象时,不仅会执行该类的初始化块和构 造方法,系统会先执行其父类的初始化块和构造方法。 5.3 静态初始化块 静态初始化块 如果定义初始化块时使用了static修饰符,则这个初始化 块就变成了静态初始化块,也被称为类初始化块。 静态初始化块是类相关的,系统将在类初始化阶段 执行静态初始化块,而不是在创建对象时才执行,因 此静态初始块总是比普通初始化块先执行。 静态初始块属于类的静态成员,用于对类属性执行 初始化处理,不能对实例属性进行初始化处理。 系统在类初始化阶段执行静态初始化时,不仅会执 行本类的静态初始化块,还会一直上溯到Object类( 如果它包含静态初始化块)。经过这个过程,才完成 了对类的初始化过程。 5.3 静态初始化块 例5.9 写出程序的运行结果。 第一次创建一个Leaf对象时,系统中不存在Leaf类 ,因此需要先加载类并初始化,初始化Leaf类时先执 行顶层父类的静态初始化块,然后执行其直接父类的 静态初始化块,最后才执行Leaf本身的静态初始块。 每次创建一个Leaf对象时,都需要执行最顶层父类 的初始化块、构造方法,然后执行父类的初始化块、 构造方法最后执行Leaf类的初始化块和构造方法。 例5.10 静态初始化块的使用。 注意:静态初始块和声明静态属性时所指定的初始值都是该 类的初始化代码,它们的执行顺序与源程序中排列顺序相同 5.5 final修饰符 final关键字可用于修饰类、变量和方法,用于表示它修 饰的类、变量和方法不可改变。 final变量 final修饰变量时,表示该变量一旦获得了初始值之后就 不可被改变,final既可修饰成员变量(包括类变量和实例变 量),也可以修饰局部变量、形参。 final修饰成员变量 类变量: 成员变量 实例变量: 当类初始化时,系统会为类变量 分配内存,并赋默认值。 当创建对象时,系统会为该对象的 实例属性分配内存,并赋默认值。 5.5 final修饰符 final修饰的类变量、实例变量能指定初始值的地方如下 : 类变量:静态初始化块或声明该属性时指定初始 值。 实例变量:非静态初始化块、声明该属性时或构 造方法中指定初始值。 例5.12 编写程序,演示final修饰成员变量的用法。 注意:实例属性不能在静态初始化块中指定初始值,因为静态 初始化块是静态成员,不可访问实例属性非静态成员;类属 性不能在普通初始化块中指定初始值,因为类属性在类初始化 阶段已经被初始化了,普通初始化块不能对其重新赋值。 5.5 final修饰符 例5.13 final成员的使用示例。 public class Test final int age; System.out.println(age);/编译出错 age=6; System.out.println(age); public static void main(String args) new Test(); 注意:如果打算在构造方法、初始化块中对final成员 变量进行初始化,则不要在初始化之前就访问成员变 量的值。 5.5 final修饰符 final修饰局部变量 使用final修饰局部变量: 可以在定义时指定默认值,则 后面代码中不能再对该变量赋值。 如果在定义时没有指定默认值 ,则可在后面代码中对该final变量赋初始值 ,但只能一次,不能重复赋值。 例5.14 编写程序,演示final修饰局部变量、形参的 情形。 注意:test方法的形参用final修饰,则该形参由系 统根据传入的参数来完成初始化。 5.5 final修饰符 final修饰基本类型和引用类型变量的区别 当用final修饰基 本类型变量时, 不能对基本类型 变量重新赋值, 即基本类型变量 的值不能被改变 区别 引用类型变量保 存的是一个引用 ,final只保证这 个引用(地址) 不会改变,即一 直引用同一个对 象,但这个对象 可以发生改变。 例5.15 编写程序,演示 final修饰基本类型和引 用类型变量的区别。 5.5 final修饰符 final方法 final修饰的方法不可被重写,如果出于某些原因,不希 望子类重写父类的某个方法,则可以使用final修饰该方法。 例5.16 final方法举例。 public class TestFinalMethod public final void test() class Sub extends TestFinalMethod public void test() 出现编译错误 final修饰的方法仅仅是 不能被重写,并不是不 能被重载。 5.5 final修饰符 final类 final修饰的类不可有子类。例如,java.lang.Math类就是 一个final类,它不可以有子类。 例5.17 编写程序,演示final修饰的类不可被继承。 public final class FinalClass /类中成员 class Sub extends FinalClass 将出现编译错误 5.6 抽象类 抽象方法 基类中定义的方法,有时候只有在派生类中才能写出方法 体。例如, Shape TwoDimensionalShapeThreeDimensionalShape RectangleCircleEllipseCubeSphereCylinder 需定义方法area()计算面积 ,能写出合适的方法体? 5.6 抽象类 Java中,这种没有方法体的方法称为抽象方法。 抽象方法声明格式: 修饰符 abstract 返回值类型 方法名(形式参数表); 抽象方法的特点 抽象方法的返回值类型前有关键字abstract; 抽象方法没有方法体; 抽象方法的定义是一行单独语句,以分号结束; 在抽象方法声明中使用static修饰符是错误的。 例如,public abstract double area(); 5.6 抽象类 抽象类 类中如果定义了抽象方法,这个类必须定义为抽象类。 public abstract class 类名 /类体(属性、非抽象方法、抽象方法、构造方法) /类体(初始化块、内部类、枚举类) 抽象类不能创建自己的对象,使用new创建抽象类对 象将产生错误。 子类继承抽象类时,应该覆盖抽象类中的所有抽象方 法,否则子类也必须定义为抽象类。 5.6 抽象类 注意 含有抽象方法的类(包括直接定义了一个抽象方法; 继承了一个抽象父类,但没有完全实现父类包含的抽象 方法)只能被定义成抽象类。但抽象类中却并一定包含 抽象方法。 抽象方法和空方法体的方法不是同一个概念 public abstract void test(); public void test() 是一个抽象方法,它根本没有方法体 ,即方法定义后面没有一对花括号 一个普通方法,定义了方法体,只是方法体为 空,因此这个方法不可以使用abstract来修饰 5.6 抽象类 例5.18 抽象类示例。 public abstract class Shape public abstract double calcArea(); public Shape() public Shape(String name) System.out.println(name+ “ Shape Created“); public String toString() System.out.println(“this is Shape!”); 抽象方法 构造方法不用于创建Shape 对象,而是用于被子类调用 抽象类,不能实例化的 5.6 抽象类 public class Circle extends Shape public float r; private final float PI=3.14; public Circle(String name,float r) super(name); this.r=r; public float calcArea() return PI*r*r; 子类Circle,必须重写Shape类中的抽 象方法 ,否则Circle就是一个抽象类 5.6 抽象类 注意 final和abstract永远不能同时使用。 abstract不能用于修饰属性,不能用于修饰局部变量 ,即没有抽象变量、没有抽象属性等说法;abstract也 不能用于修饰构造方法,没有抽象构造方法。抽象类里 定义的构造方法只能是普通构造方法。 static和abstract不能同时修饰某个方法,即没有所 谓的类抽象方法。 abstract关键字修饰的方法必须被其子类重写才有意 义,否则这个方法将永远不会有方法体,因此abstract 方法不能定义为private访问权限。 5.6 抽象类 抽象类的作用 代码重用子类可以重用抽象父类中的属性和非 抽象方法; 规划抽象类中通过定义抽象方法规划了其所有 子类必须要实现的功能,或者说指定了其子类对象与 外界的交互界面,因为抽象方法的方法头部分已经规 定了该方法将来被子类对象调用的格式。 模板模式的设计 5.6 抽象类 模板模式:抽象类作为多个子类的通用模板,子类 在抽象类的基础上扩展、改造,但子类总体上会保留 抽象类的行为方式。 抽象类不能实例化,但抽象类可作为变量的类型和 方法形参类型,可将抽象类子类的对象赋给该变量或 做方法的实参。例如, Shape s=new Rectangle(); public static String ShowShapinfo(Shape item) if(item instanceof Rectangle) Rectangle r=(Rectangle)item; /其他代码 5.7 接口 接口是另一种定义数据类型的方式。它和类非常相似的 。 相同之处:都有成员变量和成员方法 也可以形成继承关系 不同之处:接口中的属性都是常量(final) 接口中的方法是抽象方法(没有方法 体) 引入接口的原因:Java只支持单重继承,每个类只能有一个 超类。但实际应用中有时候需要多重继承使用接口,一 个类可以实现多个接口。 接口的概念 类比:计算机的USB口 5.7 接口 接口的定义 public interface 接口名 extends 父接口1,父接口2, publicstaticfinal 数据类型 属性名=常量值; public abstract 返回值类型 方法名(形参表); 表示可以被不同包中的类或接口 使用,缺省时具有包内可访问性 interface关键字表示接口任意有效标识符 接口支持多继承,多个父接口之间用逗号分隔 接口的属性必须用public static final修饰,是系统默认 的,可部分省略或全部省略,但一般都写出final。 int MAX_SIZE = 50; 等价于 public static final int MAX_SIZE = 50; 接口的方法默认为public abstract,一般不写修饰符, 可省略接口中的方法都是抽象方法。 5.7 接口 例5.19 接口的定义。 public interface Figure final double pi=3.14; abstract void area(); 实现接口 接口定义后不能直接创建对象,必须由类实现接口后创 建类的对象。每个类只能继承一个基类,但可以实现多个接 口。类定义形式如下: 5.7 接口 public class 类名 extends 基类 implements 接口1, /类体 注意:类实现接口,就继承了接口中的所有成员 变量和成员方法。由于接口中的方法都是抽象的 ,因此实现接口的类必须重写这些方法。 public class Circle implements Figure double radius; public Circle(double r) radius=r; public void area() System.out.println(“圆的面积=“+pi*radius*radius); 可实现多个接口,多个 接口之间用逗号分隔 5.7 接口 注意: 实现接口中的抽象方法时,除去掉关键字abstract 外,方法头必须和接口定义中的方法头完全相同,并 且public修饰符不能省略。 如果类实现了多个接口,必须重写这些接口中的所 有方法。 接口不是类,不能使用new实例化接口,但可以声 明接口变量。接口变量可以指向一个实现了该接口的 类的对象,例如, Shape s=new Shape(); /错 Shape s=new Circle(); /对 5.7 接口 可以使用instanceof来判断对象是否实现了某个接 口。 虽然可以使用接口变量来引用实现接口类的对象, 但这种引用只能引用接口的成员,否则会发生编译错 误。 例如,class Rectangle implements Shape Shape s; s=new Circle(); s.area(); s=new Rectangle(); s.area(); 例5.21 接口的定义与实现。 调用的是同 一方法吗? 多态 强调:一个接口定义一个协定,实现接口的类必须遵守其协 定。接口最适合为不相关的类提供通用功能,利用接口提供 的方法,程序可以多态地处理这些完全不同的类的对象。 5.7 接口 接口的继承 接口具有多重继承的特点,即一个接口可以有多个父接 口。新的子接口继承所有父接口的全部方法和常量。接口继 承的格式为: public interface 子接口 extends 父接口1,父接口2, /静态属性; /抽象方法; 例5.20 接口的继承。 5.7 接口 接口和抽象类 接口和抽象类很像,它们都具有如下特征: 接口和抽象类都不能被实例化,它们都位于继承树 的顶端,用于被其他类实现和继承。 接口和抽象类都可以包含抽象方法,实现接口或继 承抽象类的普通子类都必须实现这些抽象方法。 区别 设计目的不同 接口体现的是一种规范,类似于整个系统的“ 总纲”,它制定了系统各模块应该遵循的标准 。因此一个系统中的接口不应该经常改变 抽象类作为多个子类的共同父类,体现的是模板式设计。抽象类可以被当成系 统实现过程中的中间产品,这个中间产品已经实现了部分功能,但这个产品还 不能当成最终产品,必须更进一步的完善,这种完善可能有几种不同方式。 5.7 接口 用法不同 (1)接口里只能包含抽象方法 (2)接口里不能定义静态方法 (3)接口里只能定义静态常量 属性 (4)接口不包含构造方法 (5)接口里不能包含初始化块 (6)一个类可以实现多个接口 (1)抽象类可以包含普通方法 。 (2)抽象类可以定义静态方法 (3)抽象类既包含普通属性, 也可以包含静态常量属性 (4)抽象类里构造方法不用于 创建对象,是让子类调用 (5)抽象类可以包含初始化块 (6)一个只能继承一个父类 上机实践 1.定义一个接口,接口中有三个抽象方法: long factorial(int m);/求参数的阶乘 long myPower(int m,int n);/求参数m的n次方 boolean findFactorSum(

温馨提示

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

评论

0/150

提交评论