论坛首页 Java企业应用论坛

总结java的interface和abstract class

浏览 7376 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (11)
作者 正文
   发表时间:2011-02-23   最后修改:2011-02-28
原文出处:http://www.blogjava.net/vcycyv/archive/2011/02/20/344716.html先说说interface和abstract method语法中需要注意的地方。

Interface:

1. An interface can contain fields, but these are implicitly static and final.

2. You can choose to explicitly declare the methods in an interface as public, but they are public even if you don’t say it.

3. Interface cannot define static method



Abstract:

1. 一个类中如果所有的方法都有实现,我们仍然可以定义这个类为abstract class

2. abstract和static不能放在一起定义方法。



Interface和Abstract class的实践

1. interface适合定义mixins(不知道mixin怎么翻译,它指窄接口,只定义specific contract).

java不能多重继承。如果想达到多重继承的效果,需要借助“多重实现”interface. interface的一个典型用法是定义小接口。比如Comparable。这样它的实现成本比较小,一个class比较容易mixin多个interface。

2. 如果interface不是mixin, 而是大一点的接口。

effective java, 2nd edition有精彩的阐述,对于大接口,我们往往使用skeletal implementation class. 举个例子:

 
  // Concrete implementation built atop skeletal implementation
   static List<Integer> intArrayAsList(final int[] a) {
   if (a == null)
   throw new NullPointerException();
   return new AbstractList<Integer>() {
   public Integer get(int i) {
   return a[i];  // Autoboxing (Item 5)
   }
   @Override public Integer set(int i, Integer val) {
   int oldVal = a[i];
   a[i] = val;     // Auto-unboxing
   return oldVal;  // Autoboxing
   }
   public int size() {
   return a.length;
   }
   };
  }
new AbstractList<Integer>就是在应用Skeletal implementation. 有两个好处:

a) 它使实现接口更方便了

b) If, in a subsequent release, you want to add a new method to an abstract class, you can always add a concrete method containing a reasonable default implementation. All existing implementations of the abstract class will then provide the new method. This does not work for interfaces.

跟interface相关的还有一个话题是wrapper class,也很精彩,它是把继承转成合成的方式,应用了decorater模式的思想. 在书里的第16章介绍。

  
 // Wrapper class - uses composition in place of inheritance
    public class InstrumentedSet<E> extends ForwardingSet<E> {
        private int addCount = 0;
        public InstrumentedSet(Set<E> s) {
            super(s);
        }
        @Override public boolean add(E e) {
            addCount++;
            return super.add(e);
       }
       @Override public boolean addAll(Collection<? extends E> c) {
           addCount += c.size();
           return super.addAll(c);
       }
       public int getAddCount() {
           return addCount;
       }
   }
   // Reusable forwarding class
   public class ForwardingSet<E> implements Set<E> {
       private final Set<E> s;
       public ForwardingSet(Set<E> s) { this.s = s; }
       public void clear()               { s.clear();            }
       public boolean contains(Object o) { return s.contains(o); }
       public boolean isEmpty()          { return s.isEmpty();   }
       public int size()                 { return s.size();      }
       public Iterator<E> iterator()     { return s.iterator();  }
       public boolean add(E e)           { return s.add(e);      }
       public boolean remove(Object o)   { return s.remove(o);   }
       public boolean containsAll(Collection<?> c)
                                      { return s.containsAll(c); }
       public boolean addAll(Collection<? extends E> c)
                                      { return s.addAll(c);      }
       public boolean removeAll(Collection<?> c)
                                      { return s.removeAll(c);   }
       public boolean retainAll(Collection<?> c)
                                      { return s.retainAll(c);   }
       public Object[] toArray()          { return s.toArray();  }
       public <T> T[] toArray(T[] a)      { return s.toArray(a); }
       @Override public boolean equals(Object o)
                                          { return s.equals(o);  }
       @Override public int hashCode()    { return s.hashCode(); }
       @Override public String toString() { return s.toString(); }
   }
使用它的客户端程序:

   Set<Date> s = new InstrumentedSet<Date>(new TreeSet<Date>(cmp));
   Set<E> s2 = new InstrumentedSet<E>(new HashSet<E>(capacity));



