thinking in java (三) ----- 接口与抽象类

 

接口的抽象类给我们提供了接口和实现分离更加结构化的方法

接口和抽象类是java中对抽象概念进行定义的两种机制,正是因为他们的存在,才赋予了java强大的面向对象的能力。他们之间对于抽象有很大的相似,但是也有一些不同

抽象类

前面我们说过万物皆对象,对象是通过类来描述的,但并不是所有的类都是用来描述对象的。如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称为抽象类

比如new Car(),但是具体的car长什么样,我们是不知道的,是抽象类。我们需要一个具体的车,比如卡宴,宝马等进行特定描述。

抽象类体现了抽象的思想,是实现多态的一种机制,他定义了一组抽象方法,其中的具体形式通过子类来实现。抽象类会被继承,否则其没有存在的意义。使用抽象类时,需要注意以下几点:

  1. 抽象类不能被实体化,只需要提供一个引用就行了
  2. 抽象方法由子类进行重写
  3. 只要有一个抽象方法,这个类就是抽象类
  4. 子类中的抽象方法不能和父类中的抽象方法一样
  5. 抽象方法也可以有具体方法,可以有成员变量
  6. abstract修饰的方法就是需要被重写,因此不能跟static,private并列修饰一个方法

实例

定义一个动物类Aninal,提供抽象方法cry(),猫狗为子类,如下:

public abstract class Animal {
    public abstract void cry();
}

public class Cat extends Animal{

    @Override
    public void cry() {
        System.out.println("猫叫:喵喵...");
    }
}

public class Dog extends Animal{

    @Override
    public void cry() {
        System.out.println("狗叫:汪汪...");
    }

}

public class Test {

    public static void main(String[] args) {
        Animal a1 = new Cat();
        Animal a2 = new Dog();
        
        a1.cry();
        a2.cry();
    }
}

--------------------------------------------------------------------
Output:
猫叫:喵喵...
狗叫:汪汪...

接口

关键字interface将abstract的概念做了更进一步的发挥,可以想象它是纯粹的abstract class,他构建出class(函数名,参数列表 返回类型)的形式,但是没有方法体。interface中可以含有数据成员,但是自然而然成为static final。interface值提供形式,不实现细节。

接口是抽象类的延伸,接口优于抽象类的一点是能够多实现,弥补了抽象类不能多继承的缺陷。在使用接口的过程中,需要注意一下问题:

  1. interface中的所有方法都会被自动声明为public,且只能为public
  2. 接口中可以声明变量,但是是静态变量
  3. 接口中不存在实现的方法
  4. 实现接口的非抽象类必须实现接口中所有的方法
  5. 接口不能被实例化
  6. 在实现多接口的时候注意避免方法名的重复

抽象类的接口的区别

1,语法层次

在语法层次,两者定义不同。下面使用代码来说明不同之处。

抽象类:

public abstract class Demo {
    abstract void method1();
    
    
    void method2(){
        //实现
    }
}

接口:

interface Demo {
    void method1();
    void method2();
}

抽象类方式中,抽象类可以拥有任意范围的成员数据,同时也可以拥有自己的非抽象方法,但是接口方式中,它仅能够有静态、不能修改的成员数据(但是我们一般是不会在接口中使用成员数据),同时它所有的方法都必须是抽象的。在某种程度上来说,接口是抽象类的特殊化。

对子类而言,它只能继承一个抽象类(这是java为了数据安全而考虑的),但是却可以实现多个接口。

2,设计层次

从设计层次上来讲,才能看出两者本质的差别

1,抽象层次不同。抽象类时对类抽象,接口是对行为的抽象。抽象类时是对类整体抽象,包括行为属性,但是interface只是对行为进行抽象

2,跨域不同,抽象类体现的 是一种继承关系,父类的子类必须是is-a关系,父类和子类本质上是相同的。interface则不是,interface只是是实现者对行为的实现,比如说飞机和鸟实现飞的行为

3,设计层次不同。抽象类时自下而上设计的,我们要先知道子类才能抽象出父类,而接口不需要知道子类的存在,只需要定义规则就行。

区别的例子

定义一个phone的类,里面有打电话的方法,所有的手机都会有打电话的功能。

抽象类

abstract class Phone{
    abstract void call();
    
}

接口 

interface Phone{
    void call();
}

现在增加一个功能“上网”surf,

抽象类变成了:

abstract class Phone{
    abstract void call();
    abstract void surf();
    
}

接口变为:

interface Phone{
    void call();
    void surf();
}

 但是这样就有些问题出现了,phone中除了固定有的方法外还混进去了一个 surf功能,这样依赖于phone模块的就必学会上网,但是每个手机不一定都能上网(老年机)。这样就违反了设计原则,接口污染。

解决方法

一个使用接口,一个使用抽象类

abstract class Door{
    abstract void open();
    abstract void close();
}

interface Alarm{
    void alarm();
}

class AlarmDoor extends Door implements Alarm{
    void open(){}
    void close(){}
    void alarm(){}
}

这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其实抽象类表示的是"is-a"关系,接口表示的是"like-a"关系。

总结

  • 抽象类表示的是一种继承关系,只能单继承。接口表示的是一种行为规范,可以实现多个接口
  • 抽象类可以拥有自己的成员变量和非抽象方法,接口中只能有静态常量,所有的方法都没有实现的
  • 抽象类和接口的设计理念是不一样的,抽象类体现的是is-a关系,而接口代表的是like-a关系

抽象类和接口是java中两种不同的抽象概念,他们的存在对多态提供了好的支持,虽然他们之间语法上有很多相似性,但是他们的设计上往往体现了对问题的理解。只有对问题更好理解,才能更好设计接口和抽象类。

参考资料:作者: chenssy 
出处: http://www.cnblogs.com/chenssy/ 

猜你喜欢

转载自blog.csdn.net/sinat_38430122/article/details/82965320
今日推荐