接上篇博文——《详解 继承(上)—— 工具的抽象与分层》

废话不多说,进入正题:

本人在上篇“故弄玄虚”,用super();解决了问题,这是为什么呢?

答曰:子类中所有的构造方法默认都会访问父类中空参数的构造方法

(拓展:由于这个原理,我们今后所做的“工具类”都必须要带上无参构造)

那么,父类没有无参构造方法,子类怎么办?

解决父类没有无参构造的手段

  • 父类中添加一个无参的构造方法
  • 子类通过super去调用父类其他的带参的构造方法
  • 子类通过this去调用本类的其他构造方法 (本类其他构造也必须首先访问了父类构造)

那么,现在,本人来讲解一下super吧:

super:

super class 其实就是超类、基类、父类的意思。

在这里本人来提醒一点:

Object类 是 所有类的基类

super有两个严格要求:

  1. 只能出现在构造方法中;
  2. 如果有super(),则它必须是构造方法的第一条语句

    (所以,super() 和 this() 不能同时出现在同一个构造方法中)

而且,不论我们在 子类 中的构造方法是 无参 还是 带参,在默认情况下,JVM只调用基类的无参构造方法!

我们在上篇博文开头就提到过,我们在“继承”的过程中可以“择优继承”,那么,本人现在就来讲解下,如何“择优继承”:

我们实现这个结果的方法是:方法的覆盖

那么,现在我们对于方法的覆盖进行以下说明

(1)仅存在于有继承关系的类之间;

(2)子类的方法名名称参数个数类型,必须和被覆盖的父类保持一致;

(3)子类的返回值必须和被覆盖的父类保持一致;

(4)子类方法的修饰符不能“低于”被覆盖的分类方法;

(5)若违反了(2),则实质上是方法的重载,并非覆盖

(本人在这里只是为了使同学们能了解后面的代码,仅在这里浅谈覆盖,在本人后续博文中会对于方法的覆盖进行深度讲解)

现在我们来举一个简单有趣的例子:

我们先建立一个包 com.mec.about_override.demo,并在包下建立如下类:

Animal.java:

package com.mec.about_override.demo;

public class Animal {
private String name; public Animal(String name) {
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public void cry() {
System.out.println("动物的叫声!");
} }

Dog.java:

package com.mec.about_override.demo;

public class Dog extends Animal {
public Dog(String name) {
super(name);
} public void cry() {
System.out.println("汪汪");
}
}

Demo.java:

package com.mec.about_override.demo;

public class Demo {

	public static void main(String[] args) {
Animal animal =new Animal("动物");
animal.cry(); Dog dog = new Dog("二愣子");
dog.cry();
}
}

我们现在来编译一下,结果如下:

可以看出,我们在 Animal类中所编写的 cry() 方法被覆盖了!

多态:

现在,本人来介绍本篇博文的另一个知识点 —— 多态

多态 —— 某一个事物,在不同时刻表现出来的不同状态

首先,多态是有 条件的:

多态前提

  • 要有继承关系
  • 要有覆盖(方法重写)

    其实没有也是可以的,但是如果没有这个就没有意义
  • 要有父类引用指向子类对象

    形如:

    父 f = new 子();

接下来,本人来讲解一个非常有趣的 知识点:

基类 与 派生类 之间的 强制类型转换:

我们对上面的 Dog类 和 Demo类 做如下修改:

Dog.java:

package com.mec.about_override.demo;

public class Dog extends Animal {
public Dog(String name) {
super(name);
} public void cry() {
System.out.println("汪汪");
} public void dogAction() {
System.out.println("狗子快跑!");
}
}

Demo.java:

package com.mec.about_override.demo;

public class Demo {

	public static void main(String[] args) {
Animal animal =new Animal("动物");
animal.cry(); Dog dog = new Dog("二愣子");
dog.cry(); Animal otherAnimal = (Animal) dog;
dog.dogAction();
dog.cry();
} }

运行结果如下:



现在可能就有同学有疑问了这里的输出结果竟然是“汪汪”而不是“动物的叫声”!

这里对上述问题做出解释:

基类 与 派生类 之间的 强制类型转换 遵循如下原则

  1. 对象的类型 约束 对象所能引用成员方法,但是,不能更改 成员 和 方法 的本质内容;
  2. 对于方法,强转不能改变 其所 实际指向 的 代码 的首地址; 对象 的类型 决定 对象 所能引用的 对象和方法 的种类(即:Animal类型); 对象 所能调用的 成员 和 方法 取决于所申请空间的 对象和方法(即:Dog类型);
  3. 子类对象 可以被强转成 父类类型,但父类对象 不能被强转成 子类类型,因为父类对象中可能不存在子类类型的成员和方法

对于以上的现象,可能同学们在初学时会对子类与基类之间的关系感觉有点头晕。

别怕,在这里,本人还要介绍一个知识点,来辅助我们识别它们之间的关系:

多态中的成员访问特点

