摘要:子类继承抽象类,并具体实现方法。抽象类的使用区别于具体类,抽象类无法直接创建抽象类对象,但是可以声明抽象类的变量,引用抽象类对应具体子类对象。接口优于抽象类中讨论到一条规则接口优于抽象类。接口声明能力,抽象类提供默认实现全部或部分方法。
接口
类,强调数据类型(自定义)的概念,在一些情况下,并不能反映对象以及对象操作的本质。有时我们关注的并非对象的类型,而是对象的能力。
接口声明一组功能,作为协议(约定),但是自身不去实现功能方法。接口形式的交互涉及两方对象:一方实现接口,另一方使用接口,双方并不直接依赖,而是针对接口编程。
接口定义
接口定义即声明方法,制定功能协议。
Java 使用 interface 关键字声明接口,修饰符一般采用 public。
接口内部声明方法时,通常不需要加修饰符,默认视为 public abstract。
接口实现
类可以实现接口,表示类的对象具有接口(协议)制定的功能。
Java 使用 implements 关键字实现接口。
实现接口必须实现接口中声明的所有方法。
public interface Printable { void print(); } public class A6 implements Printable { public void print() { System.out.println("Hello"); } public static void main(String args[]) { A6 obj = new A6(); obj.print(); } }
接口扩展
接口可以扩展另一个接口甚至多个接口,其方式与类可以扩展(继承)另一个类的方式相同,使用 extends 关键字,但是类的继承限制为单继承。
public interface BallGame extends Sport, Match {}
类的继承与接口实现可以共存,并且类可以实现多个接口,从某种形式上构成多继承结构。
public class Football extends Ball implements Sport, Match {}
等价于:
public class Football extends Ball implements BallGame {}
接口使用
与类不同,无法直接 new 创建接口对象,但是可以声明接口类型的变量,引用实现了接口的类对象。
public interface Printable { void print(); } public class Main { public static void main(String args[]) { Printable obj = new Printable() { @Override public void print() { System.out.println("Hello"); } } obj.print(); } }
上述代码看似创建接口对象,实则创建匿名内部类对象,由其实现接口。
接口有时更能反映出对象的本质(能力,一组功能协议)。所谓针对接口编程,使用接口而非具体实现接口的类型,统一处理不同类型对象,旨在降低耦合性,提高灵活性。当然,接口本身由于没有代码实现,并没有太大用处,需要依赖具体实现,才能生效。
抽象类抽象类,顾名思义抽象的类,一般代表多个具体类(子类)上层公共的父类,作为基类统一调用接口(方法)。
抽象类的意义抽象方法和抽象类密不可分,抽象方法是将来作为统一接口调用,而目前不知道如何实现的方法,只有通过子类重写方法才能具体实现功能。
抽象类 Animal 定义 sound() 方法作为统一接口调用,因为无法确定 sound() 方法该如何具体实现,Java 使用 abstract 关键字声明方法为抽象方法,无需定义方法体。子类 Dog 继承抽象类 Animal,并具体实现 sound() 方法。
//abstract parent class abstract class Animal { //abstract method public abstract void sound(); } //Dog class extends Animal class public class Dog extends Animal { public void sound() { System.out.println("Woof"); } public static void main(String args[]) { Animal obj = new Dog(); obj.sound(); } }抽象类的使用
区别于具体类,抽象类无法直接 new 创建抽象类对象,但是可以声明抽象类的变量,引用抽象类对应具体子类对象。
定义了抽象方法的类必须声明为抽象类,但是抽象类可以没有抽象方法。
抽象类和具体类一样,可以定义并实现具体方法,实例变量等。
一个类在继承抽象类后,必须实现抽象类的所有抽象方法,除非类自己也声明为抽象类。
抽象类介于接口和类之间。
接口与抽象类的区别及应用场景相同点
无法创建对象(实例化)
抽象方法由具体类实现(统一接口)
作为引用变量指向具体类对象(多态性)
不同点
对比条件 | 接口 | 抽象类 |
---|---|---|
构造器 | 不存在 | 可以有 |
具体方法 | 不存在 | 可以有 |
实例变量 | 不存在 | 可以有 |
“多继承” | 支持 | 不支持 |
接口 = 纯抽象类(所有方法都是抽象方法)
应用场景
考虑多态性、统一接口调用的同时,需要实例变量、带有默认实现的具体方法,使用抽象类。
声明一组方法,却又不想每个具体类都实现所有方法,可以使用抽象类,借助空方法,交由具体类自行决定重写其感兴趣的方法。
具体类已经有父类,受 Java 限制只允许单继承,只能选择通过实现接口方式扩展类。
《Effective Java》中讨论到一条规则:“接口优于抽象类”。基于如下论断:
现有的类可以很容易被更新,以实现新的接口。
一般来说,无法更新现有的类来扩展新的抽象类。如果希望让两个类扩展同一个抽象类,就必须把抽象类放到类型层次的高处,这样会间接地伤害到类层次,迫使这个公共祖先的所有子类都扩展这个新的抽象类。接口是定义 mixin(混合类型)的理想选择。
混合类型除了自身类型之外,还可以提供某些可选择的行为。例如,实现 Comparable 接口的实例之间可以相互比较。接口允许我们构造非层次结构的类型框架。
类型层次对于组织某些事物是非常合适的,但是并非所有事物都能被整齐地组织成一个严格的层次结构。类层次过于臃肿缺乏灵活性,通过接口扩展行为,一定程度上模拟多重继承。
P.S. Java 限制只允许单继承,即类不可能有一个以上的父类。
规则存在例外,即当演变的容易性比灵活性和功能更为重要的时候,应该使用抽象类来定义类型。抽象类的演变比接口的演变要容易得多,当在抽象类中增加新的具体方法,它包含合理的默认实现,该抽象类的所有现有实现都将提供这个新的方法。接口一旦被公开发行,并且已被广泛实现,再想改变这个接口几乎是不可能的。当在公有接口中增加方法,不可避免破坏实现这个接口的所有现有的类。
书中建议程序员为“每个重要接口都提供一个抽象的骨架实现(skeletal implementation)类,把接口和抽象类的优点结合起来。接口的作用仍然是定义类型,但是骨架实现类接管了所有与接口实现相关的工作。”
Java 类库中存在许多一个接口对应一个抽象类的设计,例如:Collection 接口与 AbstractCollection 抽象类、List 接口与AbstractList 抽象类...。
抽象类和接口是配合而非替代关系。接口声明能力,抽象类提供默认实现(全部或部分方法)。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71771.html
摘要:依赖倒置原则是个设计原则中最难以实现的原则,它是实现开闭原则的重要途径,依赖倒置原则没有实现,就别想实现对扩展开放,对修改关闭。 1、单一职能原则(Single Responsibility Principle, SRP) 定义 There should never be more than one reason for a class to change.应该有且仅有一个原因引起类的...
摘要:在我们做系统设计时,经常会设计接口或抽象类,然后由子类来实现抽象方法,这里使用的其实就是里氏替换原则。 1.开闭原则(Open Close Principle/OCP) 定义:一个类、模块和函数应该对扩展开放,对修改关闭。 开放-封闭原则的意思就是说,你设计的时候,时刻要考虑,尽量让这个类是足够好,写好了就不要去修改了,如果新需求来,我们增加一些类就完事了,原来的代码能不动则不动。这个...
摘要:单一职责原则可以看做是低耦合高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。抽象的稳定性决定了系统的稳定性,因为抽象是不变的,依赖于抽象是面向对象设计的精髓,也是依赖倒置原则的核心。 Java-面向对象 什么是面过程 把题分解成一个一个步骤,每个步骤用函数实现,依次调用即可。就是说,在进行面向过程 编程的时候,不需要考虑那么多,上来先定义一个...
摘要:前言是面对对象的语言,因此有必要单独纪录下对象的各种定义和理解。面对对象基本概述概述是基于面向过程的变成思想,是对面向过程的一种封装。面对对象开发就是不断的创建对象,使用对象,指挥对象做事情。面对对象设计其实就是在管理和维护对象之间的关系。 前言 java是面对对象的语言,因此有必要单独纪录下对象的各种定义和理解。 面对对象,主要包括:面向对象思想,类与对象及其使用,对象的内存图,成...
摘要:类的适配器结构目标角色这就是所期待得到的接口,由于是类适配器模式,因此目标不可以是类。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。和适配器模式的关系适配器模式的用意是改变所考虑对象的接口,而代理模式不能改变。 点击进入我的博客 3.1 适配器模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口,使得原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 3...
阅读 2597·2021-09-28 09:36
阅读 2212·2021-09-07 09:58
阅读 1469·2019-08-26 13:53
阅读 1256·2019-08-23 17:53
阅读 3001·2019-08-23 15:34
阅读 1829·2019-08-23 15:34
阅读 2839·2019-08-23 12:04
阅读 3691·2019-08-23 10:56