天天看点

再看抽象类与接口

       抽象类更多的情况下是作为一个模板使用,而接口更多的情况下是作为一个标准出现。

       一个子类如果实现了一个接口,则肯定要覆写接口中的全部方法,那是否有一种方式,可以让子类有选择的去实现接口中的方法,而不是全都实现呢?

interface A{

         public void printA() ;

         public void printB() ;

         public void printC() ;

         public void printD() ;

         public void printE() ;

}

       以上的接口的子类能否有选择性的进行所需要方法的覆写呢?

abstract class AAdapter implements A{

         // 方法全部实现

         // 但是此类是中间过渡类,不能直接使用,所以此时应该把此类定义成抽象类。

         public void printA() {}

         public void printB() {}

         public void printC() {}

         public void printD() {}

         public void printE() {}

};

class AAA extends AA{

         public void printA() {

                   System.out.println("dafa");

         }

<b>思考:</b>

       张三去酒会参加活动,碰见了一个美国女孩,想跟她说“HELLO,MAKE FRIEND”,第二次又参加了一个舞会,又碰见了一个中国的女孩,想跟她说“你好,我想跟你交朋友”。

       · 碰见美国人说英语

       · 碰见中国人说中文

       · 接口的第二个作用就是表示一种能力。

interface SayChina{

         public void sayChina() ;

interface SayEnglish{

         public void sayEnglish() ;

class Person implements SayChina,SayEnglish{

         public void sayChina(){

                   System.out.println("你好,交朋友吧!") ;

         public void sayEnglish(){

                   System.out.println("HELLO,MAKE FRIEND!") ;

       现在孙键欠了我500000000元钱,此时,王宁是一个老实人,孙键欺负他,不还,之后王宁没有办法了,找到了王伟(专门的讨债公司),准备好了绳索、刀子、枪支,从孙键手里把银子要了回来,之后销毁了一切的证据。但是王宁只管拿回了自己的钱。

       可以按照以下的形式组织代码:

interface Subject{

         public void giveMoney() ;

class RealSubject implements Subject{

         public void giveMoney(){

                   System.out.println("把钱拿回。。。") ;

class ProxySubject implements Subject{

         private Subject sub = null ;

         public ProxySubject(Subject sub){

                   this.sub = sub ;

         public void before(){

                   System.out.println("要准备绳索、刀子、枪支。。。") ;

                   this.before() ;

                   this.sub.giveMoney() ;

                   this.after() ;

         public void after(){

                   System.out.println("销毁一切的罪证。。。") ;

public class Demo06{

         public static void main(String args[]){

                   Subject sub = new ProxySubject(new RealSubject()) ;

                   sub.giveMoney() ;

       问题的引出:现在使用一个接口,同时定义出子类,通过子类为接口进行实例化:

interface Fruit{

         public void eat() ;

class Apple implements Fruit{

         public void eat(){

                   System.out.println("吃苹果。。。") ;

public class Demo07{

                   Fruit f = new Apple() ;

                   f.eat() ;

       以上代码存在问题?

              · main方法实际上相当于是一个客户端程序

              · 如果现在需要换一个子类了,那么就要修改客户端。

              · 好的程序:某一处的更改不影响调用处

       造成以上问题的根源:

              · 子类直接在客户端使用,耦合度太深了。

       在对象实例化的中间加入一个过渡端,所谓的解耦合最大的特点就是永远有一个过渡端。

       那么现在加入一个过渡端:

class Cherry implements Fruit{

                   System.out.println("吃樱桃。。。") ;

<b>class Factory{</b>

<b>         public static Fruit getInstance(String str){</b>

<b>                   Fruit f = null ;</b>

<b>                   if("apple".equals(str)){</b>

<b>                            f = new Apple() ;</b>

<b>                   }</b>

<b>                   if("cherry".equals(str)){</b>

<b>                            f = new Cherry() ;</b>

<b>                   return f ;</b>

<b>         }</b>

<b>};</b>

public class Demo08{

                   Fruit f = Factory.getInstance(args[0]) ;

                   if(f!=null)

                            f.eat() ;

       此时,发现程序的客户端没有任何的改变,而直接可以选择各种所要的子类。那么通过工厂取得全部的接口实例,那么以后修改的时候就可以只修改工厂了。

<b>区别点</b>

<b>抽象类</b>

<b>接口</b>

<b>定义</b><b></b>

abstract class 抽象类名称{}

interface 接口名称{}

<b>概念</b><b></b>

包含一个抽象方法的类就是抽象类,除此之外还包含常量、变量、普通方法、构造方法

只包含全局常量和抽象方法的类称为接口

<b>使用</b><b></b>

需要通过子类继承

class 子类 extends 父类

需要通过子类实现

class 子类 implements 接口

<b>关系</b><b></b>

一个抽象类可以实现多个接口,一个接口不能继承一个抽象类

<b>作用</b><b></b>

提供了一个模板

提供了一个标准,或者说表示了一种能力

<b>设计模式</b><b></b>

模板设计模式

工厂设计模式、代理设计模式

适配器设计模式

<b>限制</b><b></b>

抽象类有单继承局限

无此局限

<b>应用</b><b></b>

如果抽象类与接口同时都可以使用,优先使用接口

<b>特殊点</b><b></b>

一个抽象类可以包含一个接口或一个抽象类

一个接口中也可以包含抽象类或接口

<b>特殊点:</b>

1、  一个抽象类中能否包含一个接口?可以

abstract class A{

         public abstract void printA() ;

         interface B{

                   public void printB() ;

class DA extends A{

         public void printA(){}

         class DB implements B{

                   public void printB(){}

         };

2、  一个接口中能否包含一个抽象类?可以

         abstract class B{

                   public abstract void printB() ;

class DA implements A{

         class DB extends B{

观察以下的题目,写出输出结果:

         public A(){

                   this.print() ;

         public abstract void print() ;

class B extends A{

         private int i = 10 ;

         public B(int i){

                   this.i = i ;

         public void print(){

                   System.out.println(this.i) ;

public class Demo11{

         public static void main(String artgs[]){

                   new B(100) ;

       答案是0

       子类对象实例化之前,肯定要先去调用父类中的无参构造方法,为父类中的属性初始化,但是父类中的方法未调用完之前,子类的内容并没有初始化,如果没有初始化,则会安排默认值,默认值就是“0”。

本文转自 李兴华 51CTO博客,原文链接:http://blog.51cto.com/lixinghua/96923,如需转载请自行联系原作者

继续阅读