  • 成员变量 :

    编译看左边,运行看左边。
  • 构造方法 :

    创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
  • 成员方法 :

    编译看左边,运行看右边。
  • 静态方法 :

    编译看左边,运行看左边。

    (静态和类相关,算不上重写,所以,访问还是左边的)

那么,为什么要存在多态这个机制呢?

多态的好处

  1. 提高了代码的维护性(继承保证)
  2. 提高了代码的扩展性(由多态保证)

详解 继承(下)—— super关键字 与 多态的更多相关文章

  1. 菜鸟笔记 -- Chapter 6.4.2 详解继承

    6.4.2  详解继承 6.4.2.1  继承入门 继承使得程序架构具有一定的弹性,在程序中复用一些已经定义完善的类不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性.基本思想是基于某个父类 ...

  2. C#中的Attribute详解(下)

    原文地址:https://blog.csdn.net/xiaouncle/article/details/70229119 C#中的Attribute详解(下) 一.Attribute本质 从上篇里我 ...

  3. javac命令详解(下)

    摘自http://blog.csdn.net/hudashi/article/details/7058999 javac命令详解(下)                             -ver ...

  4. NPM使用详解(下)

    NPM使用详解(下) *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impo ...

  5. iOS 开发之照片框架详解之二 —— PhotoKit 详解(下)

    本文链接:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-three.html 这里接着前文<iOS ...

  6. 详解Linux下swig 3.0.12的手动安装过程

    详解Linux下swig 3.0.12的手动安装过程 首先 从http://www.linuxfromscratch.org/blfs/view/cvs/general/swig.html上下载swi ...

  7. 详解Linux下iptables中的DNAT与SNAT设置(转)

    详解Linux下iptables中的DNAT与SNAT设置 这篇文章主要介绍了Linux下iptables中的DNAT与SNAT设置,是Linux网络配置中的基础知识,需要的朋友可以参考下   原文连 ...

  8. Window下PHP三种运行方式图文详解,window下的php是不是单进程的?

    Window下PHP三种运行方式图文详解,window下的php是不是单进程的? PHP运行目前为止主要有三种方式: a.以模块加载的方式运行,初学者可能不容易理解,其实就是将PHP集成到Apache ...

  9. hadoop2.7之作业提交详解(下)

    接着作业提交详解(上)继续写:在上一篇(hadoop2.7之作业提交详解(上))中已经讲到了YARNRunner.submitJob() [WordCount.main() -> Job.wai ...

随机推荐

  1. php解析配置文件

    php解析配置文件 标签(空格分隔): php .ini格式 ![](https://img2020.cnblogs.com/blog/1458583/202003/1458583-202003301 ...

  2. OpenAI的GPT-2:用Python构建世界上最先进的文本生成器的简单指南

    介绍 "The world's best economies are directly linked to a culture of encouragement and positive f ...

  3. CNN更新换代!性能提升算力减半,还即插即用

    传统的卷积运算,要成为过去时了. Facebook和新加坡国立大学联手提出了新一代替代品:OctConv(Octave Convolution),效果惊艳,用起来还非常方便. OctConv就如同卷积 ...

  4. 命令行中运行Java字节码文件提示找不到或无法加载主类的问题

    测试类在命令行操作,编译通过,运行时,提示 错误: 找不到或无法加载主类 java类 package com.company.schoolExercise; public class test7_3_ ...

  5. ArrayList 扩容 和 Vector

    public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[siz ...

  6. MySql 分组函数

    #二.分组函数/*功能:用作统计使用,又称为聚合函数或统计函数或组函数 分类:sum 求和.avg 平均值.max 最大值 .min 最小值 .count 计算个数 特点:1.sum.avg一般用于处 ...

  7. 使用IDEA编写JDBC

    省去下载MySQL的过程,创建数据库demo 首先在下载的Java服务中将此jar包复制到项目中的一个空文件夹中 在当前工程下新建目录lib(名字可自定) 找到MySQL的Java服务的jar包 打开 ...

  8. 多线程学习笔记(五)---- 在JDK文档的使用

    1.前言 我们经常在JDK文档中见到一些类上的介绍说,该类是"安全的"."不安全"."效率高"."效率低"的词眼.这里, ...

  9. 掌握使用gitlab ci构建Android包的正确方式

    最近公司在做移动端的项目,自然而然的需要搭建打包的环境.本来计划用Jenkins的,但是发现在gitlab上创建完项目后,提示去配置pipeline,于是决定用gitlab去尝试下,毕竟我觉得Jenk ...

  10. Redis 笔记(五)—— HASH 常用命令

    添加和删除键值对的散列操作 命令 用例和描述 HMGET HMGET key-name key [key ...] —— 从散列里面获取一个或多个键的值 HMSET HMSET key-name ke ...