3.2. 继承与多态

一. Java中类和类之间的关系

1. 继承关系

继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。 在Java中继承关系通过关键字extends明确标识,在设计时一般没有争议性。在UML类图设计中,继承用一条带空心三角箭头的实线表示,从子类指向父类,或者子接口指向父接口。

image.png|275

2. 实现关系

实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。 在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。

image.png|177

3. 依赖关系

简单的理解,依赖就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。 比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖。表现在代码层面,为类B作为参数被类A在某个method方法中使用。在UML类图设计中,依赖关系用由类A指向类B的带箭头虚线表示。

image.png

4. 关联关系

关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。 在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。

image.png

5. 聚合关系

聚合是关联关系的一种特例,它体现的是整体与部分的关系,即has-a的关系。此时整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。 比如计算机与CPU、公司与员工的关系等,比如一个航母编队包括海空母舰、驱护舰艇、舰载飞机及核动力攻击潜艇等。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,聚合关系以空心菱形加实线箭头表示。

image.png

6. 组合关系

组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。

image.png

二. 继承

关于java语言当中的继承:

  • 1 继承是面向的对象三大特征之一,三大特征是封装、继承、多态。


  • 2 继承“基本”的作用是:代码复用。但是继承最“重要”的作用是:有了继承才有了以后的“方法覆盖”和“多态机制”


  • 3 继承语法格式:


[修饰符列表] class 类名 extends 父类名{
    类体 = 属性 + 方法
}
  • 4 java 语言当中的继承只支持单继承,一个类不同同时继承很多类,只能继承一个类。【在 C++中支持多继承】。


  • 5 关于继承中的一些术语:
    B 类继承 A 类,其中:
    A 类称为:父类、基类、超类、superclass
    B 类称为:子类、派生类、subclass


  • 6 在 Java 语言当中子类继承父类都继承那些数据?
    私有的不支持继承
    构造方法不支持继承
    其他数据都可以被继承


  • 7 虽然 java 语言当中只支持单继承,但是一个类也可以间接继承其他类,例如:


C extends B{
}
B extends A{
}
A extends T{
}
C类直接继承B类,但是C类间接继承T、A类。
  • 8 java语言中假设一个类没有显示的继承任何类,该类默认继承JavaSE库中提供的java.lang.Object类。java语言中任何一个类中都有Object类的特征

三. 方法覆盖

1. 方法覆盖又称方法重写(override官方、overwrite)

2. 什么时候使用方法覆盖?

当父类中的方法已经无法满足当前子类的业务需求,子类有必要将父类中继承过来的方法进行重新编写,这个编写过程称为方法重写/方法覆盖。

3. 什么条件满足之后会发生重写呢?

代码满足什么条件之后,就构成方法的覆盖呢?

  • 方法重写发生在具有继承关系的父子类之间
  • 返回值类型相同,方法名相同,形参列表相同
  • 访问权限不能更低,可以更高。
  • 抛出异常不能更多,可以更少

建议方法重写的时候尽量复制粘贴,容易导致没有产生覆盖。

注意

  • 私有方法不能继承,所以不能覆盖
  • 构造方法不能继承,所以不能覆盖
  • 静态方法不存在覆盖
  • 覆盖只针对方法,不谈属性

四. 多态

1. 基础语法

向上转型(upcasting)

子类型–>父类型  
又被称为:自动类型转换

向下转型(downcasting)

父类型–>子类型  
又被称为:强制类型转换。【需要加强制类型转换符】

无论是向上转型还是向下转型,两种类型之间必须要有继承关系。
没有继承关系,程序是无法编译通过的。

使用多态语法机制
1.Animal和Cat之间存在继承关系,Animal是父类,Cat是子类
2.Cat is a Animal
3.new  Cat()创建的对象的类型是Cat,a2这个引用的数据类型是Animal,可见它们进行了类型转换
子类型转化为父类型,称为向上转型,或者称为自动类型转换。
4.Java中允许这种语法:父类型引用指向子类型对象。

Aniaml a1 = new Animal();
Aniaml a2 = new Cat();

a1.move(); //动物在移动
a2.move();// 猫在走猫步
//a2.catchMouse();  //编译不通过,Animal类中没有catchMouse方法
//因为编译阶段编译器检查a2的类型是Animal类型,
//从Animal.class字节码文件当中查找catchMouse()方法,
//最终没有找到该方法,导致静态绑定失败,没有绑定成功,也就是说编译失败了。
  1. Java 程序永远都分为编译阶段和运行阶段
  2. 先分析编译阶段,在分析运行阶段,编译无法通过,根本是无法运行的。
  3. 编译阶段编译器检查 a 2 这个引用的数据类型为 Animal,由于 Animal. Class 字节码当中有 move () 方法,所以编译通过了。这个过程我们称为静态绑定,编译阶段绑定。只有静态绑定成功了才有后续的运行。
  4. 在程序运行阶段,JVM 堆内存当中真实创建的对象是 Cat 对象,那么以下程序在运行阶段一定会调用 Cat 对象的 move () 方法,此时发生了程序的动态绑定,运行阶段绑定。
  5. 无论是 Cat 类有没有重写 move 的方法,运行阶段一定调用的是 Cat 对象的 move 方法,因为底层真实对象就是 Cat 对象
  6. 父类型引用指向子类型对象这种机制导致程序存在编译阶段绑定和运行阶段绑定两种不同的形态/状态,这种机制可以称为一种多态语法机制。
Animal a3 = new Bird();
/**
* 1.以下程序编译是没有问题的,因为编译器检查到a3的数据类型是Animal
* Animal和Cat之间存在继承关系,并且Anima1是父类型,Cat是子类型,
*父类型转换成子类型叫做向下转型,语法合格。

* 2、程序虽然编译通过了,但是程序在运行阶段会出现异常,因为JVM雄内存
*当中真实存在的对象是Bi rd类型, Bi rd对象无法转换成Cat对象,因为两种
*类型之间不存在任何继承关系,此时出现了著名的异常:java.lang . ClassCastException
类型转换异常,这种异常总是在“向下转型"的时候会发生。
*/
Cat c3 = (Cat)a3;

怎么解决 ClassCastException异常呢?

使用instanceof运算符可以避免出现以上异常。

instanceof运算符怎么使用?

语法格式:

引用 instanceof 数据类型名

以上运算符的执行结果类型是布尔类型,结果可能是 true/false

关于运算结果 true/false:

假设:(a instanceof Animal)

True 表示:a 这个引用指向的对象是一个 Animal 类型 False 表示:a 这个引用指向的对象不是一个 Animal 类型。 Java 规范中要求:在进行强制类型转换之前,建议采用 instanceof 运算符进行判断,避免 ClassCastException 异常的发生。这是一种好习惯。

if (a3 instanceof Cat){ //a3是一个Cat类型的对象
    Cat c3 = (Cat)a3;
    c3.catchMouse();
    }else if(a3 instanceof Bird){//a3是一个Bird类型的对象
        Bird b2 = (Bird)a3;
        b2.fly();
    }

}

2. 多态在实际开发中的作用


    1. 降低耦合度【解耦合】,提高程序的扩展力【软件开发的一个很重要的目标】


    1. 能使用多态尽量使用多态

    1. 父类型引用指向子类型对象
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