Java面向对象之抽象类、接口

在之前的文章中,我们依次介绍了类与对象、面向对象三大特征的封装、以及继承(一)、继承(二) 和 多态。本文我们接着补充抽象类和接口。


抽象类

抽象类的应用场景:

  1. 定义一个类时,常需要定义成员方法来描述类的行为特征,若该类的成员方法无法确定,需要在子类中实现不同的行为时可用作抽象类。

例如Animal类中的shout()方法用来描述动物的叫声,不同动物的叫声不同,因此Shout就无法确定,Cat类与Dog类的shout()必然不同。

  1. 当需要创建一个类,该类不会被实例化而只会被用作其他类的父类时,可用作抽象类

  2. 抽象类的声明格式:
    使用abstract关键字来修饰类,且加在class前面。
    抽象方法是将abstract关键字加在返回值类型。

    abstract class 抽象类名称{
    	属性;
    	访问权限 返回值类型 方法名称(参数){ //普通方法
    		return [返回值];
    	}
    	访问权限 abstract 返回值类型 抽象方法名称(参数); 	//抽象方法,无方法体
    }
    

抽象类的性质

  1. 一个有抽象方法的类,就必须定义为抽象类.在方法返回值类型左侧加abstract。
    抽象类不一定要有抽象方法。
  2. 抽象方法主要是为了指定规则让所有继承的子类都实现这个抽象方法
  3. 抽象类的子类,要么重写抽象类中的所有抽象方法要么子类自己也是抽象类。
  4. 抽象类除了不能实例化对象以及多了抽象方法,其他方面与普通类一样。
  5. 抽象方法只需要声明而不需要实现。
  6. 使用 abstract 关键字修饰的抽象方法不能使用 private 关键字修饰
    因为抽象方法必须被子类实现,如果使用了 private 关键字修饰抽象方法,则子类无法实现该方法。

抽象类不能被实例化的原因:

因为抽象类中包含了抽象方法,这些抽象方法没有具体的实现,需要在子类中进行实现。
因此,实例化抽象类将导致无法完成所有抽象方法的实现,从而违反了抽象类的设计初衷。所以,抽象类只能作为父类被继承,而不能被直接实例化。

接口

接口的概述:

  1. 接口的定义:

    一种用来定义程序的协议,它用于描述类或结构的一组相关行为。
  2. 接口是由抽象类衍生的一个概念,并由此产生了一种编程方式,可以称这种编程方式为面向接口编程。
    面向接口编程就是将程序的不同的业务逻辑分离,以接口的形式对接不同的业务模块
    接口中不实现任何业务逻辑业务逻辑由接口的实现类完成。当业务需求变更时,只需要修改实现类中的业务逻辑,而不需要修改接口中的内容,以减少需求变更对系统产生的影响

例子:通过现实生活中的例子来类比面向接口编程。例如,鼠标、U 盘等外部设备通过USB 接口来连接计算机,即插即用,非常灵活。如果需要更换与计算机连接的外部设备,只需要拔掉当前 USB 接口上的设备,把新的设备插入即可,这就是面向接口编程的思想。

  1. 在Java 中,使用接口的目的是克服单继承的限制,因为一个类只能有一个父类,而一个类可以同时实现多个父接口。
    在JDK 8之前,接口是由全局常量和抽象方法组成的
    JDK 8对接口进行了重新定义,接口中除了抽象方法外,还可以定义默认方法和静态方法,默认方法使用 default 关键字修饰静态方法使用 static 关键字修饰,而且这两种方法都允许有法体。

接口的语法

  1. 接口使用interface声明,格式如下:

    [public] interface 接口名 [extends 接口1,接口2,..]{    //继承多借口
    	[public][static] [final] 数据类型 常量名 =常量;    //全局变量
    	[public] [abstract] 返回值的数据类型 方法名(参数列表); //抽象方法
    	[public] static 返回值的数据类型 方法名(参数列表){}  //静态方法
    	[public] default 返回值的数据类型 方法(参数列表){}   //默认方法
        //接口中的变量默认使用 public static final 进行修饰,即全局常量。接口中定义的抽象方法默认使用 public abstract 进行修饰。
        //在很多的 Java 程序中,经常看到编写接口中的方法时省略了 public,有很多读者认为它的访问权限是 default,这实际上是错误的。不管写不写访问权限,接口中方法的访问权限永远是 public。
    }
    
  2. 定义接口实现类使用implements,格式如下:
    注意:类不是继承接口,是类实现接口

修饰符 class 类名 implements 接口 1,接口 2,……{
    ……
}

接口的性质

  1. 接口不能实例化:我们可以创建接口的实现类对象使用
    接口的子类(实现类):要么重写接口中的所有抽象方法,要么子类也是抽象类
    (一般在层级结构比较多的框架中会遇到)

  2. 抽象类其实是一个半虚半实的东西,可以全部为虚,这时候变成接口。
    接口就是虚到极点的抽象类。也即是说接口是特殊的抽象类。

  3. 当类实现接口的时候,类要实现接口中所有的抽象方法否则类必须声明为抽象类

  4. 接口本身不能直接实例化,接口中的抽象方法和默认方法只能通过接口实现类的实例对象进行调用

接口的成员特点(记忆):

  1. 成员变量

    • 只能是常量
    • 默认修饰符:public static final(公共的静态的无法改变的)
  2. 构造方法

    没有,因为接口主要是扩展功能的,而没有具体存在

  3. 成员方法

    1.8之前只能是抽象方法,默认修饰符public abstract

  4. 接口的方法只能是 抽象的,静态的,默认的

  5. 接口中的私有方法

    • 和类中的定义方式引用,即只能在接口的内部使用

    • 一般在接口内部,多个默认方法或者多个静态方法,有很多共性的代码时,就可以抽取出来放到私有方法中

类与接口

类和接口的多种关系

  1. 类继承类
  2. 类实现接口,且支持多个实现
  3. 接口继承接口,且支持多继承
    子接口会继承父接口的所有抽象方法,

子类访问优先级

倘若一个子类,同时继承一个父类和实现一个接口,并且父类与接口有同样的方法,子类优先使用继承的父类的方法

    [访问修饰符] class 类名 implements 接口名1,接口名2……{ }
    [访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{ }
extends在前面,implements在后面

下面是《Java面向对象三大特征》这几篇文章的参考链接:
(1) (2) (3) (4) (5)
(6) (7) (8) (9) (10)
(11) (12) (13) (14)

你可能感兴趣的:(Java语言基础,java,开发语言,接口,职场和发展)