Java中比较抽象类与接口的异同
作者:cookies_k 发布时间:2023-09-24 01:50:40
一.抽象类
(一)概念
在继承的层次结构中,每个新的子类都使类变得更加明确和具体。如果从一个子类向父类追溯,类就会变得更通用、更加不明确。类的设计应该确保父类包含它的子类的共同特征。有时候,一个父类设计得非常抽象,以至于它都没有任何具体的实例。这样的类称为抽象类(abstract class)。在类的头部使用 abstract 修饰符表示该类为抽象类。
(二)抽象类和抽象方法
同样用 abstract 声明抽象方法。抽象方法(abstract method)只定义成员方法的接口形式,而没有具体操作。只有派生类对抽象成员方法的重定义才能真正实现与该派生类相关的操作。在各子类继承了父类的抽象方法之后,再分别用不同的语句和方法体来重新定义它,形成若干个名字相同、返回值相同、参数列表相同、目的一致但是具体实现有一定差别的方法。抽象类中定义抽象方法的目的是实现一个接口,即所有的子类对外都呈现一个相同名字的方法。
1.一个包含抽象方法的类必须声明为抽象类
几点说明:
1.抽象类不一定有抽象方法,但有抽象方法的类一定是抽象类。
2.即使子类的父类是具体的,这个子类也可以是抽象的。
3.当父类的方法实现在子类中变得无效时,子类可以重写父类的方法并将它定义为抽象的。
2.抽象方法只有定义而没有实现,它的实现由子类提供
下面定义了一个抽象类Object类:
public abstract class Object {
public abstract double getArea();
public abstract double getPerimeter();
}
Object类是多个子类的父类,由于在多个子类中都要用到getArea()方法和getPermeter()方法,所以在父类中定义比较好;由于计算面积和周长的getArea()方法和getPermeter()方法在不同子类里的实现方式不同,所以Object类中定义的这两个方法的实现只能由子类提供。
3.抽象类无法被直接实例化,可以让子类继承然后实例化子类
通过一个例子来说明:
public abstract class Person {
//定义一个抽象方法
public abstract void isSmoke();
}
//学生类
class Students extends Person{
//继承抽象类后抽象类中的抽象方法必须在子类中实现
public void isSmoke() {
System.out.print("Students can't smoke.");
}
}
//教师类
class Teachers extends Person{
public void isSmoke() {
System.out.print("Teachers can smoke.");
}
}
(三)使用抽象类的意义
因为抽象类不能实例化对象,必须要有子类来实现它之后才能使用。这样就可以把一些具有相同属性和方法的组件进行抽象,更有利于代码和程序的维护。同时,抽象类也是Java面向对象的一个重要体现。
二.接口
(一)概念
接口(Interface),在Java编程语言中是一个抽象类型,是象方法的集合。
接口通常以 interface 来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口有以下特性:
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。接口中的方法都是公有的。
(二)语法
1. 定义:一个简单的接口拥有全局变量和抽象方法。在接口中的所有方法都必须只声明方法标识,而不要去声明具体的方法体,因为具体的方法体的实现是由继承该接口的类来去实现的。
接口定义的一般形式为:
[访问控制符]interface <接口名> {
类型标识符final 符号常量名n = 常数;
返回值类型 方法名([参数列表]);
…
}
定义接口实例:
interface Human {
//定义一个全局变量
final String txt="吸烟有害健康";
//定义一个抽象方法
public void isSmoke();
}
2.实现:要实现接口,就必须去实现接口规定的方法,只有把接口规定的抽象方法都给实现了,才承认这个类实现了这个接口,实现了这个接口代表的某种功能。使用 implements 关键字实现接口。
实现接口实例:
class Student implements Human{
public void isSmoke() {
System.out.println("Students can't smoke.");
}
public static void main(String[] args) {
Student h=new Student();
h.isSmoke();
System.out.println(txt);
}
}
3.接口的继承
子接口可以对父接口的方法和常量进行重写。例如:
// 接口 Student 继承 Human
public interface Student extends Human {
// 重写父接口中的txt
String txt = "未成年禁止吸烟";
// 重写父接口中的isSmoke()方法
void isSmoke();
}
注意: 在Java中,类的多继承是不合法的,但接口允许多继承。
public interface C extends A, B
三.比较抽象类与接口
Q: 为什么有了抽象类还要接口?
看起来抽象类除了多继承以外,完全可以完成接口所作的事情,为什么还需要定义接口呢?
1、避免java单继承的局限
2、避免多继承带来的复杂性和低效性
3、面向接口编程带来的优势。降低程序间的耦合,易扩展,易维护
Q: 如何确定在什么情况下应该使用接口,什么情况下应该使用类呢?
抽象类和接口都是用来指定多个对象的共同特征的。那么如何确定在什么情况下应该使用接口,什么情况下应该使用类呢?一般来说,清晰描述父子关系的强的“是......的一种”关系应该用类建模。弱的“是..的一种”关系也称为类属关系,它表明对象拥有某种属性,可以用接口来建模。
类型抽象类接口定义abstract关键字interface关键字继承可以继承一个类和实现多个接口;子类只可以继承一个抽象类接口只可以继承接口(一或多);子类可以实现多个接口方法实现可定义构造方法,可以有抽象方法和具体方法无构造方法,且方法都是抽象的,也没有方法的实现实现方式子类使用extend关键字来继承抽象类。如果子类不是抽象类,需要提供抽象类中所有声明的方法的实现子类使用关键字implements来实现接口。需要提供接口中所有声明的方法的实现作用把相同的东西提取出来,即重用把程序模块进行固化的契约,降低耦合
来源:https://blog.csdn.net/cookies_k/article/details/121999870


