JAVA整理

Java成长之路(九)

Posted by MiaoMiaoMiao on February 5, 2021

Java成长之路九

接口

  • 接口与抽象类提供了一种将接口与实现分离的更加结构化方法;
  • 抽象类是一种介于普通类和接口之间的这种手段;

抽象类和方法

  • 通用接口建立了一个基本形式:以此表达所有派生类的共同部分,另一种方法是把Instrument称为抽象基类,简称抽象类;
  • 对于像Instrument那样的抽象类来说,它的对象几乎总是没有意义的;
  • 创建一个抽象类是为了通用接口操作一系列类;
  • 抽象方法:abstract void f();包含抽象方法的类叫做抽象类,如果一个类包含一个或多个抽象方法,那么类本身必须是抽象类;
  • 如果抽象类是不完整的新类并为之创建对象,那么必须为基类的所有抽象方法提供方法定义,如果不那么做,新类也是一个抽象类,编译器会为我们加上abstract关键字;
  • 可以将一个不包含抽象方法的类指明为abstract;
  • @Override的使用,没有这个注解的话,如果没有定义相同额方法或签名,抽象机制会认为没有实现抽象方法从而产生编译时错误;
  • 接口只允许public方法,如果不加访问修饰符的话,接口的方法不是friendly而是Public;
  • 创建抽象类和抽象方法是有帮助的,因为它们使得类的抽象性很明确,并能告知用户和编译器使用意图,抽象类同时也是一种有用的重构工具,使用它们使得我们很容易地沿着继承层级结构上移公共方法。

接口创建

  • 使用interface关键字创建接口;
  • 我们只能描述类应该像什么,做什么,但不能描述怎么做,即只能决定方法名,参数列表和返回类型,但无法确定方法体。接口只提供形式,通常来说没有实现;
  • 一个接口表示:所有实现了该接口的类看起来都像这样,因此,任何使用某特定接口的代码都知道可以调用该接口的哪些方法,而且仅知道这些,而且仅需知道这些,所以接口被用来建立类之间的协议;
  • Java8允许接口包含默认方法的静态方法,基于某些原因,介于类型之上,实现之下;
  • 接口与抽象类最明确的区别可能就是使用上的惯用方式,接口的典型使用是代表一个类的类型或一个形容词如Runnable或Serializable,而抽象类通常是类层次结构的一部分或一件事物的类型,如String或ActionHero;
  • interface同样具备相同的访问权限;
  • 接口同样包含属性,这些属性指明static和final;

默认方法

  • Java8为关键字default增加了一个新的用途(之前只用于Switch,当在接口中使用之时,任何是实现接口和没有定义方法的时候可以使用default创建的方法体。默认方法从抽象类中的方法受到更多的限制,但是非常有用)
  • 若使用default为接口方法提供实现,所有与接口相关的代码能正常工作,不受影响,而且这些代码还可以调用新的方法;
  • 增加默认方法的理由是允许在不被破坏已使用接口的代码的情况下,在接口增加新方法,默认方法也被称为守卫方法或虚拟扩展方法;

多继承

  • Java过去是一种严格要求单继承的语言;只能继承自一个类(或抽象类),但可以实现任意多个接口;
  • 结合带有默认方法的接口意味着结合了多个基类中的行为,因为接口中不允许存在属性(只有静态属性,不适用),所以属性仍然只会来自单个基类或抽象类,不存在状态的多继承;
  • 可以重定义接口方法,但是需要像上例使用super关键字选择基类实现中的一种;

接口中的静态方法

  • 接口添加静态方法,能恰当地把工具功能置于接口中,从而操作接口或者成为通用的工具;
  • 接口的工作方式使得我们不需要显式地声明其中的方法为public,它们自助就是public;
  • 还是叫作Instrument的接口,其行为都是相同的,事实上,从tune()方法上看不出来instrument到底是普通类,抽象类还是个接口;

