is-A,has-A(面向对象的继承关系)

715 阅读2分钟

在我们进行面向对象的程序设计的时候,有is-A和has-A两种重要的关系。is-A表示“是什么”,描述的是对象和类之间的继承赋值关系;has-A表示“有什么”,描述的是类与其成员(类的成员变量或成员函数)之间所能执行的“动作”。

例如,我们看下面的java代码:

class animal{              //定义一个animal的类
  public int age;
  public String name;
  public void eat(){;}     //{;}为空语句
}
class cat extends animal{   //定义一个cat类,并继承于animal
  pulic void run{;}
}
public class Demo{
  public static void main(String[] args){
  animal [] a=new cat[2];   //1.正确
  a[1]=new cat();           //2.正确
  a[1].run();               //3.编译错
  animal b=new cat();       //4.正确
  b=new animal();           //5.正确
  a[1]=new animal();        //6.编译对,运行错
}
}

我们来详细讲解一下1-6号代码语句:

1.定义一个animal类型的数组a,但是数组对象的类型是cat[]类型,所以每一个数组元素的类型都为cat型。

2.给a[1]赋值,正确。

3.因为a[1]的类型是animal类型,赋给他的值为cat类型,所以a[1]只能用animal和cat共有的方法。(这里的这个语句编译不能通过但是他能够通过运行,是不是觉得这句话很矛盾,我下一章会谈谈java中的栈和堆的存储方式以及编译和运行这两个模块的一些机理。)所以这个语句是错的,因为它违反了has-A的原理,编译器无法找到该对象的方法,报错。

4.定义一个animal类型的b,接收的是cat的类型。

5.b是animal类型,所以正确。

6.这个语句编译可以通过,但是运行就会出错。(这里和第三句语句有着相同的知识点,因为Java的new会在编译的时候不执行,程序运行的时候才执行。)所以等到程序执行的时候就会报错,因为前面已经把cat类型赋给a[1],所以a[1]此刻的类型为cat类型,这句话想把animal类型给a[1],系统当然会不接受,报错。