JavaSE面向对象

JavaSE面向对象,第1张

文章目录
  • 引入
  • 继承的语法
  • 继承中两个类的关系
  • 引用数据类型的类型转换
    • 转换的是什么
    • 转换的前提条件
    • 转换的具体情况
  • 继承的优缺点
  • 继承层次
    • Java单继承机制
    • 继承层次
  • protected访问权限
    • 回顾访问权限修饰符的四种访问级别
    • protected访问权限
    • 结论
    • protected访问权限存在的意义
  • 继承的限制

继承是整个Java面向对象的核心技术,没有继承就没有Java面向对象,也就没有Java语言。

 

引入

对于在多个类中被重复定义的成员,既然有重复,那就想复用它们。Java中对代码的直接复用通常依赖于方法,但是想要复用类的成员,显然用方法无法实现,那就必须使用Java中的继承机制。Java中的继承,本质上是对类的成员的复用。

 

继承的语法

Java在定义一个类时,可以显式地直接让它继承另一个类,这就是Java的继承机制,其语法为:

[访问权限修饰符] class 类名 extends 被继承的类{
	// 类体
}

语法解释:

  1. extends关键字表示继承。

  2. 被继承的类必须是已经存在的某个类。

  3. 被继承的类称之为“父类”,继承父类的类称之为“子类”。

  4. 继承后,子类会得到父类的所有成员。

    需要注意的是:这里的成员只考虑普通成员,静态成员实际上不能被继承,构造器也不能。

  5. 子类继承父类后,可以在得到父类成员的基础上再自定义自己的成员。所以从功能上来说,子类往往比父类更强大,至少不会比父类差。所以,这也正是Java中的继承使用“extends”关键字的含义:子类继承父类,实际上是子类“扩展”了父类。

  6. 父类中没有的东西,子类继承不来。

 

继承中两个类的关系

继承中,子类和父类是“is-a”关系,子类“is-a”父类,子类可以看成是一个父类,子类可以当成父类使用。

“is-a”关系的理解

  1. 从实际代码角度

    可以用父类引用指向子类对象,说明子类对象可以当成父类对象去使用,所以子类“is-a”父类。

  2. 从数据类型的定义的角度

    数据类型是:一组数据 + 基于数据的 *** 作

    引用数据类型是:成员变量的集合 + 成员方法的集合

    子类通过继承父类,得到了父类的所有成员,从数据类型上来说,子类就覆盖了父类的成员,具有了父类的功能,子类可以当作父类去使用,也就是子类“is-a”父类。

  3. 从直观的逻辑角度

    比如学生属于人类,猫属于动物。直接就能看出“is-a”关系。

    值得注意的是:这种方式只能应对常见和简单的场景,实际开发中很多时候没有直白的逻辑关系,就需要通过设计文档来了解相关信息。

反过来,父类和子类的关系

父类对于子类没有直接关系,子类往往要比父类功能更强大丰富,父类不能当作子类使用。

使用继承的原则

要使用继承语法,一定要充分考虑父子类是否具有“is-a”关系。虽然继承的本质是复用成员,但是不要单纯的为了复用成员而使用继承,没有“is-a”关系,就不应该使用继承。在实际开发中,需要认真分析程序中类的关系,写入文档,避免出现错误的继承。

 

引用数据类型的类型转换 转换的是什么

转换的是引用的数据类型,而对象的类型是不可能转换的。

 

转换的前提条件

前提条件是必须存在继承,而且类型转换必须发生在父子类关系中,如果不是继承关系的两个类发生类型转换,会导致编译报错。

这也反映出继承一个重要的优点:继承打破了引用数据类型的类型限制,有了继承以后,引用数据类型才出现了类型转换。

 

转换的具体情况

基本数据类型的类型转换

  • 自动类型转换: 指的是不需要写额外代码,编译器自动完成类型转换。是一种取值范围“小转大”的转换。
  • 强制类型转换: 指的是由程序员手动写代码,强制编译器完成类型转换。是一种取值范围“大转小”的转换。

引用数据类型的类型转换同样分为两大类:

  • 自动类型转换: 指的是不需要写额外代码,编译器自动完成类型转换。

    • 条件:子类引用转换成父类引用。
    • 特殊称呼:从继承的方向来说,子到父,属于“向上转型”。
    • 原因:子类“is-a”父类,子类可以当成父类使用。
  • 强制类型转换: 指的是由程序员手动写代码,强制编译器完成类型转换。

    • 条件:父类引用转换成子类引用。

    • 语法:

      强转后的引用的类名 对象名 = (强转后的引用的类名)被强转类型的引用名;
      
    • 特殊称呼:从继承的方向来说,父到子,属于“向下转型”。

    • 原因:绝大多数情况下,父类都不能当成子类使用。

 

继承的优缺点

优点

  1. 继承可以复用类的成员,减少代码冗余。
  2. 继承的出现,更有利于功能的扩展,提升了程序的可维护性,更好地应对需求变更。
  3. 继承的出现,对于Java的引用类型而言,弱化了类型的约束力,引用数据类型出现了数据类型转换的概念。这其实是Java实现面向对象第三个特征——多态的前提。

