抽象类与接口_第1页
抽象类与接口_第2页
抽象类与接口_第3页
抽象类与接口_第4页
抽象类与接口_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

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

文档简介

final 和 abstract 修饰符 1 final 修饰符 使用 final 修饰符可以修饰类的成员变量 类的成员方法和类 前面我们知道 用 final 修饰成员变量或局部变量 则该变量为常值变量 常量 一旦赋值便不能改变 一般与 static 组合定义类常量 也可以用 final 修饰成员方法 如果一个方法使用 final 修饰 则该方法不能在子类中 被覆盖 例如下面的代码会发生编译错误 class A final void method class B extends A void method final 关键字还可以修饰一个类 如果一个类使用 final 修饰 则该类就为最终类 final class 最终类是不能被继承的类 定义 final 类的格式为 final class ClassName 下面代码会发生编译错误 final class A class B extends A 有时为了安全的考虑 防止类被继承 可以在类的定义时使用 final 修饰符 在 Java 的类库中就有一些类声明为 final 类 如 Math 类和 String 类都是 final 类 它们都不能被继 承 声明为 final 的类隐含声明了其中的方法都为 final 方法 2 abstract 修饰符 在继承的层次结构中 随着一个个新子类的出现 类变得越来越专门 越具体 如果 从一个子类上溯到父类 类就变得更一般 更通用 类的设计应该保证父类和子类能够共 享特征 有时将一个类的设计得非常抽象 以至于它没有具体的实例 前面我们定义了圆的类 假设我们还要设计一个矩形 Rectangle 类和三角形 Triangle 类 这些类也需要定义求周长和面积的方法 它们具有共同的特征和行为 这时我们就可以设计一个更一般的类 比如几何形状 GeometricShape 类 来模拟圆 矩形 三角形等 在该类中定义那些求周长和面积的方法 然后在定义具体形状的类时继承该类并覆盖其中的方法 由于几何形状不能有一个具体的对象 因此方法的实现需要依赖于具体的形状 这些 方法就不能实现 因此要定义为抽象的方法 abstract method 抽象方法是只有方法的声明 没有方法的实现 定义抽象方法需要在方法前加上 abstract 修饰符 包含抽象方法的类应该定义为抽象类 abstract class 定义抽象类需要的类前加上 abstract 修饰符 下面定义的 GeometricShape 类即为抽象类 其中定义了两个抽象方法 程序 GeometricShape java public abstract class GeometricShape public int color public String name public GeometricShape color 0 name shape public GeometricShape int color String name this color color this name name public void setColor int color this color color public int getColor return color public void setName String name this name name public String getName return name public abstract double circum public abstract double area 抽象类不能被实例化 即不能生成抽象类的对象 如下列语句将会产生编译错误 GeometricShape gs new GeometricShape 可以创建抽象类的子类 抽象类的子类还可以是抽象类 只有非抽象的子类才能使用 new 创建该类的对象 在抽象类中可以定义构造方法 这些构造方法可以在子类的构造方 法中调用 在抽象类中可以定义非抽象的方法 抽象方法的作用是为所有子类提供一个统一的接口 对抽象方法只需声明 不需实现 即在声明后用一个分号 结束 而不需要用大括号 例如上面类定义的最后两行就声明了 两个抽象方法 抽象类中可以没有抽象方法 但仍然需要被子类继承 才能实例化 注意 因为 abstract 类必须被继承而 final 类不能被继承 所以 final 和 abstract 不能在定 义类时同时使用 下面重新定义了 Circle 类 它继承了 GeometricShape 类并实现了其中的抽象方法 程序 Circle java public class Circle extends GeometricShape public double radius public Circle this 1 0 Circle 255 public Circle double radius super 192 red this radius radius public Circle double radius String name int color super color name this radius radius public void setRadius double radius this radius radius public double getRadius return radius public double circum return 2 Math PI radius public double area return Math PI radius radius public boolean equals Circle circle return this radius circle getRadius public String toString return Circle radius radius 这里定义的 Circle 类不是抽象类 继承了抽象类 因此它必须实现抽象类中所有的方 法 否则该类也要被定义为抽象类 再定义一个 Rectangle 类继承 GeometricShape 类 程序 RectangleTest java class Rectangle extends GeometricShape double length double width public Rectangle this Rectangle 128 100 50 public Rectangle String name int color super name color public Rectangle double length double width super this length length this width width public Rectangle String name int color double length double width super name color this length length this width width public void setLength double length this length length public double getLength return length public double circum return 2 length 2 width public double area return length width public class RectangleTest public static void main String args Rectangle rect new Rectangle 200 100 System out println Name rect getName System out println Color rect getColor System out println The circumference rect circum System out println The area rect area GeometricShape 类及其子类的继承关系如图 1 所示 图 1 GeometricShape 类及其继承关系图 接口 Java 语言中所有的类都处于一个类层次结构中 除 Object 类以外 所有的类都只有一 个直接超类 即子类与超类之间是单继承的关系 而不允许多重继承 而现实问题类之间 的继承关系往往是多继承的关系 为了实现多重继承 Java 语言通过接口 interface 使 得处于不同层次 甚至互不相关的类具有相同的行为 接口是一个常量和方法的集合 这些方法只有定义没有实现 接口主要用来实现多重 继承 接口定义了一种可以被类层次中的任何类实现的行为的协议 1 定义接口 接口的定义与类的定义类似 包括接口声明和接口体两部分 1 接口声明接口声明 接口声明的一般格式如下 Object GeometricShape CircleRectangle Cylinder Triangle public interface InterfaceName extends SuperInterfaces public static final type name value public abstract returnType methodName paramlist throws ExceptionList 接口声明使用 interface 关键字 InterfaceName 为接口名 extends 表示该接口继承 扩展 了哪些接口 一个接口可以继承多个接口 如果接口使用 public 修饰 则该接口 可以被所有的类使用 否则接口只能被同一个包中的类使用 大括号内为接口体 接口体中包含常量定义和方法定义两部分 常量的定义可以缺省 修饰符 但系统会自动加上 public final static 属性 接口中的方法只有声明 没有实现 方法也可以缺省修饰符 缺省修饰符系统自动加上 public abstract 属性 接口中的所有方 法都是抽象的方法 因此 接口是比抽象类还抽象的类型 2 接口继承接口继承 一个接口可以继承一个或多个接口 例如 下面的代码定义了 3 个接口 其中 CCC 接 口继承了 AAA BBB 接口 是 AAA BBB 接口的子接口 程序 CCC java interface AAA int a 1 void showa interface BBB int b 2 void showb public interface CCC extends AAA BBB int c 3 void showc 编译该程序将产生 AAA class BBB class 和 CCC class 三个类文件 如果子接口中定义了和父接口中同名的变量和相同的方法 则父接口中的常量被隐藏 方法被覆盖 接口与抽象类的区别是 接口中的方法都是抽象方法 不能实现任何方法 而抽象类中可以有非抽象方 法 一个类可以实现多个接口 但只能有一个超类 接口不是类层次结构的一部分 不相关的类可以实现相同的接口 2 接口的实现 接口只能被类实现 类声明中用 implements 子句来表示实现接口 一般格式如下 public class ClassName implements InterfaceList Class Body 一个类可以实现多个接口 一个类实现多个接口时 在 implements 子句中指定要实现 的接口并用逗号分隔 如果实现接口的类不是 abstract 类 则在类的定义部分必须实现所 有接口中的所有抽象方法 即必须保证非 abstract 类中不能存在 abstract 方法 在这种情况下如果把接口理解成特殊的类 那么这个类利用接口实际上实现了多继承 一个类在实现某接口的抽象方法时 必须使用与接口完全相同的方法头 否则只是重 载一个新的方法而不是实现已有的抽象方法 接口的抽象方法的访问修饰符都是 public 修饰符 所以类在实现方法时 必须显式使 用 public 修饰符 否则编译器警告缩小了访问控制范围 下面程序中定义的 ABC 类实现 了 CCC 接口 程序 ABCTest java class ABC implements CCC int d 4 public void showa System out println a a public void showb System out println b b public void showc System out println c c public class ABCTest public static void main String args ABC abc new ABC abc showa abc showb abc showc 程序的输出结果为 a 1 b 2 c 3 3 接口类型的使用 接口可以作为一种引用类型使用 任何实现该接口的类的实例都可以存储在该接口类 型的变量中 Java 运行时系统确定该调用哪个类中的方法 请看下面程序 程序 5 20 InterTypeTest java public class InterTypeTest public static void main String args AAA a new ABC BBB b new ABC CCC c new ABC a showa b showb c showa 程序输出结果为 a 1 b 2 a 1 程序中创建了三个 ABC 类的对象 并分别赋给 AAA BBB 和 CCC 接口对象 在这三个 对象上可以调用接口本身定义的和继承的方法 如在接口对象 c 上可以调用 showa showb 和 showc 方法 而在接口对象 a 上就只能调用 showa 方法 clone 方法介绍 在 object 类中有个 clone 方法 它的作用是用来进行对象克隆的 但是该方法的访问 限定符是 protected 故在其他类中无法直接访问 需要通过实现 Cloneable 接口才能被调用 下面就演示如何调用该方法 现有需要被克隆的类 public class SuperCloneClass public String value 如果不实现 Cloneable 接口而是直接覆盖 clone 方法把其访问修饰符修改成 public 代码如 下 public class SuperCloneClass public String value public SuperCloneClass clone throws CloneNotSupportedException return SuperCloneClass super clone 下面程序将进行克隆的使用 public class CloneTest public static void main String args throws CloneNotSupportedException 创建源对象 SuperCloneClass sourceClass new SuperCloneClass sourceClass value clone is success 开始调用clone方法并把克隆后的对象给予另一个引用 SuperCloneClass cloneClass sourceClass clone System out println cloneClass value 结果如下 Exception in thread main java lang CloneNotSupportedException advancedpropertyofclass abstractandinterface clone OtherClass at java lang Object clone Native Method at advancedpropertyofclass abstractandinterface clone OtherClass clone O therClass java 9 at advancedpropertyofclass abstractandinterface clone CloneTest main Clo neTest java 10 由以上结果可知道 如果不实现 Cloneable 接口而是直接覆盖 clone 方法时将会出现一 个运行时异常java lang CloneNotSupportedException 那么我们实现了 Cloneable 接口将会怎样 代码修改如下 public class SuperCloneClass implements Cloneable public String value public SuperCloneClass clone throws CloneNotSupportedException return SuperCloneClass super clone 然后再次执行 CloneTest java 的代码 结果如下 clone is success 我们看到了正确的结果输出了 我们通过 Api 查看了 java lang Cloneable 这个接口 发 现这个接口中没有任何的数据和方法 也就是说它只定义了一个空的接口 但是不实现这个接 口就无法进行克隆 这样的接口我们称为标记型接口 java lang Cloneable 是我们学习的第 一个标记型接口 今后还将学习另一个标记型接口 java io Serializable 那么我们现在懂得如何克隆对象了 太好了 可以收工了 请等等 在上面的演示中如果你仔细看将会发现被克隆类中的数据类型是 String 而 String 类在 赋值的时候是特殊处理的很接近基本数据类型 如果是一个普通类型呢 结果将如何 请看以下代码 public class OtherClass public String name 添加一个普通的类 然后修改 SuperCloneClass java 为 public class SuperCloneClass implements Cloneable public String value public OtherClass other public SuperCloneClass clone throws CloneNotSupportedException return su SuperCloneClass super clone 测试类也修改为 public class CloneTest public static void main String args throws CloneNotSupportedException SuperCloneClass source new SuperCloneClass source value I am cloning source other new OtherClass 为里面的对象赋值 source other name success 开始调用克隆方法 SuperCloneClass cloneClass source clone System out printf cloneClass value s cloneClass other name s n cloneClass value cloneClass other name 结果如下 cloneClass value I am cloning cloneClass other name success 哈哈 成功了 结果输出一致 真的是这样的么 那么请把上面的代码修改成这样 public class CloneTest public static void main String args throws CloneNotSupportedException SuperCloneClass source new SuperCloneClass source value I am cloning source other new OtherClass 为里面的对象赋值 source other name success 开始调用克隆方法 SuperCloneClass cloneClass source clone System out printf cloneClass value s cloneClass other name s n cloneClass value cloneClass other name 修改 源中引用对象的值 source other name you fail 再次输出克隆对象中的值 System out printf cloneClass value s cloneClass other name s n cloneClass value cloneClass other name 结果如下 cloneClass value I am cloning cloneClass other name success cloneClass value I am cloning cloneClass other name you fail 看着这结果你发现了什么 克隆后的对象和源对象引用的 other 对象是同一个对象 也 就是说它的克隆只是克隆了对 other 对象的引用 而没有克隆 other 对象 那么要怎样才能做到 other 对象也自己克隆呢 只要把代码修改如下 public class OtherClass implements Cloneable public String name public OtherClass clone throws CloneNotSupportedException return OtherClass super clone public class SuperCloneClass implements Cloneable public String value public OtherClass other public SuperCloneClass clone throws CloneNotSupportedException SuperCloneClass su SuperCloneClass super clone 重点 调用other对象的克隆方法把自己克隆一个 su other other clone return su 这样再次执行的结果就正确了 自己试试看吧 枚举类型介绍 作业 20 下列程序有什么错误 abstract class AbstractIt abstract float getFloat public class AbstractTest extends AbstractIt private float f1 1 0f private float getFloat return f1 22 下面声明的方法中哪两个不能被子类覆盖 A final void methoda B void final methoda C

温馨提示

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

评论

0/150

提交评论