• java 面向对象接口的应用


    简介

    上几篇一直在说面向对象理论中的抽象类的一些具体应用。今天我来说说面向对象理论中另一个关键的东西。接口。抽象类是类,接口是特殊的抽象类。为什么要用那么多时间来研究抽象类和接口呢?因为只有这二个理论我们掌握了、理解了。会用了。才能大大提高程序的可扩展性和可维护性。以后在学什么设计模式也是一层窗户纸一捅就破。

    概念

    Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
    两种含义:(概念摘录于百度百科)
    1. Java接口,Java语言中存在的结构,有特定的语法和结构;
    2. 一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫做“Java接口”,后者叫做“接口”。

    我个人理解,接口=>口号 相关于口号  具体的工作由下面的人来完成  

    例如:某领导在开会时对手下的人说,我们公司想要开发一个跑步时计算卡罗里的手环,最终结果可在手机上显示出来。手机与蓝牙连接方式采用蓝牙技术。

    这就是口号。具体的手机蓝牙如何和手环相连接,数据如何显示在手机上等等的技术问题,领导不关。这些个工作主要由手下的人去做。从面向对象理论上来讲这就是接口。

    接口,英文称作interface,在软件工程中,接口泛指供别人调用的方法或者函数。从这里,我们可以体会到Java语言设计者的初衷,它是对行为的抽象。在Java中,定一个接口的形式如下:

    语法格式:

    [public] interface Person {
        abstract void Study() throws Exception;//抽象方法,具体的功能由子类来完成
    }

    大家是不是觉得,接口和前面讲的抽象类很像。是的。接口和抽象类。这两者有太多相似的地方,又有太多不同的地方。很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然。

    抽象类是类,接口是接口

    简单点说就是:抽象类的子类不能再继承其他的类,可以实现多个接口.因为java是单继承的.

    讲接口的时候离不开抽象类。如果单独的去讲,失去了其本质的内容。有的培训中心的老师在讲解的时候,是单独举例讲解的。很坑人。

    下面我以一个例子来说明在实际开发中接口和抽象类是如何使用的。

    记住面向对象编程,其实就是面向接口编程。Java是单继承的,但是可以实现多个接口。这就是Java代码的神奇之处。很多的设计模式也是利用了这一点。

    举例子分析:

           狗、兔子、鱼  这三个动物为例

    按照我前面所讲的。大家很快就能把抽象类设计出来。如果还不能也没有关系。在把我们所讲结合百度一起在看一遍。

    1 public abstract class Animal {
    2         public abstract void Breathing();//呼吸
    3         public abstract void Eat();//
    4         public abstract void Swimming();//游泳
    5 }

    抽象类有了。我们现在设计 狗、兔子、鱼这三个子类。

     1 public class Dog extends Animal {
     2 
     3     @Override
     4     public void Breathing() {
     5         System.out.print("呼吸空气的感觉真好");
     6     }
     7 
     8     @Override
     9     public void Eat() {
    10         System.out.print("主人给我骨头吃了");
    11     }
    12 
    13     @Override
    14     public void Swimming() {
    15         System.out.print("游泳的感觉真好");
    16     }
    17 }
     1 public class Fish extends Animal {
     2 
     3     @Override
     4     public void Breathing() {
     5         System.out.print("呼吸空气的感觉真好");
     6     }
     7 
     8     @Override
     9     public void Eat() {
    10         System.out.print("我在吃东西");
    11     }
    12 
    13     @Override
    14     public void Swimming() {
    15         System.out.print("水中的感觉真好");
    16     }
    17 }

    最后是兔子类。

     1 public class Rabbit extends Animal {
     2 
     3     @Override
     4     public void Breathing() {
     5         System.out.print("呼吸空气的感觉真好");
     6     }
     7 
     8     @Override
     9     public void Eat() {
    10         System.out.print("胡萝卜真好吃");
    11     }
    12 
    13     @Override
    14     public void Swimming() {
    15         System.out.print("5555555555555,我不会游泳");
    16     }
    17 }

    发现问题了吧,兔子不会游泳,因为是继承的关系。以后每一个动物不管会不会游泳都要重写那个Swimming方法。要知道不是每个动物都会游泳的。

    怎么办。有人说在写一个游泳功能的类,让其继承。亲 Java只支持单继承,不支持多继承,但是可但是但可是呢?可以支持多接口。在这里我们不需要那么多的接口一个就够了。

    先把抽象类的代码改一下

    1 public abstract class Animal {
    2         public abstract void Breathing();//呼吸
    3         public abstract void Eat();//
    4 }

    那个游泳功能怎么办。我们单独写一个接口

    1 public interface AnimalBehavior {
    2     public abstract void Swimming();//游泳
    3 }

    那该怎么用呢?我们将上面的 狗、鱼的子类改一下

     1 public class Dog extends Animal implements AnimalBehavior{
     2 
     3     @Override
     4     public void Breathing() {
     5         System.out.print("呼吸空气的感觉真好");
     6     }
     7 
     8     @Override
     9     public void Eat() {
    10         System.out.print("主人给我骨头吃了");
    11     }
    12 
    13     @Override
    14     public void Swimming() {
    15         System.out.print("游泳的感觉真好");
    16     }
    17 }
     1 public class Fish extends Animal implements AnimalBehavior {
     2 
     3     @Override
     4     public void Breathing() {
     5         System.out.print("呼吸空气的感觉真好");
     6     }
     7 
     8     @Override
     9     public void Eat() {
    10         System.out.print("我在吃东西");
    11     }
    12 
    13     @Override
    14     public void Swimming() {
    15         System.out.print("水中的感觉真好");
    16     }
    17 }

    兔子类

     1 public class Rabbit extends Animal {
     2 
     3     @Override
     4     public void Breathing() {
     5         System.out.print("呼吸空气的感觉真好");
     6     }
     7 
     8     @Override
     9     public void Eat() {
    10         System.out.print("胡萝卜真好吃");
    11     }
    12 }

    抽象类与接口的区别

    Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方,才是它们的最佳位置呢?把它们比较一下,你就可以发现了。

    Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以(就是interface中只能定义方法,而不能有方法的实现,而在abstract class中则可以既有方法的具体实现,又有没有具体实现的抽象方法),这大概就是Java抽象类唯一的优点吧,但这个优点非常有用。如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个 新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点。这个在我的另外一篇博客mapreduce 新旧API 区别中有提到类似的问题,在新的mapreduce api中更倾向于使用抽象类,而不是接口,因为这更容易扩展。原因就是上面划线部分所说的。

    一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。(使用抽象类,那么继承这个抽象类的子类类型就比较单一,因为子类只能单继承抽象类;而子类能够同时实现多个接口,因为类型就比较多。接口和抽象类都可以定义对象,但是只能用他们的具体实现类来进行实例化。)

    从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。

    结合1、2点中抽象类和Java接口的各自优势,具精典的设计模式就出来了:声明类型的工作仍然由Java接口承担,但是同时给出一个Java 抽象类,且实现了这个接口,而其他同属于这个抽象类型的具体类可以选择实现这个Java接口,也可以选择继承这个抽象类,也就是说在层次结构中,Java 接口在最上面,然后紧跟着抽象类,这下两个的最大优点都能发挥到极至了。这个模式就是“缺省适配模式”。在Java语言API中用了这种模式,而且全都遵循一定的命名规范:Abstract +接口名。(A extends AbstractB implements interfaceC,那么A即可以选择实现(@Override)接口interfaceC中的方法,也可以选择不实现;A即可以选择实现(@Override)抽象类AbstractB中的方法,也可以选择不实现)

    继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者有没有飞行这个特点)

    感悟

    简单的业务设计起来容易,复杂的业务要想把其按面向对象理论方式进行设计。得需要一定的经验来我们对技术孜孜不倦的追求。和对业务的深入理解。软件开发不要以为就是编写代码。其实不然这里面充满的智慧和挑战。

    如果你对你要开发的业务流程不熟悉。你设计模式学的再好,你也会感到无从下手。当你对业务熟悉了,设计模式也精通了。您一定是在那个领域中的领军人物。将来知深架构师这个头衔非你莫属。

    声明如下:

    1. 学会用面向对象思想解决问题,是作为程序员一个良好的习惯。
    2. 技术无止境,学习无止境。我只是起到一个入门和抛砖引玉的作用。
    3. 因为本人有很多的工作要做。写这个主要是利用业余时间。难免代码有错误的地方。或文字上有错别字。还是这句话,写这些主要是教大家如何学习。理论掌握了,语言只是工具。谢谢大家在百忙之中观看此文。
    4. 文中代码实现,已经测试过:
    5. 我写的内容可以随便转载,欢迎大家转载。
  • 相关阅读:
    vue1.0
    网络抓包(四)
    物联网框架ServerSuperIO
    Solrcloud(Solr集群)
    机器学习1
    TCP/IP协议族(一)
    ElasticSearch(简称ES)
    工具
    线程本地变量的使用
    Features of Spring Web MVC
  • 原文地址:https://www.cnblogs.com/littlestone/p/4307957.html
Copyright © 2020-2023  润新知