`

Java语言接口与继承的本质

    博客分类:
  • Java
阅读更多

大多数人认为,接口的意义在于顶替多重继承。众所周知Java没有c++那样多重继承的机制,但是却能够实作多个接口。其实这样做是很牵强的,接口和继承是完全不同的东西,接口没有能力代替多重继承,也没有这个义务。接口的作用,一言以蔽之,就是标志类的类别(type of class)。把不同类型的类归于不同的接口,可以更好的管理他们。OO的精髓,我以为,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。(cowboy的名言是“抽象就是抽去像的部分”,看似调侃,实乃至理)。

  设计模式中最基础的是工厂模式(Factory),在我最近的一个很简单的应用中,我想尽量的让我的程序能够在多个数据库间移植,当然,这涉及很多问题,单是如何兼容不同DBMS的SQL就让人头痛。我们不妨先把问题简单化,只考虑如何连接不同的数据库。

  假设我有很多个类,分别是Mysql.java、SQLServer.java、Oracle.java、DB2.java,他们分别连接不同的数据库,统一返回一个Connection对象,并且都有一个close方法,用于关闭连接。只需要针对你的DBMS,选择不同的类,就可以用了,但是我的用户他会使用什么数据库?我不知道,我希望的是尽量少的修改代码,就能满足他的需要。我可以抽象如下接口:

  package org.bromon.test;
  public interface DB
  {
  java.sql.Connection openDB(String url,String user,String password);
  void close();
  }

  这个接口只定义两个方法,没有任何有实际意义的代码,具体的代码由实现这个接口的类来给出,比如Mysql.java:

  Package org.bromon.test;
  import java.sql.*;
  public class Mysql implements DB
  {
  private String url=”jdbc:mysql:localhost:3306/test”;
  private String user=”root”;
  private String password=””;
  private Connection conn;
  public Connection openDB(url,user,password)
  {
    //连接数据库的代码
  }

  public void close()
  {
    //关闭数据库
  }
  }

  类似的当然还有Oracle.java等等,接口DB给这些类归了个类,在应用程序中我们这样定义对象:

  org.bromon.test.DB myDB;

  使用myDB来操作数据库,就可以不用管实际上我所使用的是哪个类,这就是所谓的“开-闭”原则。但是问题在于接口是不能实例化的,myDB=new DB(),这样的代码是绝对错误的,我们只能myDB=new Mysql()或者myDB=new Oracle()。麻烦了,我还是需要指定具体实例化的是哪个类,用了接口跟没用一样。所以我们需要一个工厂:

  package org.bromon.test;
  public class DBFactory
  {
  public static DB Connection getConn()
  {
    Return(new Mysql());
  }
  }

  所以实例化的代码变成:myDB=DBFactory.getConn();

  这就是23种模式中最基础的普通工厂(Factory),工厂类负责具体实例化哪个类,而其他的程序逻辑都是针对DB这个接口进行操作,这就是“针对接口编程”。责任都被推卸给工厂类了,当然你也可以继续定义工厂接口,继续把责任上抛,这就演变成抽象工厂(Abstract Factory)。

  整个过程中接口不负责任何具体操作,其他的程序要连接数据库的话,只需要构造一个DB对象就OK,而不管工厂类如何变化。这就是接口的意义----抽象。

  继承的概念不用多说,很好理解。为什么要继承呢?因为你想重用代码?这绝对不是理由,继承的意义也在于抽象,而不是代码重用。如果对象A有一个run()方法,对象B也想有这个方法,所以有人就Class B extends A。这是不经大脑的做法。如果在B中实例化一个A,调用A的Run()方法,是不是可以达到同样的目的?如下:

  Class B
  {
  A a=new A();
  a.run();
  }

  这就是利用类的聚合来重用代码,是委派模式的雏形,是GoF一贯倡导的做法。

  那么继承的意义何在?其实这是历史原因造成的,最开始的OO语言只有继承,没有接口,所以只能以继承来实现抽象,请一定注意,继承的本意在于抽象,而非代码重用(虽然继承也有这个作用),这是很多Java烂书最严重的错误之一,它们所造成的阴影,我至今还没有完全摆脱,坏书害人啊,尤其是入门类的,流毒太大。什么时候应该使用继承?只在抽象类中使用,其他情况下尽量不使用。抽象类也是不能实例化的,它仅仅提供一个模版而已,这就很能说明问题。

  软件开发的万恶之源,一是重复代码而不是重用代码,二是烂用继承,尤以c++程序员为甚。Java中取缔多重继承,目的就是制止烂用继承,实是非常明智的做法,不过很多人都不理解。Java能够更好的体现设计,这是让我入迷的原因之一。

 

 

 

 

 

分享到:
评论

相关推荐

    2022年Java语言接口与继承的本质Java教程.docx

    2022年Java语言接口与继承的本质Java教程.docx

    JAVA入门-接口-语法

    Java语言接口与继承的本质 java 语法

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    在 java 语言中,Java 程序的基本单位是类,也就是说:一个 Java 程序是由多个类组成 的。定义一个类与定义一个数据类型是有区别的。在程序设计语言中,把定义数据类型的能 力作为一种很重要的能力来对待。在面向...

    瑜琅java学习笔记

    1 java起源 2 java语言概述 3 简单(基本)数据类型 4 运算符:java有四大类运算符:算数运算、位运算、关系运算和逻辑运算 5 程序控制语句 6 介绍类:类是java的核心和本质 7 深入方法和类:方法重载、参数传递和递归...

    Java语言面向对象上册教程

    14.13 继承的本质 121 14.14 多态性 121 15. 内部类/匿名内部类 135 16. 接口 144 16.1 为什么使用接口 144 16.2 接口的体验 148 16.3 接口语法 150 16.4 接口作为一种标准理解 151 16.5 面向接口编程 154

    JAVA基础课程讲义

    JAVA语言应用范围 18 第一个JAVA程序 18 JAVA开发环境搭建 18 一个典型的JAVA程序的编写和运行过程 19 第一个程序常见错误 20 第一个JAVA程序的总结和提升 20 常用Java开发工具 20 常用dos命令 21 本章笔试作业 21 ...

    java三大特性说明

    当在内存形成类的信息绑定的时候不会出现多个交叉点,结构的清晰程度较高.Java本身的运行效率较低,只能达到C语言的五分之一.Java语言舍弃效率的完美要求,换来学习和使用的简单. 属性的遮盖: Father f = new Son...

    JAVA面试题最全集

    50.JAVA语言如何进行异常处理,关键字:thorws,throw,try,catch,finally 51.Object类(或者其子类)的finalize()方法在什么情况下被调用? 52.一个“.java”原文件中是否可以包括多个类(不是内部类)? 53.掌握...

    Java核心技术 卷Ⅰ:基础知识 【中文】(第八版)

    对于C或 C++程序员来说,学习这一章的内容将会感觉一帆风顺,因为这些语言特性的语法本质上与C 语言相同。对于没有C语言程序设计背景,但使用过其他程序设计语言(Visual Basic)的程序 员,仔细地阅读这一章是非常...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...

    java jdk实列宝典 光盘源代码

    15 applet java可以编写两类程序,applications和applet,applications可以在控制台直接运行,与其他高级编程语言没有太大区别,而java的特色在于它具有编制小应用程序的功能,applet可以在internet上传输并在兼容...

    java 面试题 总结

    内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的...

    java课程设计报告-五子棋.doc

    Java 语言中,所有的类都是直接或间接的继承 java.lang.object类而得到的。被继承的类称为基类或父类,继承而的来的类成为子类 。子类继承基类的方法和属性,同时也可以修改基类的方法和属性 ,并增加自己新的属性和...

    java课程设计报告-五子棋(1).doc

    Java 语言中,所有的类都是直接或间接的继承 java.lang.object类而得到的。被继承的类称为基类或父类,继承而的来的类成为子类 。子类继承基类的方法和属性,同时也可以修改基类的方法和属性 ,并增加自己新的属性和...

    java课程设计报告-五子棋(2).doc

    Java 语言中,所有的类都是直接或间接的继承 java.lang.object类而得到的。被继承的类称为基类或父类,继承而的来的类成为子类 。子类继承基类的方法和属性,同时也可以修改基类的方法和属性 ,并增加自己新的属性和...

    基于JAVA超级玛丽游戏GUL 设计软件源码+WORD毕业论文文档.zip

    1.2 Java语言的特点 12 1.3 系统运行环境及开发软件: 12 1.4 可行性的分析 13 1.4.1 技术可行性 13 1.4.2 经济可行性 13 1.4.3 操作可行性 14 2、 需求分析 14 2.1 用户需求分析 14 2.2功能需求分析 15 2.3...

    Java面试宝典-经典

    45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗? 29 46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法...

Global site tag (gtag.js) - Google Analytics