缺点

  1. 子类继承父类必须无条件的接收父类的所有成员,无法在继承时选择不继承某个成员。
  2. 父类中对成员进行修改,也会严格地体现到每一个子类中,无法选择具体在哪一个子类生效。

由继承的缺点可以引出——方法的重写

子类在继承父类方法时,不可能不继承父类成员方法,但是,子类可以通过某种手段修改父类方法的实现,这称之为方法的覆盖/重写(override)。

如果说继承是面向对象的核心,那么方法的重写就是继承的核心。

 

继承层次 Java单继承机制

Java中的一个类,在使用extends关键字直接继承某个类时,最多只能继承一个,不能使用extends关键字同时直接继承多个类。即一个类最多只能有一个“直接父类”。

像Java这种,只能由一个直接父类而不能有多个的设计,称之为“单重继承”或“单继承”。而像C++当中,一个类可以直接继承多个类,就称之为“多重继承”或“多继承”。

但Java中实际上有一些手段,可以实现真正意义上的多继承。

 

继承层次

Java中的一个类虽然只能有一个直接父类,但是直接父类还有直接父类,那么就会存在多个“间接父类”。

于是就有以下几个概念

  • 祖先类:处在继承顶层的类。

    Object类是Java所有类继承层次中顶层的祖先类,Java中的每个类,都直接或间接地继承了Object类。如果一个类没有直接使用extends关键字直接继承某个类,那么它就隐式继承Object类,Object类就是它的直接父类,隐式继承不用写出。

  • 继承层次:由某个祖先类派生出来的所有类的集合叫做继承层次(族谱)。

  • 继承链:从某一个子类开始,到其祖先类的路径。

继承层次中需要注意:

  1. 在一条继承链中,总称呼下游类是上游类的子类,不管隔了几层。没有孙子类或重孙子类的概念。
  2. 在一条继承链中,下游的类宗室继承上游类的所有成员,不管隔了几层。
  3. 在一条继承链中,下游类总可以看成一个上游类,存在“is-a”关系。
  4. 【重要】不在同一条继承链中的类,没有任何关系,Java中没有“兄弟姐妹”类的概念。因为一方面,子类可以自由扩展功能,另一方面,继承来的东西也是可以修改的。
  5. 【重要】不在同一条继承链中的类,引用数据类型的类型转换也是不能发生的。引用数据类型的转换一定是发生在同一条继承链中。
    • 同一条继承链中,从子到父,是向上转型,是自动类型转换。
    • 同一条继承链中,从父到子,是向下转型,是强制类型转换。
  6. 不能循环定义继承。比如A继承B,B继承C,再让C来继承A,这是不行的。
  7. 继承链理论上可以无限延伸下去,但是一般实际中不会使用到太多层的继承。

 

protected访问权限 回顾访问权限修饰符的四种访问级别
  1. private,私有的,最严格,自己类中才能访问。
  2. package-private,默认的,缺省的访问权限,同包下可用。
  3. protected,受保护的访问权限,在不同包包下的子类中可以访问。
  4. public,公共的,不同包下,随便访问。

注:宽松的访问权限级别,总是包含更严格的访问级别。

 

protected访问权限

在使用受保护的访问权限时,首先要看清楚这个受保护的成员的位置(包位置)

  1. 只要是同包下,随便访问。
  2. 不同包下,只要是非子类,都不能访问。
  3. 不同包下的子类,这是我们关注的重点。

受保护的成员在不同包的子类中的访问情况:

可以访问,但是只能在子类中创建子类自身对象,然后访问子类从父类中继承过来的受保护成员,其他方式皆不可行。

 

结论

protected修饰的成员,在同类、同包下可以任意访问;如果是非同包下,则必须是在子类中,且必须是创建子类自身对象,才可以访问它继承自父类的protected成员,其他方式创建对象都不可以访问。

 

protected访问权限存在的意义

由于继承机制的存在,如果类中的某个成员,非常有价值,我们希望这个成员总是被子类使用,但又不会被滥用,使用protected修访问权限就能达到这样的目的。

被protected修饰的成员,在不同包下能够保证该成员能且只能被子类自身所使用,这样就充分保证了子类拥有对自己继承的protected成员最大的权限,在子类中,可以重写从父类继承过来的方法的访问权限和方法体(注意继承的变量是不存在重写的)。

 

继承的限制
  1. 父类中的私有成员,能不能被子类继承

    继承了,但是没有访问权限,导致子类无法直接访问父类中的私有成员。可以间接的在父类中写一个有访问权限的Getter方法去访问它,子类继承这个Getter就能够访问继承过来的私有成员了。

  2. 父类中的构造器,能不能被子类继承

    构造器是不能被继承的。

  3. 父类中的静态成员,能不能被子类继承

    静态成员不考虑继承,也不是继承。代码中可以用“子类类名.”访问父类静态成员,不过是父子类共用了父类的静态成员。静态成员永远属于类,可以被子类共用,但这不是继承。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/800564.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-07
下一篇 2022-05-07

发表评论

登录后才能评论

评论列表(0条)

保存