3. 人人都说 面向接口编程,很多时候矫枉过正了, 搞得接口漫天飞。interface常常是重构出来的,而不总是设计出来的。程序分层中,越是靠近底层的程序,越倾向于需要接口,越靠近顶层的程序,对接口的需求倾向于越小。如果你明知道以后不太可能提供另一套实现,提前写个接口摆那里也没啥意义,尽管定义接口的成本很低。如果你担心一旦有一天确实提供了另一套实现,重构code也不会很麻烦。只要遵守了单一职责原则和迪米特法则。迪米特法则的一种表述方式是:talk only to your immediate friends
   发表时间:2011-02-24   最后修改:2011-02-24
接口的契约性更加强,class可以继承,可以拥有数据和已实现的方法

最后一点你说得真的很对,现在接口都是漫天飞舞,呵呵,不争的事实

不过如果系统中有明确的模块边界,虽然功能上两者都可以,接口更好,可以多继承,可以根据需要提供更加灵活的的功能宽窄需要。

大多数都是crud,多个接口无所谓了!

现在我在dao中的实践回归原始,dao只是存储介质:整个系统中只定义一个jdbcTemplate——通过这一个代替原来所有的dao

service按照功能职责只管理自己的数据(呵呵,说白了就是sql都写在service中了),其他需要数据的都找service

感觉:系统中没有烦人的dao了,sql现在感觉也不多,一个service中一般也就7、8条左右,维护简单,一看就清楚(以往要从不通的dao去看,麻烦死了)

service的功能职责强化了

需要提供查询的一般都按照大模块构建queryservice,然后在其中进行处理!
0 请登录后投票
   发表时间:2011-02-25  
接口比抽象类更“抽象”
0 请登录后投票
   发表时间:2011-02-25  
abstract class表示的是"is a"关系,interface表示的是"like a"关系
0 请登录后投票
   发表时间:2011-02-25  
结合环境探讨,接口和抽象类它们只有谁更加适合:功能需要和未来扩展需要
0 请登录后投票
   发表时间:2011-02-25  
接口是对外暴露的,但自己开发的系统内部模块之间是否有必要留接口。
0 请登录后投票
   发表时间:2011-02-25  
skzr.org 写道

现在我在dao中的实践回归原始,dao只是存储介质:整个系统中只定义一个jdbcTemplate——通过这一个代替原来所有的dao

service按照功能职责只管理自己的数据(呵呵,说白了就是sql都写在service中了),其他需要数据的都找service

感觉:系统中没有烦人的dao了,sql现在感觉也不多,一个service中一般也就7、8条左右,维护简单,一看就清楚(以往要从不通的dao去看,麻烦死了)


不错,我现在的系统也不存在dao了,用泛型技术,一个类完全可以取代一整个DAO层。
0 请登录后投票
   发表时间:2011-02-25  
yuhang_java 写道

3. 人人都说 面向接口编程,很多时候矫枉过正了, 搞得接口漫天飞。interface常常是重构出来的,而不总是设计出来的。程序分层中,越是靠近底层的程序,越倾向于需要接口,越靠近顶层的程序,对接口的需求倾向于越小。如果你明知道以后不太可能提供另一套实现,提前写个接口摆那里也没啥意义,尽管定义接口的成本很低。如果你担心一旦有一天确实提供了另一套实现,重构code也不会很麻烦。只要遵守了单一职责原则和迪米特法则。迪米特法则的一种表述方式是:talk only to your immediate friends


第三点还是有点道理的,不过以后的事情说不定的,不太可能!=一定不会
0 请登录后投票
   发表时间:2011-02-25   最后修改:2011-02-28
haigui.chen 写道
yuhang_java 写道

3. 人人都说 面向接口编程,很多时候矫枉过正了, 搞得接口漫天飞。interface常常是重构出来的,而不总是设计出来的。程序分层中,越是靠近底层的程序,越倾向于需要接口,越靠近顶层的程序,对接口的需求倾向于越小。如果你明知道以后不太可能提供另一套实现,提前写个接口摆那里也没啥意义,尽管定义接口的成本很低。如果你担心一旦有一天确实提供了另一套实现,重构code也不会很麻烦。只要遵守了单一职责原则和迪米特法则。迪米特法则的一种表述方式是:talk only to your immediate friends


第三点还是有点道理的,不过以后的事情说不定的,不太可能!=一定不会


+1
0 请登录后投票
   发表时间:2011-02-26  
interface常常是重构出来的,而不总是设计出来的

+1
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics