SCJP认证 第二章2.2继承、IS-A、HAS (2.1.0 继承)

目标:

5.5 编写代码,实现IS-A关系和/或HAS-A关系。

继承在Java中无处不在。可以断言,不使用继承,及时编译最微小的Java程序也几乎(几乎?) 是不可能的。为了探讨这一主题,我们将使用instanceof运算符。对于这个运算符,现在只需记住:如果被测试的引用变量是比较的类型,那么instanceof将返回true。以下代码:

将产生如下输出:

they're not equal

t1's an Object

 其中的equals()方法来自何处?引用变量t1是Test类型,而Test类中没哟uequals()方法。第二if测试询问t1使用为Object类的一个实例,由于确实如此(稍后将详细介绍),因此ig测试会成功。

 继续我们的话题。t1如何能够称为Object类型的一个实例,我们只是说它是说它是Test类型的吗?我们确信这里,你已经走在我们的前面,但它证明Java中的每个类都是Object类的子类(当然,Object类本身除外) 。换句话说,你曾经使用或编写过的每个类都继承自Object类。你可以使用用equals()方法、clone()方法,以及notify()、wait()等其他方法。无论何时创建一个都会自动继承Object类的所有方法。

为什么呢?比如考虑equals()方法。java的创建者正确地假定Java程序员非常普遍希望比较他们累的实例,以检验相等性。如果Object类没有equals()方法,则你以及所有的其他Java程序员都将不得不机子编写这样一个方法。一个equals()方法被继承了数十亿次。

对于考试,你只需要知道可以通过扩展类在Java中创建继承关系。理解继承的使用还有两个重要的理由:

  • 促进代码服用。
  • 使用多态性。 

让我们从服用开始。一种常见的设计方法是:创建类的相当一般化的一个版本,其目标是创建继承它的更为特殊化的子类。例如:

 

输出如下:

 displaying shape

moving game piece

 

继承的第二种(以及相关的) 用法是允许以多态方式访问你的类,多态性也是由接口提供的一种能力,但是将在稍后再介绍它。假定你有一个GameLauncher类,它想虚幻遍历一列不同类型的GameShape对象,并且在每个对象上调用display()方法。当你编写这个类时,你并不知道其他任何人将编写的每种可能的GameShape子类,但你确信自己不希望重新编写代码,仅仅是由于有人决定在6个月后腰构建一个Dice形状。

关于多态性(“许多形式”) 的美妙之处是:可以将GameShape的任何子类视作GameShape。换句话说,可以在你的GameLauncher类中编写代码,指出:”只要是继承自(扩展)“GameShape,那么并不在意对象的类型是什么。

摄像有两个特殊子类PlayerPiece和TilePiece,它们扩展了更加泛型的GameShape类:

现在设想测试类具有一个方法,它带有声明的GameShape变元类型,这意味着它可以获取任何类型的GameShape。换句话说,GameShape的任何子类都可以传递给具有GameShape类型的变元的方法。以下代码:

输出如下:

displaying shape

displaying shape

 

关键点在于,doShape()方法是用GameShape变元声明的,但可以向它传递GameShape的任何子类型(这里就是一个子类) 。然后,该方法可以调用GameShape的任何方法,而无需考虑传递给方法的对象实际运行时的类类型,尽管有这方面的暗示。doShapes()方法只知道对象是GameShape类型,因为这是参数的声明方式。使用声明为GameShape类型的引用变量——而不考虑该变量是方法参数、局部变量——意味着只能对它调用GameShape的方法。

能够在引用上调用的方法完全依赖于变量的声明类型,而不管该引用的实际对象是什么。这意味着本鞥使用GameShape变量调用(比如说) getAdjacent()方法,即使传入的对象是TilePiece类型也是如此(当探讨接口时,将再次看到一点)。

 

IS-A关系和HAS-A关系

 对于考试,要能够看懂代码,并判断是IS-A还是HAS-A关系。规则很简单,因此,这应该是几个几乎不需要动脑筋就能够正确回答的问题之一。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章