抽象类和接口

  • 抽象类任然是一个类,在创建新类只能继承定一个,而创建类的过程中可以实现多个接口;
  • 在合理的范围内尽可能地抽象,因此更倾向于使用接口而不是抽象类,只有必要时才使用抽象类,否则不要用接口和抽象类。大多数时候,普通类做的很好,如果不行的话,再移动到接口或抽象类中;

接口

  • 组合:新类可以组合多个接口;
  • 状态:不能包含属性(除了静态属性,不支持对象状态)
  • 默认方法和抽象方法:不需要在子类中实现默认方法。默认方法可以引用其他接口的方法;
  • 构造器:没有构造器;
  • 可见性:隐式public;

抽象类

  • 组合:只能继承单一抽象类;
  • 状态:可以包含属性,非抽象方法可以引用这些属性;
  • 默认方法和抽象方法:必须在子类中实现抽象方法;
  • 构造器:可以有构造器;
  • 可见性:可以使protected或“friendly”;

完全耦合

  • 每当一个方法与一个类而不是一个接口,一起工作时(当方法的参数都是类而不是接口),你只能应用到那个类或它的子类,如果你想把它这方法应用到一个继承层次之外的类,是做不到的。接口在很大程度上放宽了这个限制,因此使用接口可以编写复用性更好的代码;
  • 创建一个能根据传入的参数类型从而具备不同行为的方法称为策略设计模式,策略包含变化的部分,策略就是传入对象,它包含要执行的代码;

多接口结合

  • 没有任何与接口相关的存储,无法阻止结合的多接口;
  • 派生类并不要求必须继承自抽象的或“具体的”(没有任何抽象方法)的基类,如果继承一个非接口的类,那么只能继承一个类,其余的基元素必须都是接口,需要将所有的接口名称置于implements关键字之后且用逗号分隔;可以有任意多接口,并可以向上转型为毎个接口,因为每个接口都是独立的类型;
  • 为了能够向上转型为多个基类型(以及由此带来的灵活性),然而,使用接口的第二个原因与使用抽象基类相同:放置客户端程序员创建这个类的对象,确保这仅仅是一个接口。如果创建不带任何方法定义或成员变量的基类,就这样接口而不是抽象类。事实上,如果知道某事物是一个基类,可以考虑用接口实现它;

使用继承扩展接口

  • 通过继承,可以很容易在接口中增加方法声明,还可以在新接口汇总,结合多个接口;
  • 在不同的接口中使用相同的方法通常会造成代码可读性的混乱,尽量避免这种情况;

接口适配

  • 接口最吸引人的原因之一是相同的接口可以有多个实现,在简单情况下提现在一个方法接受接口作为参数,该接口的实现和传递对象则取决于方法的使用者;
  • 策略设计模式,编写一个方法执行某些操作并接受一个指定的接口作为参数。只要对象遵循接口,就可以调用方法。
  • 在已有的类中增加新接口,意味着一个接受接口类型的方法提供了一种让任何类都可以与该方法进行适配的方式;

接口字段

  • 因为接口中的字段自动是static和final,所以接口就成为了创建一组变量的方便工具;
  • Java中使用大写字母的风格定义具有初始化值的static final变量,接口中的字段自动式public的,所有没有显式指明这点;
  • 因为字段是static的,所以在类第一次被加载时初始化,它们的值被储存在接口的静态存储区域中;
  • 接口嵌套中,private接口不能在定义它的类之外被发现;

接口和工厂方法模式

  • 生成某个接口的对象的典型方式是工厂方法设计模式,不同于直接调用的构造器,只需调用工厂对象中的创建方法就能生成对象实现,理论上这种方式可以将接口与实现代码完全分离;
  • 创建类都可以替代为创建一个接口或工厂,单任何抽象性都应该是由真正的需求驱动的,当有必要时才使用接口进行重构,而不是到处添加间接层,从而带来额外的复杂性;

bye