黑马程序员技术交流社区

标题: read方法为什么有的抽象,有的具体? [打印本页]

作者: liuzhming    时间: 2013-7-22 00:52
标题: read方法为什么有的抽象,有的具体?
本帖最后由 杨兴庭 于 2013-7-22 21:21 编辑

在inputStream抽象类中,有三个read重载方法,分别是:abstact int read(),int read(byte[] b),int read(byte[] b,int off,int len),为什么第一个方法是抽象方法,而后两个是具体方法呢?outputStream中也是这样。

作者: 草貌路飞    时间: 2013-7-22 01:02
因为其它两个方法说到底还是调用抽象的那个方法,所以只要实现那个抽象的就行了
作者: 王磊    时间: 2013-7-22 01:48
曾经也注意过这个问题,后来查了下源代码,有了点自己的理解。
按照楼主所列的3个方法为例,两个方法是非抽象的,说明可以由子类对象直接调用,并且由于其多数子类对象所使用的该方法主体相同,则将其主体直接在父类中统一定义,方便后续子类的调用(无需再去覆写),如有个别的子类使用该方法时与父类不同,则可单独覆写掉该方法主体,以供子类自身对象调用。
而read定义成抽象,是因为InputStream的子类大多数使用该方法的时候,方法主体都不同,如下:
  1. public native int read() throws IOException;
复制代码
这个是FileInputStream中的read方法的覆写
注:这里的方法虽然没有主体,但它也不是抽象方法,因为它用native修饰,表示该方法调用的是系统底层的数据结构或者该方法中调用了一些不是由JAVA编写的代码。
  1. public int read() throws IOException {
  2.         return in.read();
  3.     }
复制代码
这是FilterInputStream种的read方法的覆写
  1. public synchronized int read()  throws IOException {
  2.         if (!connected) {
  3.             throw new IOException("Pipe not connected");
  4.         } else if (closedByReader) {
  5.             throw new IOException("Pipe closed");
  6.         } else if (writeSide != null && !writeSide.isAlive()
  7.                    && !closedByWriter && (in < 0)) {
  8.             throw new IOException("Write end dead");
  9.         }

  10.         readSide = Thread.currentThread();
  11.         int trials = 2;
  12.         while (in < 0) {
  13.             if (closedByWriter) {
  14.                 /* closed by writer, return EOF */
  15.                 return -1;
  16.             }
  17.             if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
  18.                 throw new IOException("Pipe broken");
  19.             }
  20.             /* might be a writer waiting */
  21.             notifyAll();
  22.             try {
  23.                 wait(1000);
  24.             } catch (InterruptedException ex) {
  25.                 throw new java.io.InterruptedIOException();
  26.             }
  27.         }
  28.         int ret = buffer[out++] & 0xFF;
  29.         if (out >= buffer.length) {
  30.             out = 0;
  31.         }
  32.         if (in == out) {
  33.             /* now empty */
  34.             in = -1;
  35.         }

  36.         return ret;
  37.     }
复制代码
这是PipedOutputStream种的read方法的覆写

我没有将InputStream的所有子类的源代码都看过,但是至少我找了3个子类,其中的read方法主体就都不相同。所以我认为,在父类中定义成抽象方法,就是针对其大多数子类都没有一个相同的主体。所以只有定义成抽象,并又不同的子类去使用各自的read方法,这样的定义最合适。

希望对楼主有所帮助。
作者: chensc    时间: 2013-7-22 05:43
学习学习!
作者: lkjghvcx@163.co    时间: 2013-7-22 07:30
抽象的方法是最基本的读写方法,要子类来覆盖的,子类要有特殊的读写方法,然后其他方法都是调用这个最基本的读写方法,
作者: 王丽达    时间: 2013-7-22 11:27
首先,抽象类中不一定要有抽象方法;抽象方法所在的类,一定是抽象类。
我是这样理解的
理解一:抽象类:顾名思义,抽象出来的就是一些事物的共性,一次定义,方便多次拥有并覆盖,方便多个具有该共性的事物(对象)拥有并覆盖。
但是, 不同的对象除了共性,还有不同,即抽象类中的非抽象方法,以表现出自己独有的东西,父类中的非抽象方法在子类中不用覆盖,但只是抽象类自己不能new对象,想要调用,只要在子类中new对象就可以了。
理解二:正是因为抽象类的抽象方法抽象出来的是共性的东西,所以要实现抽象类,首先,抽象类中的所有抽象方法要被覆盖(除非子类也是非接口的抽象类,不用覆盖),才能拥有所有自己和别的事物共有的特点,但是还不够全面,再加上自己独有的具体的别人没有的特点(即具体的方法)。这是因需要而产生的具体的非抽象方法。
作者: liuzhming    时间: 2013-7-22 12:05
哦,明白了,谢谢大家的回答
作者: 枫儿    时间: 2013-11-8 08:05

我顶
必须顶
不得不顶
用尽全力顶
再加上千斤顶
总之把它顶到顶
接着使出葵花宝顶
就算顶到史前也要顶
老子看了会用道德经顶
孔子亲自拜你为师天天顶
作者: 枫儿    时间: 2013-11-8 08:06
秦始皇站在阿房宫上使劲顶
汉高祖挥师杀向东罗马为你顶
吕布抛弃了貂禅而选择了帮你顶
张三丰见了后用太极拳九式全力顶
左冷禅召开武林盟主大会商讨如何顶
西门吹雪从此学会了最强一招剑神一顶
龙剑飞的如来神掌最后一式改为万佛朝顶
陆小凤从此再也不管闲事了而专门来为你顶
四大名捕四面出击看天下还有没有人敢不在顶
顶到阎罗王说我制造噪音我刁根烟看看他继续顶
作者: 枫儿    时间: 2013-11-8 08:06
顶到火山喷发太平洋海啸我还要继续往死里顶
顶到益阳地震山崩地裂地下水泛滥我还要顶
顶到地下水喷发造成洪灾损失惨重我也顶
要是你觉得敢兴趣你也可以过来一起顶
要是你看我不爽我没办法还要继续顶
要是警察敢过来阻止我就更加要顶
要是别人见了骂我傻我还是要顶
要是踩到我脚骨折我也继续顶
作者: 枫儿    时间: 2013-11-8 08:06
要是地面凹了我不管继续顶
要是天真塌下来了继续顶
就算天塌下来我都要顶
就算腾讯倒闭也要顶
就算鞋子烂也要顶
我用尽全力去顶
我非常用力顶
我很用力顶
我用力顶
我再顶
我顶





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2