抽象类和抽象方法

抽象方法是指没有具体实现的方法,仅仅有方法的声明和没有方法体;使用abstract关键字定义一个抽象方法;包含抽象方法的类成为抽象类,如果一个类中包含抽象方法则必须使用abstract来限定该类为抽象类;抽象类不能实例化对象,抽象类的子类必须对所有的抽象方法提供方法定义,否则仍然是抽象类,且必须用abstract来限定;

接口

接口是一个完全抽象的类,没有提供任何具体的实现,只提供了具体的方法形式(方法名、参数列表、返回值);由于类是通过接口和外部通信,接口被用来建立类和类之间的协议(protocol);使用interface代替class定义一个接口,在接口中,所有的方法都是public的,就算不添加public,也会自动成为public,否则这将限制接口的意义;

接口中除了抽象方法,还可以包含域,但是这些域将隐式地成为static和final的(常量,用大写字母表示)并且不可以是空final,可以被常量表达式初始化这些域并不是接口的一部分,而是存储在该接口的静态存储区域内;

让一个类遵循某个(或者某组)特定的接口,需要使用implements关键字,表示该类使用的接口的样子,以及该类将对接口中的方法做具体实现;

示例代码中,Wind、Percussion、Stringed都使用了Instrument接口,表名这四个类(接口)都具有相同的行为;从Wind派生出两个子类:Brass、Woodwind,这两个子类也可以通过向上转型,使用该接口;

完全解耦

接口相对于继承的意义是:如果方法操作的是类,那么该方法只能使用这个类及其子类,否则将会出错;而通过方法操作一个接口,则没有该限制,只要满足该接口的类都可以被调用;

创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,称为策略设计模式;如:

publicclass Apply {

    public static void process(Processor p, Object s){

        println("Using Processor " + p.name());

        println(p.process(s));

    }

}

 

Apply.process()方法接收一个Processor对象,并将其应用到Object对象上;根据不同Processor接口的实现(策略),该方法对Object可以有不同的行为;

当Processor是一个类时,Apply.process()方法和Processor之间是紧耦合的,只能接收该类或者其子类的对象,当一个具有相同接口的其他类使用该方法时,复用会被禁止;而当Processor是一个接口时,耦合就会松动,只要是相同接口的类的对象都可以接收;

如果已有一个类Filter,要将其改变成Processor接口的类,则需要使用到适配器:

class FilterAdapter implements Processor{

    Filter filter;

    FilterAdapter(Filter filter){

        this.filter = filter;

    }

    public String name() {

        return filter.name();

    }

    public Object process(Object input) {

        return filter.process((Waveform)input);

    }

}

 

该类使用了Processor接口,并接受一个Filter对象,用代理的方式,将Filter对象像Processor接口适配;

见:示例代码,其中依赖的部分见相同路径下的各个类文件;

多重继承

示例代码中,Hero继承了基类ActionCharacter,并且继承了三个接口:CanSwim、CanFight、CanFly;此时,具体基类必须放在前面,而接口放到后面并且用逗号隔开;

在Adventure中,实现了四个方法,并且传入不同的接口和类,而Hero对象可以被传递到这些接口或者类中的任何一个;

接口可以通过继承其他的接口来进行扩展,使用extends进行扩展,并且如果继承多个接口,则使用逗号隔开(extends用于类时,只适用于单一类);

在使用多重继承时,应该避免多个不同接口中存在相同的方法名,这样做会造成代码可读性的混乱;

通过多重继承,可以对适配器进行功能扩展,使其可以在任何现有类之上添加接口,让现有类适配成某个方法;

接口与工厂

如在示例代码中,使用工厂方法,避免在使用某一个Service类的对象时,调用特定的构造方法,而是使用一个特定接口的工厂方法,并在其中实现构造函数的调用,此时,只要对该接口进行实现即可;

有关工厂方法的讨论在Effective Java中也提到,目前只有一个主观认识,需要在使用中加深;

