Java继承分析

Posted 無昂博奥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java继承分析相关的知识,希望对你有一定的参考价值。

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

继承

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

关系图

优点

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

  • 子类可以形似基类,但又和基类不同。有两种方式可以使子类和基类产生差异:
    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()
        //绘制图片
    

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

向上转型

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

Window w = new Window();
w.show(new TextView);

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

向下转型

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

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

总结

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

以上是关于Java继承分析的主要内容,如果未能解决你的问题,请参考以下文章

怎样测球的半径?

Java继承问题

JavaScript中使用new操作符实例化对象时构造函数有返回值的情况分析

JavaScript中使用new操作符实例化对象时构造函数有返回值的情况分析

如何测量在 ubuntu 上运行的 java 应用程序的 I/O 时间?

如何系统全面性学习Java语言?Java校招面试指南