`
cdwzwd
  • 浏览: 124008 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

java中的接口和抽象类区别

 
阅读更多
http://hanhongke123.blog.163.com/blog/static/62223494201081433426189/

首先,我们来看一下抽象类的概念,java编程思想中说“万物皆对象”,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类是表征我们对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。   

       好比,我们都知道三角形是一个形状,世界上有三角形这样具体的东西,但是确没有形状这样具体的东西,我们要描述这个形状的概念就要用到抽象类。因此在java中抽象类是不允许被实例化的。
      在面向对象领域,抽象类主要用来进行类型隐藏。那什么是类型隐藏呢?我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。

      好比,动物是一个抽象类,人、猴子、老虎就是具体实现的派生类,我们就可以用动物类型来隐藏人、猴子和老虎的类型。


      再来看一下接口,接口是什么呢?Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。接口是一种特殊形式的抽象类。

  
   抽象类和接口有很大的区别:

        首先,抽象类在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系,但是,一个类却可以实现多个接口。也许,这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。
         其次,在抽象类的定义中,我们可以赋予方法的默认行为。但是在接口的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会 增加一些复杂性,有时会造成很大的麻烦。
        已经提到过,抽象类在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在”is a”关系,即父类和派生类在概念本质上应该是相同的。对于接口来说则不然,并不要求接口的实现者和接口定义在概念本质上是一致的,仅仅是实现了接口定义的契约而已。接口表示的是”like a”关系。
使用抽象类来定义允许多个实现的类型,比使用接口有一个明显的优势:抽象类的演化比接口的演化要容易的多。在后续的发行版中,如果希望在抽象类中增加一个方法,只增加一个默认的合理的实现即可,抽象类的所有实现都自动提供了这个新的方法。对于接口,这是行不通的。虽然可以在骨架实现类中增加一方法的实现来解决部分问题,但这不能解决不从骨架实现类继承的接口实现的问题。由此,设计公有的接口要非常谨慎,一旦一个接口被公开且被广泛实现,对它进行修改将是不可能的。
所以,使用接口还是抽象类,取决于我们对问题的概念的本质理解和设计的意图。
//---------------------------------------------------------------------
        类描述了一个实体,包括实体的状态,也包括实体可能发出的动作。
  接口定义了一个实体可能发出的动作。但是只是定义了这些动作的原型,没有实现,也没有任何状态信息。
  所以接口有点象一个规范、一个协议,是一个抽象的概念;而类则是实现了这个协议,满足了这个规范的具体实体,是一个具体的概念。
  从程序角度,简单理解,接口就是函数声明,类就是函数实现。需要注意的是同一个声明可能有很多种实现。
  1、接口中定义类方法的原型,但是不能说是空方法,因为空方法的意思是有实现体,只不过实现体是空操作。实际上接口没有定义任何实现体。具体的实现体都是在实现接口的类中,接口只是定义了这些方法的调用方式。
  你当然也可以不用接口,直接在类里面写方法,但是如果你的一组方法需要在很多类里实现,那么把它们抽象出来,做成一个接口规范,不是更好么?
  2、一个类描述了一个实体,这个实体可能是一个复杂的对象,它的动作很多,如果把这些动作分类,用接口a定义其中的某一组动作,接口b定义其中的另外一组动作,这样的结构,比较清楚。
  这种方式具备了多继承的优点,避免了多继承的缺陷。实际上在历史上,接口在很大程度上,是为了解决多继承带来的种种问题而设计出来的。
  3、包中那些已定义的接口,怎么知道那里面定义了什么方法。
  接口里定义了方法的输入输出,这些都是协议,具体的实现都在每个类中。对于很多只需要抽象接口的地方,不需要知道具体的类是什么,只要这个类实现了这个接口就可以了。

当然,以上只是对接口的初步认识,在对面向对象程序设计有更深入的认识以后,会发现接口有更广泛的用途。

另外,抽象类不能被实例化,也就是说,不能创建抽象类的任何对象。必须创建抽象类的子类,然后再创建子类的对象。一个接口可以继承多个接口,一个类可以实现多个接口。
本文出自 51CTO.COM技术博客





***************************************************************************************************************************************************

1、抽象类
       抽象类实际上也是一个类,只是与之前的普通类相比,在抽象类中多了抽象方法。
       抽象方法是只声明而未实现的方法,所有的抽象方法必须使用abstract关键字声明,包含抽象方法的类也必须使用abstract class声明。
一个抽象类的定义
abstract class A{
         private String name = "WWW" ;
         public void fun(){
                   // 此处定义了一个普通方法
                   System.out.println("Hello World!!!") ;
         }
         public abstract void print() ;
}; 
     

可以发现抽象方法后面没有“{}”,则表示方法没有实现。
       如果对抽象方法直接实例化,则会出现无法实例化的错误。
abstract class A{
         private String name = "WWW" ;
         public void fun(){
                   // 此处定义了一个普通方法
                   System.out.println("Hello World!!!") ;
         }
         public abstract void print() ;
};
public class Demo01{
         public static void main(String args[]){
                   A a = new A() ;
         }
}; 

抽象类的使用原则:
       1、  抽象类必须有子类,抽象类必须被继承
       2、  抽象类的子类如果不是抽象类的话,则必须覆写里面的全部抽象方法。
       3、  抽象类不能直接实例化,必须依靠子类完成。
进一步完善之前的程序:
abstract class A{
         private String name = "WWW" ;
         public void fun(){
                   // 此处定义了一个普通方法
                   System.out.println("Hello World!!!") ;
         }
         public abstract void print() ;
};
class B extends A{
         // 覆写抽象方法
         public void print(){
                   System.out.println("**********************") ;
         }
};
public class Demo02{
         public static void main(String args[]){
                   B b = new B() ;
                   b.print() ;
                   b.fun() ;
         }
}; 

讨论问题:
       1、  能否用final修饰一个抽象类呢?
              · 因为抽象类必须被子类继承,而被final修饰的类不能有子类。所以不能
       2、  抽象类中能否有构造方法呢?可以有
abstract class Person{
         private String name ;
         private int age ;
         // 单独按一个类来说,应该可以直接在构造方法中初始化
         public Person(String name,int age){
                   this.name = name ;
                   this.age = age ;
         }
         public abstract String getInfo() ;
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
};
class Student extends Person{
         private String school ;
         public Student(String name,int age,String school){
                   super(name,age) ;
                   this.school = school ;
         }
         public String getInfo(){
                   return "姓名:"+super.getName()+",年龄:"+super.getAge()+",学校:"+this.school ;
         }
};
public class Demo03{
         public static void main(String args[]){
                   Student stu = new Student("张三",30,"北京大学") ;
                   System.out.println(stu.getInfo()) ;
         }
}; 

抽象类中可以有构造方法,但是要求在没有无参构造方法的时候,子类必须明确的调用父类中的构造方法。
回顾:子类对象的实例化过程
· 子类对象实例化的时候默认会先去调用父类中的无参构造方法,如果父类中没有无参构造,则可以通过super指定调用父类中的其他构造方法。
注意:
       一个类只可以继承一个抽象类,属于单继承。
2、接口
       接口定义:
              · 只包含抽象方法和全局常量的类称为接口。
              · 接口使用interface进行定义。
interface A{
         public static final String INFO = "HELLO" ;
         public abstract void print() ;
} 
      
接口定义完之后,一个接口也必须依靠其子类使用,子类继承接口的概念称为实现。格式如下:
              class 子类 implements 接口名称{}
       接口的子类如果不是抽象类的话,则也必须覆写里面的全部抽象方法。
interface A{
         public static final String INFO = "HELLO" ;
         public abstract void print() ;
}
class B implements A{
         public void print(){
                   System.out.println(INFO) ;
         }
};
public class Demo04{
         public static void main(String args[]){
                   B b = new B() ;
                   b.print() ;
         }
}; 

       接口与抽象类相比,有一个优点:说一个子类只能继承一个父类,但是可以同时实现多个接口,也就说是通过接口完成多继承。
       class 子类 implements 接口A,接口B
interface A{
         public static final String INFO = "HELLO" ;
         public abstract void print() ;
}
interface C{
         public static final String PARAM = "WWW" ;
         public abstract void fun() ;
}
class B implements A,C{
         public void print(){
                   System.out.println(INFO) ;
         }
         public void fun(){
                   System.out.println(PARAM) ;
         }
};
public class Demo05{
         public static void main(String args[]){
                   B b = new B() ;
                   b.print() ;
                   b.fun() ;
         }
}; 

       问题:
既然,接口中的一切方法都是抽象方法,接口中的一切变量都是全局常量,那么实际上接口就可以简化成如下的形式定义。
interface A{
         // public static final String INFO = "HELLO" ;
         String INFO = "HELLO" ;
         // public abstract void print() ;
         void print() ;     //à 此处虽然没有明确的写出权限,但实际上权限是public
} 

       一定要明确:接口中的一切方法都是public访问权限,所以在子类实现方法的时候访问权限必须是public。写与不写是一样的。所以有时候为了避免此种情况,还是建议写上:public
         public void print() ;

       那么如果一个类继承继承一个抽象类又要实现一个接口,则必须按照以下格式完成:
       class 子类 extends 父类(一般都是抽象类) implements 接口A,接口B

interface A{
         // public static final String INFO = "HELLO" ;
         String INFO = "HELLO" ;
         // public abstract void print() ;
         void print() ;
}
abstract class X{
         public String param = "hello" ;
         abstract void fun() ;
};
class B extends X implements A{
         public void print(){
                   System.out.println(INFO) ;
         }
         void fun(){
                   System.out.println(INFO) ;
                   System.out.println(param) ;
         }
};
public class Demo07{
         public static void main(String args[]){
                   B b = new B() ;
                   b.print() ;
         }
}; 


开发原则:
       在开发中一定要记住,一个类往往很少去继承一个已经实现好的类,即:普通类之间不能互相继承。

注意点:
       1、  一个抽象类可以实现多个接口,但是一个接口不能继承一个抽象类。
interface A{
         // public static final String INFO = "HELLO" ;
         String INFO = "HELLO" ;
         // public abstract void print() ;
         void print() ;
}
abstract class X implements A{
         public String param = "hello" ;
         abstract void fun() ;
}; 
      
2、  一个接口可以同时继承多个接口,即:实现多继承关系
              interface 子接口 extends 父接口A,父接口B,父接口C
interface A{
         public void printA() ;
}
interface B{
         public void printB() ;
}
interface C{
         public void printC() ;
}
interface X extends A,B,C{
         public void printX() ;
};
class Y implements X{
         public void printA(){}
         public void printB(){}
         public void printC(){}
         public void printX() ;
}; 




抽象类与接口的实际应用{百分百的重点}

开发原则:
       在类的开发之中,一个类不会去继承一个已经实现好的类,只会继承抽象类或实现接口。
       即:以下的代码是不应该出现在程序之中的:
class A{}
class B extends A{} 


3、抽象类实际应用
       抽象类本身是不能直接实例化的。因为其本身包含抽象方法。
       但是抽象类的时候符合继承关系,只要有继承关系,则肯定会存在对象的向上或向下转型的问题,一但对象发生了向上转型,则肯定一切的方法以被子类覆写过的方法为准。
abstract class A{
         public abstract void fun() ;
};
class B extends A{
         public void fun(){
                   System.out.println("Hello World!!!") ;
         }
};
public class Demo32{
         public static void main(String args[]){
                   A a = new B() ;
                   a.fun() ;
         }
}; 
      
从以上代码之中可以发现,抽象类可以实例化,但是需要通过对象的多态性,通过子类进行实例化操作。
实际上抽象类就是提供了此种类型的代码结构。
例如:人分为工人和学生,工人和学生都有说话方法,但是说话的内容要由工人或学生决定,所以此时就可以使用抽象类完成此种功能。
abstract class Person{
         private String name ;
         private int age ;
         public Person(String name,int age){
                   this.name = name ;
                   this.age = age ;
         }
         public void say(){
                   System.out.println(this.getContent()) ;
         }
         public String getName(){
                   return this.name ;
         }
         public int getAge(){
                   return this.age ;
         }
         public abstract String getContent() ;
};
class Worker extends Person{
         private float salary ;
         public Worker(String name,int age,float salary){
                   super(name,age) ;
                   this.salary = salary ;
         }
         public String getContent(){
                   return "工人说 --> 姓名:"+this.getName()+",年龄:"+this.getAge()+",工资:"+this.salary ;
         }
};
class Student extends Person{
         private float score ;
         public Student(String name,int age,float score){
                   super(name,age) ;
                   this.score = score ;
         }
         public String getContent(){
                   return "学生说 --> 姓名:"+this.getName()+",年龄:"+this.getAge()+",成绩:"+this.score ;
         }
};
public class Demo33{
         public static void main(String args[]){
                   Person p = null ;
                   // p = new Student("张三",20,99.0f) ;
                   p = new Worker("张三",20,999.0f) ;
                   p.say() ;
         }
}; 

4、接口的实际应用
总的使用原则:接口的作用就是将方法名称暴露给远程用户。
       接口与抽象类一样,如果要想正确的时候也需要通过子类进行实例化操作。
如下代码所示:
interface A{
         public void print() ;
}
class B implements A{
         public void print(){
                   System.out.println("Hello World!!!") ;
         }
};
public class Demo35{
         public static void main(String args[]){
                   A a = new B() ;
                   a.print() ;
         }
}; 

接口的实际应用:定义标准。
       以USB接口为例:
interface USB{
         public void start() ;
         public void stop() ;
}
class MainBoard{
         public void plugIn(USB usb){
                   usb.start() ;
                   usb.stop() ;
         }
};
class Mp3 implements USB{
         public void start(){
                   System.out.println("MP3开始工作。") ;
         }
         public void stop(){
                   System.out.println("MP3停止工作。") ;
         }
};
class Print implements USB{
         public void start(){
                   System.out.println("打印机开始工作。") ;
         }
         public void stop(){
                   System.out.println("打印机停止工作。") ;
         }
};
public class Demo36{
         public static void main(String args[]){
                   MainBoard mb = new MainBoard() ;
                   mb.plugIn(new Mp3()) ;
                   mb.plugIn(new Print()) ;
         }
}; 






抽象类与接口的区别(☆☆) 区别点 抽象类 接口
定义 abstract class 抽象类名称{} interface 接口名称{}
概念 包含一个抽象方法的类就是抽象类,除此之外还包含常量、变量、普通方法、构造方法 只包含全局常量和抽象方法的类称为接口
使用 需要通过子类继承
class 子类 extends 父类 需要通过子类实现
class 子类 implements 接口
关系 一个抽象类可以实现多个接口,一个接口不能继承一个抽象类
作用 提供了一个模板 提供了一个标准,或者说表示了一种能力
设计模式 模板设计模式 工厂设计模式、代理设计模式
适配器设计模式
限制 抽象类有单继承局限 无此局限
应用 如果抽象类与接口同时都可以使用,优先使用接口
特殊点 一个抽象类可以包含一个接口或一个抽象类 一个接口中也可以包含抽象类或接口

分享到:
评论

相关推荐

    11.java接口和抽象类的区别.zip

    11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别....

    java利用接口和抽象类改写求圆的面积和梯形的面积.docx

    在Java编程语言中,接口(Interface)和抽象类(Abstract Class)都是用于实现多态性和代码复用的重要概念。它们都无法被直接实例化,而是位于继承结构的顶层,被其他类实现或继承。接口和抽象类都可以包含抽象方法...

    详细解析Java中抽象类和接口的区别

    ### 详细解析Java中抽象类和接口的区别 #### 引言 在面向对象编程中,Java作为一种广泛应用的编程语言,提供了多种方式来实现抽象的概念。其中最常用的两种机制是抽象类(abstract class)和接口(interface)。这...

    Java 接口和抽象类

    Java 接口和抽象类 Java 编程语言提供了两种机制来实现面向对象编程的多态性:接口和抽象类。这两种机制使得 Java 应用开发具有灵活性和敏捷性。 抽象类 抽象类是一种特殊的类,它不能被实例化,不能被直接使用,...

    java中接口与抽象类的详细分析与比较

    在Java编程语言中,接口(Interface)和抽象类(Abstract Class)都是用于实现多态性的关键概念,它们各自有特定的用途和优缺点。本文将深入探讨这两种概念,帮助你理解它们之间的区别以及如何在实际开发中选择使用...

    Java中抽象类和接口的区别

    在Java语言中,abstract class和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,...

    10.java接口和抽象类的相似性.zip

    10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和...

    Java中的类、抽象类和接口的区别和联系

    Java中的类、抽象类和接口的区别和联系

    Java 接口和抽象类区别

    Java接口和抽象类是两种重要的面向对象编程概念,它们在软件设计中扮演着关键角色,主要用来实现多态性和代码的可扩展性。虽然两者都用于定义类的行为,但它们之间存在着显著的区别。 首先,接口是一种完全抽象的...

    java 抽象类与接口的区别

    在Java编程语言中,抽象类和接口是两种重要的面向对象设计概念,它们都用于实现多态性,但各自具有不同的特点和应用场景。了解并熟练掌握它们的区别对于编写高质量的Java代码至关重要。 首先,抽象类是一种不能被...

    JAVA中抽象类和接口的区别

    在Java语言中,abstract class 和interface 是支持抽象类定义的两种机制区别

    java抽象类与接口实例java抽象类与接口实例

    java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例...

    Java语言的接口与抽象类

    Java语言的接口与抽象类是面向对象编程中的关键概念,它们在设计模式和代码组织中起着重要作用。这里我们将深入探讨这两个概念,并分析它们的异同。 首先,接口(Interface)是Java中的一种特殊类型,它通过使用`...

    Java源代码:抽象类和接口

    在Java编程语言中,抽象类和接口是两种重要的面向对象设计概念,它们允许我们定义规范,为其他类提供模板或行为指南。让我们深入探讨这两个概念及其在Java中的应用。 首先,我们来理解抽象类。在Java中,抽象类是一...

    浅析Java抽象类和接口的比较

    Java中的抽象类(abstract class)和接口(interface)都是用于创建抽象化模型的重要工具,它们在面向对象编程中扮演着核心角色。这两种机制都允许我们定义一组方法的签名,但不提供具体实现,从而实现“设计契约”...

    Java开发接口和抽象类的区别共2页.pdf.zip

    在Java编程语言中,接口(Interface)和抽象类(Abstract Class)都是用于实现多态性的关键概念,它们各自有特定的用途和特点。理解这两者的区别对于任何Java开发者来说都至关重要,因为正确地选择使用接口或抽象类...

    Java抽象类与接口实验报告

    Java抽象类与接口实验报告

    java抽象类与接口区别

    综上所述,抽象类与接口在Java中各有优势和局限性。抽象类适用于提供一些基础的实现细节,而接口则更多地用于定义行为规范。理解两者之间的差异可以帮助开发者更加灵活地设计程序结构。在实际应用中,根据项目需求...

Global site tag (gtag.js) - Google Analytics