大多数人认为,接口的意义在于顶替多重继承。众所周知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能够更好的体现设计,这是让我入迷的原因之一

转载于:https://blog.51cto.com/cfkjava/927000

Java的接口与继承相关推荐

  1. 《Java程序设计》实验报告——Java的接口与继承

    浙江理工大学 <Java程序设计>  实验报告  20 19-20 20学年第 1学期      学  院 信息学院 班  级 计算机科学与技术18(3) 姓  名 申屠志刚 学  号 2 ...

  2. Java中接口如何继承接口呢?

    转自: Java中接口如何继承接口呢? 下文讲述一个接口继承另一个接口的实现方式,如下所示: 实现思路:接口继承接口,采用的extends关键字 例:   接口继承接口的示例分享 interface ...

  3. java中接口可以继承接口吗?

    java中接口可以继承接口吗? java中不允许类多重继承的主要原因是:如果A同时继承B和C,而假如B和C同时有一个d方法,A如何决定该继承哪一个呢? 但接口不存在这样的问题,接口中全都是抽象方法,继 ...

  4. java接口比继承优秀的地方,实现和继承的区别 java 实现接口和继承有什么区别...

    Java中继承和实现的区别 理论上:类只能单继承,接口可以多继承(接口应该叫实现): 实践上:小编们说类的继承一般继承的是事物的属性,如:姓名,年龄,性别 等,而接口的继承(或者说实现)一般是继承事物 ...

  5. Java的接口、继承与多态

    接口 java只支持单继承,即一个类只能有一个父类,因此需要接口来实现多重继承. 接口的定义 类和接口的区别:一个类通过继承接口的方式,从而来继承接口的抽象方法.类描述对象的属性和方法,接口则包含类要 ...

  6. 【Java】接口与继承

    用接口实现多继承 在Java中一个子类只被允许继承一个父类,即只允许单继承.但一个类可以实现多个接口,通过实现多个接口的方式满足多继承的设计需求.如果多个接口中有相同的方法,由于它们都是抽象的,子类实 ...

  7. Java中接口的继承

    先说结论:Java接口可以通过extends关键字继承一个或多个接口.注意是extends而不是implements.赶时间的朋友看到这里就可以离开继续快乐敲代码了. 正确代码例如: public i ...

  8. java 一个接口可以继承多个接口吗

    接口是常量值和方法定义的集合.接口是一种特殊的抽象类. java类是单继承的.classB Extends classA java接口可以多继承.Interface3 Extends Interfac ...

  9. Java中接口可以继承多个接口

    接口是常量值和方法定义的集合.接口是一种特殊的抽象类. 一.我们回忆下接口与抽象类的区别: abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制.它们之间区 ...

最新文章

  1. IP 网络性能的度量标准
  2. 【uni-app】小程序实现微信在线聊天(私聊/群聊)
  3. maven项目中如何直接访问某一个页面_整一个自己的docker镜像
  4. Qt 模型视图编程的简单实例
  5. sql语句换行_Spark随笔|关于Bucket Table与SQL语句转换
  6. maven中设置代理服务器
  7. Linux下启动启动tomcat 服务器报错 The file is absent or does not have execute permission
  8. woff字体MIME类型配置
  9. sql azure 语法_将SQL工作负载迁移到Microsoft Azure:规划迁移
  10. 利用ICallbackEventHandler接口实现Ajax效果
  11. 雪碧图PHP,Webpack中雪碧图插件使用详解
  12. javascript开发中的封装模式(转)
  13. 《大型网站技术架构》笔记
  14. (20200108)matlab弹出对话框形式打开和读取指定文件,不用提前输入文件名——uigetfile
  15. 【数学建模】二手房房价影响因素分析(描述性统计+推断统计综合应用、线性回归预测分析)
  16. C:\Users\用户名\AppData\Roaming里面的文件可以删除吗?
  17. 抖音实战~搜索页面~扫描二维码
  18. JVAV学习小练习(一)之leetcode习题之接雨水
  19. 2021湖北技能高考文化综合成绩查询,2021年湖北省技能高考文化综合考试大纲.pdf...
  20. 2022:RadiAnt DICOM Viewer-PC+CD[U盘]

热门文章

  1. python输出回文字符串_程序,用于计算我们可以在Python中使用字符串字符进行的独特回文数...
  2. ios 滑动手势事件 与cell touchevent事件_深入浅出~手势操作原理分析
  3. 基于pyQt的按键响应程序,实现按下按键进行图片曝光(按下按钮,运行另一个曝光图片程序.py)
  4. 基于Mind+的NB-IOT自动获取时间和位置
  5. 计算机片段教学优秀教案,精彩教学片段100例—导入篇(1)
  6. ES6的Reflect对象
  7. 关于(我们流量表优化),分区表数据块过多,聚合又导致数据倾斜问题
  8. yii2 刷新缓存(刷新模型缓存)
  9. 数字图像处理-频域滤波-高通/低通滤波
  10. Ubuntu ./configure 半途终止 导致没有生成makefile文件 解决方法