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

废话不多说,进入正题:

本人在上篇“故弄玄虚”,用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. [模拟] Codeforces - 1191C - Tokitsukaze and Discard Items

    Tokitsukaze and Discard Items time limit per test 1 second memory limit per test 256 megabytes input ...

  2. ASP.NET Core AutoWrapper 自定义响应输出

    前言 AutoWrapper是一个简单可自定义全局异常处理程序和ASP.NET Core API响应的包装.他使用ASP.NET Core middleware拦截传入的HTTP请求,并将最后的结果使 ...

  3. 详解十大经典机器学习算法——EM算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第14篇文章,我们来聊聊大名鼎鼎的EM算法. EM算法的英文全称是Expectation-maximization al ...

  4. 使用tensorflow实现cnn进行mnist识别

    第一个CNN代码,暂时对于CNN的BP还不熟悉.但是通过这个代码对于tensorflow的运行机制有了初步的理解 ''' softmax classifier for mnist created on ...

  5. IDEA+EasyCode实现代码生成

    IDEA+EasyCode实现代码生成 Easy Code介绍 EasyCode是基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml).只要是与数据 ...

  6. Supervisor 使用和进阶4 (Event 的使用)

    本文主要介绍 supervisor Event 的功能. supervisor 作为一个进程管理工具,在 3.0 版本之后,新增了 Event 的高级特性, 主要用于做(进程启动.退出.失败等)事件告 ...

  7. Azure SDK for Python Url

    Azure SDK for Python URL 明细表 AZURE_PUBLIC_CLOUD = Cloud( 'AzureCloud', endpoints=CloudEndpoints( man ...

  8. IE不支持sessionStorage问题

    IE8及以上版本是支持的,如果你的项目在IE8及以上打开报错: 那是因为:页面要放在服务器上才能有效!!!!!!!!!!!!!!!!!!!!!!!!

  9. stylus--安装及使用方法

    stylus介绍 Stylus 是一个CSS的预处理框架,2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,所以 Stylus 是一种新型语言,可以创建健壮的.动态的 ...

  10. Linux命令后面加 & 的作用

    在命令的后面加一个 & 的作用是,将这个任务放到后台执行.看下面的例子. 输入gedit回车,可以看到,打开了Linux的文本编辑器,但是命令窗口执行不了其他命令了,只有退出文本编辑器才能继续 ...