• 公号-云原生程序员
    2018-06-02
        接口vs抽象类vs类

    1    支持多重继承:接口支持;抽象类不支持;类不支持;
        2    支持抽象函数:接口语义上支持;抽象类支持;类不支持;
        3    允许函数实现:接口不允许;抽象类支持;类允许;
        4    允许实例化:接口不允许;抽象类不允许;类允许;
        5    允许部分函数实现:接口不允许;抽象类允许;类不允许。
        6    定义的内容:接口中只能包括public函数以及public static final常量;抽象类与类均无任何限制。
        7    使用时机:当想要支持多重继承,或是为了定义一种类型请使用接口;当打算提供带有部分实现的“模板”类,而将一些功能需要延迟实现请使用抽象类;当你打算提供完整的具体实现请使用类。

    在实际项目开发过程,一方面是业务需求频繁,需要满足开闭原则,也就是小到一个模块,大到一个架构都需要有好的可扩展性;另外一方面软件往往是团队协同开发的过程;由于团队成员水平参差不齐,这方面的坑不少。可以通过前期做好设计评审、code review等手段去提升代码质量。
    展开
     1
     88
  • ωǒ→无悔
    2018-06-02
    最后一个例子就是策略模式加工厂模式
    
     38
  • Woong
    2018-06-02
    class SlumDogVIPServiceProvider和RealVIPServiceProvider缺少implememts.

    作者回复: 汗,手敲搞出这种低级错误,非常感谢指出

    
     18
  • 雷霹雳的爸爸
    2018-06-02
    问题本身就是典型热身题,但是SOLID则是一块试金石,曾经真的以为是试金石,很多老江湖好像都不知道有这串缩写这么回事,单一职责一说就都是顾名思义,纯粹的同义反复,用自己解释自己跟没说差不多吧,里氏替换背后的契约设计基本规则就更甭说了,实际项目中能不违反的几乎凤毛麟角吧,除非对接口调用后就真的没有约束条件,连spring这货都崇尚什么都封装成非受控异常,可见这个点到底有多么不受人待见,最小知识原则也基本上就是任人践踏吧,要不全变函数接口也就都没必要反复换个名字了吧,依赖倒置还好,好歹有IoC帮衬着,但是helper和各种静态的tool被无数人个性的反复的造,同时拿着依赖查找的实用性来堵DIP的嘴,也就剩OCP,再违反就太不像话了吧,没关系最大的伤害就是无视啊,帅气的蓝精灵命名法的那一串类,依次加个方法还是客气的,直接加个version字段,把if…else请回来,总之这玩意一说我就陷入到吐槽情绪,但问题吐的是solid的槽,还是吐的不把solid当回事的槽,我自己也分不清了,这个问题真的好让人纠结
    
     13
  • 张立春
    2018-06-02
    我理解继承的根本目的是为了多态而不是为了复用,如果仅为了复用那就采用松耦合的组合。
    
     12
  • Seven4X
    2018-06-16
    对象和抽象类是is a 的关系,对象和接口是 like this的关系。
    从接口的命名一般是able ability后缀表示一种能力。
    比如大家都是程序员,如果拥有了编写java程序的能力,就可以说你是一个java程序员,同时你还如果你还会编写Go,也可以说你是一个go程序员。
    程序员就是对象实例,java编程能力就是接口,如果把java编程能力定义为抽象类,那还要实现Go能力接口才能同时具有两种语言能力的程序员,这表现的便是一个以java编程为主的程序员,同时具有编写go的能力。
    如果把java能力和go能力都定义为接口,表现的是:这是一个程序员他同时具有编写java和Go的能力。
    展开
    
     9
  • 小文同学
    2018-06-02
    hi,老师早上好。我是一家游戏公司的程序员,由于项目非常紧,所以很多技术写的代码,都非常乱。 我们的战斗系统中,之前的开发模式是在战斗逻辑里面嵌入并修改一些代码,以达到新技能的开发。这就是典型的以修改来达到需求。通过重构之后,技能的逻辑通过扩展的方式开发出来,可以通过继承技能的抽象类,来完成技能的开发。现在我们这部分的模块从最难处理变成最容易开发的了。

    作者回复: 听说过电信代码里有26个if-else……然后还有俩是重复的,少的时候无所谓,多了就是坑

     1
     9
  • 仙道
    2018-07-02
    两个接口里有一个同名方法,然后一个类实现了这两个接口,这怎么办呢
     3
     5
  • 云学
    2018-06-13
    其实有了函数式编程,绝大部分设计模式是多余的,记住,类的数量不要泛滥!!
    
     5
  • zc
    2018-07-12
    “这里你可以思考一个小问题,方法名称和参数一致,但是返回值不同,这种情况在 Java 代码中算是有效的重载吗? 答案是不是的,编译都会出错的。”

    编译出错是因为重载必须参数不一样,重载与返回值无关。感觉这里的表述有点问题……

    示例代码既不属于重写(同名同参同返回)也不属于重载(同名不同参)的范畴。
    
     4
  • bamboo
    2018-06-02
    老师最后举的例子应该就是把简单工厂模式修改为工厂方法模式。原来的违反了开闭选择,工厂方法模式刚好弥补了这个问题,倒是相应的系统中的类个数也成对的增加。设计模式没有最优的,只是特定场景下我们选择相对优良的模式来优化我们的逻辑。不知道是否正确,望老师指点迷津,谢谢老师。🙂

    作者回复: 嗯,也要避免过度设计,这个只是举例

    
     4
  • desmond
    2018-09-18
    最后一个示例,《代码大全》称作"表驱动法"。作者建议首先看这一章节,所以印象深刻
    
     3
  • 因缺思厅
    2019-06-03
    27个if else不是很简单的么,我现在维护项目中的一个类的代码,统计了一下有121个if,部分else我还没统计,代码4000多行,其中if-else主要在两个方法中,这两个方法有3500+行,总体上来看就是满屏的if-else。对于这样的代码,就不用想重构了。
     1
     2
  • 卡斯瓦德
    2018-07-14
    其实interface的deault可以通过结合抽象父类来实现吧,抽象父类实现接口方法,但是因为抽象所以不能实例化,而其子类拥有重写权,可以做到defualt的效果

    作者回复: 不错,只是:
    抽象类不能多继承;
    default method不会打破现有代码兼容性,lambda需要靠它来无缝增强collection之类API

     1
     2
  • 夏洛克的救赎
    2018-06-17
    但是,list 实际会被推断为“ArrayList < String >”

    ArrayList<String> list = new ArrayList<String>();

    不是很理解

    作者回复: 一般我们会写成:
    list<String> list=new ArrayList……;
    里氏代换,可以参考oo基础那章

    
     2
  • 小情绪
    2018-06-03
    杨老师,对于开头的:接口中没有非静态方法实现,也就是说要么是抽象方法,要么是静态方法。这句话我有疑问,java.util.List中default 方法不就是非静态方法的实现吗?还是我理解有误?

    作者回复: 前面就是个举例的回答,用来后面分析的,新版Java不准确了

    
     2
  • j.c.
    2018-06-02
    同种类型行为是通过不同方法调用还是不同实现类,哪个好点?
    
     2
  • Lpz
    2019-11-19
    重写是正方体与正方体之间的关系,重载是立方体与正方体之间的关系。
    
     1
  • clz1341521
    2018-08-05
    目前项目中很多代码工具类都是直接面向实现,才用static 方法。如日期类型转换,string操作等。这类方法有什么好的改进意见?
    
     1
  • Seven.Lin澤耿
    2018-07-30
    确实是的,目前还是许多程序员用面向对象语言书写面向过程的代码。实际工作中应该从业务流抽离出技术流,把类似if-else的处理封装,即使只是把代码抽离为方法;对于代码结构类似的(如,检查参数->业务处理->保存),应该更高一级的抽象,分离出业余模板(在JAVA表现就是一个接口或者抽象类);在每一次编程之前考虑其扩展性和松耦度,避免过度依赖导致后期难以维护。
    
     1
我们在线,来聊聊吧