• Java继承分析


    本文章观点结合《Java编程思想》、《设计模式之禅》、《大话设计模式》整理而成。站在巨人的肩旁上才能让我们看的更远。

    继承

    继承是Java编程中重要的一个特性,使用继承可以提高代码的重用性。文字总是显得过于苍白,下面是继承的关系图。

    关系图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qnAGJaue-1660013780412)(/Users/wuang/Pictures/03技术/typora-user-images/Java继承特点/image-20220807123309673.png)]

    优点

    • 提高代码的重用性,减少创建类的成本,当创建一个类之后,如果有一个类与其具有相似的功能,那么就不需要再创建一个新类。

    • 子类可以形似基类,但又和基类不同。有两种方式可以使子类和基类产生差异:
      1、第一种是直接在子类中添加新方法,当基类不能满足我们需求的时候,我们可以使用此方式来解决;

      2、第二种是改变现有基类的方法的行为,也就是Java中的覆盖。

      例如我们Android中自定义View中OnDraw()函数,TextView和ImageView虽然都继承了View,但分别在OnDraw()函数中做了不同的行为;

    • 提高代码的可扩展性。

    缺点

    • 继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法;
    • 增强了耦合性。当父类的常量、变量和方法被修改时,需要考虑子类的修改。

    里氏替换原则

    之所以把这个原则放到继承里面说明,是因为里氏替换原则的核心原理是抽象。而抽象又依赖于继承这个特性。可以说里氏替换原则是对良好的继承定义了一个规范。

    定义

    所有引用基类的地方必须能透明地使用其子类的对象。这句话的意思是说在基类出现的地方子类就可以出现,而且替换为子类也不会有任何异常。但是反过来就不行了,有子类出现的地方,父类未必就合适出现。

    目的

    构建扩展性更好的系统,里氏替换原则和开闭原则往往是生死相依、不离不弃的,通过里氏替换原则来达到对扩展开放,对修改关闭的效果。

    举例

    Android中Window和View的关系来说。

    //窗口类
    public class Window{
        public void show(View child){
            child.draw();
        }
    }
    
    //建立抽象View,测量视图的宽高为公用代码,绘制实现交给具体的子类
    public abstract class View(){
        public abstract void draw();
        public void measure(int width,int height){
            //测量视图大小
        } 
    
    }
    
    //文本控件类的实现
    public class TextView extends View{
        public void draw(){
            //绘制文本
        }
    }
    
    //图片控件类的实现
    public class ImageView extends View{
        public void draw(){
            //绘制图片
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    通过在window类的show函数中传入泛化的View。

    向上转型

    Window类的show函数参数是View基类,使用的过程中,此时如果想要显示一个TextView的话,使用方式如下:

    Window w = new Window();
    w.show(new TextView);
    
    • 1
    • 2

    上面这段代码在show函数中,将TextView看做是View的一种,把子类看做是它的基类的这个过程称为向上转型。

    向下转型

    我们在使用容器存储对象的时候,因为容器只存储Object类型,所以当将对象引用置入容器时,它必须被向上转型为Object。当取回的时候,就获得了一个对Object对象的引用,而不是存储时的那个类型的对象的引用。那么,怎样才能将它变回存储时的那个对象呢?这里就用到了向下转型,即将上层一个更泛化的类型,向下转型为一个更具体的类型。

    向下转型是不安全的,例如上面的代码,TextView是一种View类型,但是不知道某个View是TextView还是ImageView所以除非确切知道所要处理的对象的类型,否则向下转型时就有可能出现ClassCastException

    总结

    在开发过程中,使用继承可以大大提高我们开发的效率,在代码设计的过程中,也尽可能的去使用继承这一特性。当然凡事不是绝对,事物总有两面性,如何权衡利弊还需要根据我们的具体情况来做选择,掌握设计模式和编程思想,不一定会让我们变得更好,但至少不会把我们得更差。

  • 相关阅读:
    点云从入门到精通技术详解100篇-基于点云数据的机器人动态分拣
    模板template
    C语言是否快被时代所淘汰?
    使用增强版 singleflight 合并事件推送,效果炸裂!
    为什么通过一致性正则化方法就可以避免将所有未标记数据集分配给同一类?
    025-为什么要用抽象类
    基于Java+SpringBoot+Vue前后端分离网络海鲜市场系统设计和实现
    聊一聊前端图片懒加载背后的故事
    Windows计划任务权限维持
    新手选MT4还是MT5,anzo capital昂首资本建议选择MT4,一个原因
  • 原文地址:https://blog.csdn.net/Wbl752134268/article/details/126243380