thinkinginjava学习笔记08_接口的更多相关文章

  1. No2_1.接口继承多态_Java学习笔记_接口

    接口.继承与多态 1.继承和多态是面向对象开发语言中的重要一个环节,使用得当,可以将整个程序的架构变得非常有弹性,减少代码冗余: 2.继承:复用定义好的类: 3.多态:可以动态调整对象的调用,降低对象 ...

  2. thinkinginjava学习笔记07_多态

    在上一节的学习中,强调继承一般在需要向上转型时才有必要上场,否则都应该谨慎使用: 向上转型和绑定 向上转型是指子类向基类转型,由于子类拥有基类中的所有接口,所以向上转型的过程是安全无损的,所有对基类进 ...

  3. thinkinginjava学习笔记06_复用类

    MarsEdit粘代码好麻烦,所有代码交给github:https://github.com/lozybean/MyJavaLearning 复用一个类常用的两种方式:组合.继承: 组合 将对象引用置 ...

  4. thinkinginjava学习笔记01_导论

    初学java,希望旅途愉快  :) 类型决定对象的接口,(有人认为类是类型的特定实现),接口确定对象所能发出的请求(消息),满足请求的代码和隐藏的数据一起构成实现: 对象设计时,应该很好地完成一项任务 ...

  5. Java 学习笔记(7)——接口与多态

    上一篇说了Java面向对象中的继承关系,在继承中说到:调用对象中的成员变量时,根据引用类型来决定调用谁,而调用成员方法时由于多态的存在,具体调用谁的方法需要根据new出来的对象决定,这篇主要描述的是J ...

  6. Java学习笔记 07 接口、继承与多态

    一.类的继承 继承的好处 >>使整个程序架构具有一定的弹性,在程序中复用一些已经定义完善的类不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性 继承的基本思想 >>基 ...

  7. Java学习笔记之接口

    一.接口的概念与定义 首先考虑一个简单的接口的定义: public interface Output { int MAX_LINE = 40; void out(); void getData(Str ...

  8. Java学习笔记之接口和抽象类

    接口(interface)1.interface创建一个接口,implements实现接口 interface jiekou{} class lie implements jiekou{}2.接口可以 ...

  9. 1)Java学习笔记:接口和抽象类的异同

    Java接口和抽象类很像,他们有哪些相同点和异同点呢,下面我们做一个小结 相同 ① 都不能被实例化,都位于继承树的顶端,用于被实现或者继承 ② 都可以包含抽象方法,实现接口或者继承抽象类的普通子类都必 ...

随机推荐

  1. BP算法从原理到python实现

    BP算法从原理到实践 反向传播算法Backpropagation的python实现 觉得有用的话,欢迎一起讨论相互学习~Follow Me 博主接触深度学习已经一段时间,近期在与别人进行讨论时,发现自 ...

  2. eclipse中Cannot change version of project facet Dynamic Web Module to 2.5.

    Cannot change version of project facet Dynamic Web Module to 2.5.这个错误可能很多人都碰到过,这里网上查了一些资料,解决的问题.所以这里 ...

  3. java 之 桥接模式(大话设计模式)

    桥接模式定义为:将抽象部分与它的实现部分分离,使它们都可以独立的变化. 第一次看设计模式的时候,不是很清楚这句话的意思,随着笔者的不断开发,发现有一种场景, 继承关系多了,不易于维护父类,而笔者认为桥 ...

  4. sed命令针对文件操作具体解释

    Linux的简单shell脚本中改动文件操作 1.Sed简单介绍 sed 是一种在线编辑器,它一次处理一行内容.处理时.把当前处理的行存储在暂时缓冲区中,称为"模式空间"(patt ...

  5. keeplived日志位置指定

    作为一个运维DBA,除了关心数据库的关键指数.还得往架构和底层基础知识多靠拢. 2010年刚工作的时候,那会Cacti监控比較流行吧.可恶的是SNMP会把默认日志写到系统日志文件中面,导致排错时非常受 ...

  6. EventBus猜想 ----手把手带你自己实现一个EventBus

    本文是什么 本文是一篇怀着推測角度学习一个未知东西(EventBus)的文章. 先推測EventBus是怎样实现的. 依据推測去模仿他的实现. 查看源代码.验证猜想. 更深入的去理解他. 转载请注明出 ...

  7. js实现刷新

    Javascript刷新页面的几种方法: 代码如下:1,history.go(0) 2,location.reload() 3,location=location 4,location.assign( ...

  8. python实现斐波那契数列(Fibonacci sequence)

    使用Python实现斐波那契数列(Fibonacci sequence) 斐波那契数列形如 1,1,2,3,5,8,13,等等.也就是说,下一个值是序列中前两个值之和.写一个函数,给定N,返回第N个斐 ...

  9. WebApi的多版本管理

    1.多版本管理概念 什么是API的多版本问题?Android等App存在着多版本客户端共存的问题:由于早期没有内置升级机制,用户不会升级,拒绝升级等原因,造成了许多软件的旧版本App也在运行.开发新版 ...

  10. JavaScript 中 闭包 的详解

    闭包是什么 在 JavaScript 中,闭包是一个让人很难弄懂的概念.ECMAScript 中给闭包的定义是:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量. ...