Java基础十四(继承)

继承


为什么要使用继承

代码演示描述多个事物。多个事物之间发现有共同的属性和行为。可以将相同的代码进行抽取,抽取出来后放在单独的类中,为了让类与类之间能有关系,需要使用Java中提供的继承这种机制。继承需要用到关键字extends。

继承的定义
从代码上而言:在我们描述若干个类的时候,发现这些类中有大部分相同的成员
所以就可以把这部分重复的内容抽取出来,用另外一个类描述,新的类就是父类 ,其他的就是子类,父类和子类之间的关系 继承关系 extends

从业务逻辑上而言:父类和子类之间必须是 is a 关系 , is a 同一种类

继承的特点

  • 类与类之间是 单继承
  • 接口与接口之间是 多继承
  • 继承之间是有传递性的 A->B->C

多继承虽然能使子类同时拥有多个父类的特征,但是其缺点也是很显著的,主要有两方面:

  • 如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量
  • 如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法

既然继承有传递性,那么在Java里面我们会有一个最终的父类Object类 ,它是任何一个类的最终父类产生出我们Java当中继承体系、异常体系、 IO体系、 Socket体系、集合体系。

定义继承需要注意
不要仅为了获取其他类中某个功能而去继承。
一旦有private 就不考虑继承
日常开发中小技巧
多层次继承出现的继承体系中,通常看父类中的功能,了解该体系的基本功能,建立子类对象即可使用该体系功能。

继承的好处

  1. 继承的出现提高了代码的复用性,提高软件开发效率。
  2. 继承的出现让类与类之间产生了关系,提供了多态的前提

子父类中成员变量的特点

了解了继承给我们带来的好处,提高了代码的复用性。继承让类与类或者说对象与对象之间产生了关系。当继承出现后,类的成员之间产生了那些变化呢?

成员变量

  • 如果子类父类中出现不同名的成员变量,这时的访问是没有任何问题
  • 父类中的成员变量是非私有的,子类中可以直接访问
  • 若父类中的成员变量私有了,子类是不能直接访问的
  • 父类中有成员变量(非私有) 子类有同名静态变量 ,那么访问子类静态的

当子父类中出现了同名成员变量时,在子类中若要访问父类中的成员变量,必须使用关键字super来完成。

super和this的用法相似,this:代表本类的对象引用,用于区分调用者。super:代表的父类内存空间,指向的是其父类(的字节码)空间,而不是父类的引用。子父类中同名的成员变量,这种情况开发中不用,因为父类一旦描述完成了属性,子类直接使用就可以了

子类找成员变量的顺序

局部->子类成员变量(堆)->子类静态变量(静态区)
->父类成员变量(非静态父类空间)->父类静态变量(静态区)


子父类中成员函数的特点

成员函数

  • 当在程序中通过对象调用方法时,会先在子类中查找有没有对应的方法
  • 若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法

成员方法特殊情况——覆盖
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为override重写、复写或者覆盖,当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。重写的意义?保留父类的函数声明(功能),子类对功能进行改进。

重写需要注意的细节问题

  1. 子类方法覆盖父类方法,必须要保证权限大于等于父类权限
  2. 静态只能覆盖静态,或者被静态覆盖,意思就是 静态函数不存在重写!
  3. 写法上稍微注意:必须一模一样:函数的返回值类型 函数名 参数列表都要一样

总结:当一个类是另一个类中的一种时,可以通过继承,来扩展功能,如果父类具备的功能内容需要子类特殊定义时,使用重写


子父类中静态变量和静态函数的特点

静态变量和成员变量一样,静态函数和成员函数一样。


子父类中构造函数的特点

在创建子类对象时,父类的构造函数会优先执行,因为子类中所有构造函数的第一行有默认的隐式super();语句,调用本类中的构造函数用this(实参列表)语句,调用父类中的构造函数用super(实参列表),对于super(参数列表)调用,前提是父类必须有相应的构造函数。

说this关键字的时候讲到this(…)也必须在第一句 冲突不? 不冲突,因为this(…)会转接到其他构造函数,其他的构造函数最终不会再转接回去,第一句只能是super(…)

为什么子类对象初始化都要访问父类中的构造函数?因为子类继承了父类的内容,所以创建对象时必须要先看父类是如何对内容进行初始化的。

当父类中没有空参数构造函数时,子类的构造函数必须有显示的super语句指定要访问的父类中的构造函数


final关键字

有些类在描述完之后,不想被继承,或者有些类在中的部分方法功能是固定的,子类不能重写。可是当子类继承了这些特殊类之后,就可以对其中的方法进行重写,为防止这样的情况发生,需要使用一个关键字final,final的意思为最终,不可变。
final是个修饰符,它可以修饰类,类的成员,以及局部变量。

  • final修饰变量 表示该变量所存储的数据的地址不可更改,且定义的时候必须有初始值

  • final修饰类 该类不能被继承,但是可以继承其他类

  • final修饰函数 该函数不能被重写,但父类中没有被final修饰函数,子类覆盖后可以加final

  • final修饰的引用类型变量,表示该引用变量的引用不能变,而不是引用所指的对象
    中的数据还是可以变化的

    什么时候用?看具体需求

发布了70 篇原创文章 · 获赞 56 · 访问量 1996

猜你喜欢

转载自blog.csdn.net/qq_43624033/article/details/103403038