这次我想深入探究以下java里类的继承机制。

      我们知道,继承是java设计里的一个失败的地方。高司令说过:如果让他重新设计java的话,他会把继承去掉。而java里继承到底怎么了,会这么不受人欢迎呢?

      我们知道,继承设计的初衷是为了代码复用。在C++里也确实做到了这一点,因为C++允许多重继承。特别是C++里的析构函数,申明为了virtual的时候可以多重复用,用起来也很舒服。

      那么为什么在java里继承就这么让人诟病呢?

第一:java里的类不能多重继承,如果一个类一旦继承了它的父类,那么它就别想再继承别的类。一个儿子只能有一个老爸,原本设计是没错的。可是在实际应用中,就会出现各种问题。

第二:java里有更好的接口,接口从本质上来说可以更好的代替继承。实现像C++里一样的宏定义的功能,把你想要的东西都抽象在接口里,让具体的类去实现这些功能。

      如果你去面试过,肯定遇到过不少考察java继承机制的题目,其中最显著的一个就是构造函数的调用和重写方法的调用。

这里我再强调一下重载和重写:

重载是同一个类里面相同方法名,不同参数类型或个数的方法。这也是C++类里面为什么出现函数模板的原因,就拿求和来说:

int add(int a,int b);
long add(long a,long b);
int main(){
}

因为求和可能是求int的和,也可能是求long的和,这个时候就出现了需求(我始终认为,一种东西的出现必定是因为对他的需求)

而重写呢,就是子类对父类里的方法的重改,就是他改写了父类的方法。伦理上看似不孝,而道理上是事物总是要不断发展的。这就像是社会的改革一样。

下面我来分析一下父类和子类的构造函数调用顺序:

      在内存机制中,父类和子类是占用同一块内存的,只不过子类在父类的基础上增加了自己的部分(包括数据成员和属性),这样一来就好理解了。子类是依附于父类的,先有父类再有子类。所以说一个子类对象的产生,必须先调用父类的构造函数产生一个父类实例,然后在这个实例基础上添加自己的部分。

      而实际的运行机制,也正是这样的。

      因为这样就很容易理解了,先调用父类的构造函数,再调用子类的构造函数。

      而对于父类和子类里重写的方法的调用,关键要看:子类到底是否产生,如果子类产生了,子类改写了父类的方法,看似父类和子类各自有一个方法,其实它们在内存模型里占用的是同一块内存,子类方法会覆盖父类方法。

我们看下面的程序:

class SuperStringTest {
SuperStringTest(){
System.out.println("Father is constructed.");
} public void test(){
System.out.println("Father is running.");
}
} public class StringTest extends SuperStringTest{
StringTest(){
System.out.println("Son is constructed.");
} public void test(){
System.out.println("Son is running.");
} public static void main(String[] args){
/*
SuperStringTest sst = new StringTest(); 此时,派生类的方法覆盖了基类的方法,基类的方法对派生类来说为不可见(有先像作用域),也就是派生类里的同名方法重新写了基类的同名方法。此时,对基类和派生类来说只有被派生类改写后的唯一的一个方法。所以,只能调用派生类的方法。 Father is constructed.
Son is constructed.
Son is running.
*/ /*
StringTest sst = new StringTest(); 解释同上面 Father is constructed.
Son is constructed.
Son is running.
*/ /*
SuperStringTest sst = new SuperStringTest(); 此时,基类所占的内存单元中并没有派生类的东西。所以,方法没被改写,调用父类的方法。 Father is constructed.
Father is running.
*/
sst.test();
}
}

java的继承机制的更多相关文章

  1. JAVA基础-继承机制

    需要掌握的知识点: 包的使用 继承时,子类如何覆盖父类方法(重写和重载) 继承时,构造方法的执行过程 JVM中子类如何实例化(先实例化父,再实例化子) super和this关键字 final关键字 包 ...

  2. Java 动态代理机制分析及扩展

    Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...

  3. 深入理解 Java 动态代理机制

    Java 有两种代理方式,一种是静态代理,另一种是动态代理.对于静态代理,其实就是通过依赖注入,对对象进行封装,不让外部知道实现的细节.很多 API 就是通过这种形式来封装的. 代理模式结构图(图片来 ...

  4. Java 动态代理机制分析及扩展--转

    http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...

  5. Java 动态代理机制分析及扩展,第 1 部分

    Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...

  6. Java面向对象程序设计--与C++对比说明:系列3(Java 继承机制)

    继承(inheritance)背后的核心思想是:       bonus = b;    }      } Java没有像C++那样提供多继承机制,但提供了接口机制,在后面我们将详细探究接口机制的实现 ...

  7. Javascript 构造函数原型继承机制

    我们先聊聊Js的历史,1994年Netscape公司发布了Navigator浏览器0.9班.这是历史上第一个比较成熟的网络浏览器.轰动一时.但是,这个版本的浏览器只能用来浏览,不具备交互功能,最主要的 ...

  8. java Proxy(代理机制)

    我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习 ...

  9. javascript继承机制的设计思想(ryf)

    我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...

随机推荐

  1. HDFS 搭建记录

    1. 三台服务: 172.17.0.62(namenode) 172.17.0.68(datanode) 172.17.0.76(datanode) /etc/hosts包含的内容: 三台都包含的域名 ...

  2. nutch-1.7-二次开发-Content中增加编码

    1 识别nutch-1.7的编码,完成 以前1.2是在 org.apache.nutch.parse.html.HtmlParser EncodingDetector detector = new E ...

  3. Hadoop 学习笔记 (十) MapReduce实现排序 全局变量

    一些疑问:1 全排序的话,最后的应该sortJob.setNumReduceTasks(1);2 如果多个reduce task都去修改 一个静态的 IntWritable ,IntWritable会 ...

  4. The type java.lang.String cannot be resolved. It is indirectly referenced from required .class files

    最近在做J2ME开发项目,配置环境一切OK,但是打开项目时某些文件提示: The type java.lang.String cannot be resolved. It is indirectly ...

  5. 如何用 React Native 创建一个iOS APP?

    诚然,React Native 结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用.在 JavaScript 中用 Reac ...

  6. windows 版Tomcat 7.0的配置

    http://hi.baidu.com/liguohei/item/d6ea23ff904f98753d198b24 测试成功,截图 ~~~~~~~~~~~~~~~ 一.安装JDK 1.7 1.添加环 ...

  7. linux shell中的特殊符号

    该内容,均来自此网址(http://www.92csz.com/study/linux/12.htm).在下只是把那些命令的截图给去了. 你在学习linux的过程中,也许你已经接触过某个特殊符号,例如 ...

  8. lambda -- Java 8 find first element by predicate

        Java 8 find first element by predicate up vote6down votefavorite I've just started playing with ...

  9. 使用LoadRunner对Web Services进行调用--Import Soap

    利用LoadRunner对Web Services进行测试时,通常有三种可供采用的方法: 在LoadRunner的Web Services虚拟用户协议中,[Add Service Call] 在Loa ...

  10. Win32中文件的操作

    1 文件的创建或打开 HANDLE CreateFile( LPCTSTR lpFileName, //文件路径和名称 DWORD dwDesiredAccess,      //访问方式,最常用的值 ...