猜你喜欢
- 1.依赖maven依赖如下,需要说明的是,spring-boot-starter-data-redis里默认是使用lettuce作为redi
- 不同的加锁顺序我们来看一个不同加锁顺序的例子:public class DiffLockOrder {private int amount;
- summarydetail传统的Spring项目会有很多的配置文件,比如我们要使用Redis,一般除了对应的依赖的jar包我们还需要在app
- 场景随着移动支付的兴起,在我们的app'中,会经常有集成支付的需求.这时候一般都会采用微信和支付宝的sdk 来集成(一)支付宝支付在
- 前言Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring Mybatis在
- 本文主要介绍了java中LinkedList使用迭代器优化移除批量元素原理,分享给大家,具体如下:public interface Iter
- spring与IoCIoC:控制反转,将由代码操纵的对象控制权,交给第三方容器,反转给第三方容器。这种对象依赖的关系管理方式,称作IoC。I
- datagridview手动添加行数据我在做软件模型界面时,通过功能按钮触发显示的datagridview中,为了方便,需要一些数据,仅写死
- 一. switch分支结构1. 简介switch结合case,能够判断一个变量或表达式与一系列值中的某个值是否相等,这里的每个值都被称为一个
- Condition的作用是对锁进行更精确的控制。Condition中的await()方法相当于Object的wait()方法,Conditi
- 代码:public DataTable TXTToDataTable(string fileName, string columnName)
- 本文实例讲述了java实现的RSA加密算法。分享给大家供大家参考,具体如下:一、什么是非对称加密1、加密的密钥与加密的密钥不相同,这样的加密
- 比如,我们有这么个过程,项目结构如下:a --b --ca是总结点,b是子节点,c是父节点b依赖父节点class,通
- 为什么要学习Android与H5互调?微信,QQ空间等大量软件都内嵌了H5,不得不说是一种趋势。Android与H5互调可以让我们的实现混合
- SpringBoot 项目启动之后执行自定义方法的两种方式在测试配置中心的配置时,想在项目启动成功之后打印配置项,然后需要执行自定义的类一般
- 某次,在大型的工程代码中,我这样调用:#include <iostream>using namespace std;namesp
- EventBus 可以很方便地进行各组件间的通信,解耦性更强,比广播更好用。EventBus 3 简介EventBus是一种为了优化Andr
- using 指令有两个用途: 允许在命名空间中使用类型,以便您不必限定在该命名空间中使用的类型。 为命名空间创建别名。 using
- 此篇文章内容仅限于 描述springboot与 thy 自定义标签的说明,所以你在看之前,请先会使用springboot和thymeleaf
- 这几天在弄后端管理系统向指定的Android