Java面向对象之接口和抽象类的区别一目了然
介绍
相信对于Java面向对象部分,很多人很长一段时间对于接口和抽象类的区别,使用场景都不是很熟悉,同是作为抽象层重要的对象,工作中到底什么情况下使用抽象类,不是很清楚。本文就一次性把这些概念一次性说清楚,不用再烦恼了,哈哈!
核心概念
接口与抽象类最明显的区别可能就是使用上的惯用方式。接口的典型使用是代表一个类的类型或一个形容词,如 Runnable 或 Serializable,而抽象类通常是类层次结构的一部分或一件事物的类型,如 String 或 ActionHero。
java8开始增加默认方法的极具说服力的理由是它允许在不破坏已使用接口的代码的情况下,在接口中增加新的方法。默认方法有时也被称为守卫方法或虚拟扩展方法。
抽象类仍然是一个类,在创建新类时只能继承它一个。而创建类的过程中可以实现多个接口。
有一条实际经验:尽可能地使用接口而不是抽象类。只有当必要时才使用抽象类。除非必须使用,否则不要用接口和抽象类。大多数时候,普通类已经做得很好,如果不行的话,再移动到接口或抽象类中。
任何抽象性都应该是由真正的需求驱动的。当有必要时才应该使用接口进行重构,而不是到处添加额外的间接层,从而带来额外的复杂性。恰当的原则是优先使用类而不是接口。从类开始,如果使用接口的必要性变得很明确,那么就重构。接口是一个伟大的工具,但它们容易被滥用。
接口和抽象类的区别
接口和抽象类都是Java中定义行为的方式,但它们之间存在一些重要的区别。
- 定义与实现
接口:接口是一种完全抽象的类型,它只包含抽象方法和常量。接口不能被实例化,只能被类实现。一个类可以实现多个接口。
抽象类:抽象类是一个不完全的类,它可以包含抽象方法和非抽象方法。抽象类不能被直接实例化,需要通过子类来继承并实现所有抽象方法。一个类只能继承一个抽象类。
- 方法与变量
接口:接口中只能定义抽象方法(从Java 8开始也可以定义默认方法和静态方法),所有方法默认都是public的。接口中定义的变量默认是public static final的。
抽象类:抽象类中可以定义普通方法、抽象方法、静态方法、构造方法等,方法默认是public或protected的。抽象类中的变量可以是任何访问修饰符。
- 继承与实现
接口:一个类可以实现多个接口,通过关键字implements。
抽象类:一个类只能继承一个抽象类,通过关键字extends
代码示例
接口
package com.demo.java.test.javacore;
interface CanFight {
void fight();
}
interface CanSwim {
void swim();
}
interface CanFly {
void fly();
}
class ActionCharacter {
public void fight2(){
System.out.println("ActionCharacter fighting");
}
}
class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly {
public void swim() {
System.out.println("swiming");
}
public void fly() {
System.out.println("flying");
}
@Override
public void fight() {
System.out.println("fighting");
}
}
public class Adventure {
public static void t(CanFight x) {
x.fight();
}
public static void u(CanSwim x) {
x.swim();
}
public static void v(CanFly x) {
x.fly();
}
public static void w(ActionCharacter x) {
x.fight2();
}
public static void main(String[] args) {
Hero h = new Hero();
t(h); // Treat it as a CanFight
u(h); // Treat it as a CanSwim
v(h); // Treat it as a CanFly
w(h); // Treat it as an ActionCharacter
}
}
- 输出:
fighting
swiming
flying
ActionCharacter fighting
抽象类
以乐器类抽象举例,请看继承关系图:
package com.demo.java.test.javacore;
// 音符枚举
enum Note{
MIDDLE_C
}
/**
* 乐器
*/
abstract class Instrument {
private int i; // Storage allocated for each
public abstract void play(Note n);
public String what() {
return "Instrument";
}
public abstract void adjust();
}
/**
* 管乐器
*/
class Wind extends Instrument {
@Override
public void play(Note n) {
System.out.println("Wind.play() " + n);
}
@Override
public String what() {
return "Wind";
}
@Override
public void adjust() {
System.out.println("Adjusting Wind");
}
}
/**
* 打击乐器
*/
class Percussion extends Instrument {
@Override
public void play(Note n) {
System.out.println("Percussion.play() " + n);
}
@Override
public String what() {
return "Percussion";
}
@Override
public void adjust() {
System.out.println("Adjusting Percussion");
}
}
/**
* 有弦乐器
*/
class Stringed extends Instrument {
@Override
public void play(Note n) {
System.out.println("Stringed.play() " + n);
}
@Override
public String what() {
return "Stringed";
}
@Override
public void adjust() {
System.out.println("Adjusting Stringed");
}
}
/**
* 铜管乐器
*/
class Brass extends Wind {
@Override
public void play(Note n) {
System.out.println("Brass.play() " + n);
}
@Override
public void adjust() {
System.out.println("Adjusting Brass");
}
}
class Woodwind extends Wind {
@Override
public void play(Note n) {
System.out.println("Woodwind.play() " + n);
}
@Override
public String what() {
return "Woodwind";
}
}
/**
* 音乐组合类
*/
public class Music4 {
static void tune(Instrument i) {
i.play(Note.MIDDLE_C);
}
static void tuneAll(Instrument[] e) {
for (Instrument i: e) {
tune(i);
}
}
public static void main(String[] args) {
// 向上转型
Instrument[] orchestra = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind()
};
// 演凑
tuneAll(orchestra);
}
}
- 输出:
Wind.play() MIDDLE_C
Percussion.play() MIDDLE_C
Stringed.play() MIDDLE_C
Brass.play() MIDDLE_C
Woodwind.play() MIDDLE_C
Java面向对象之接口和抽象类的区别一目了然的更多相关文章
- java中的接口和抽象类的区别
1.接口从用户的角度(使用实现的代码)看问题. 2.接口由编译器强制的一个模块间协作的合约. 3.无成员变量. 4.成员函数只能声明不能实现,(jdk1.8中的default 方法可以有方法体). 接 ...
- Java中的接口与抽象类的区别
由于随着jdk版本的更新,在jdk1.8时,接口也增强了,所以我们分别来说明一下. (1)jdk1.8之前 在jdk1.8之前,接口里面只能定义抽象方法和常量:而抽象类比普通类有一点不同,就是抽象类里 ...
- Java接口和抽象类的区别
今天看到项目中,写了一个抽象类,里面有很多方法继承了这类,当调用这个接口时,采用的是这个抽象类去调方法的,当时一想,这个不就是我们说的Java的多态的特征: 继承:存在继承关系的子类和父类 重写:子类 ...
- Java学习笔记(六):面向对象、接口和抽象类
类和对象 Java是一门面向对象的语言,下面我们来了解一下Java中的面向对象. 方法和重载 Java中的方法格式如下: 访问修饰符 返回值类型 方法名(参数){ 方法主体 } Java的方法支持重载 ...
- java接口和抽象类的区别和作用(功能、用途、好处)
Java接口: 总结了4点关于JAVA中接口存在的意义: 1.重要性:在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋 ...
- java 接口和抽象类的区别
java 接口和抽象类的区别抽象类:1.含有抽象方法的类一定为抽象类,反过来抽象类,不一定含有抽象方法:2.抽象类必须用abstract来进行定义,抽象方法也必须用abstract来进行定义:3.抽象 ...
- 【Java知识点专项练习】之 接口和抽象类的区别
接口和抽象类的区别 接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的.接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为publi ...
- 《Java基础知识》Java接口和抽象类的区别
抽象类 抽象类必须用 abstract 修饰,子类必须实现抽象类中的抽象方法,如果有未实现的,那么子类也必须用 abstract 修饰.抽象类默认的权限修饰符为 public,可以定义为 public ...
- Java中接口和抽象类的区别?
抽象类 抽象类必须用 abstract 修饰,子类必须实现抽象类中的抽象方法,如果有未实现的,那么子类也必须用 abstract 修饰.抽象类默认的权限修饰符为 public,可以定义为 public ...
- Java 面向对象之接口、多态
01接口的概念 A:接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成 ...
随机推荐
- [转帖][github]Chinese-LLaMA-Alpaca Public
`https://github.com/ymcui/Chinese-LLaMA-Alpaca#%E6%A8%A1%E5%9E%8B%E4%B8%8B%E8%BD%BD` 以ChatGPT.GPT-4等 ...
- [转帖] Linux命令拾遗-理解系统负载
https://www.cnblogs.com/codelogs/p/16060498.html 简介# 这是Linux命令拾遗系列的第七篇,本篇主要介绍Linux中负载的概念与问题诊断方法. 本系列 ...
- 【字符串,哈希】【Yandex】Yandex7736
2023.6.30 Problem Link 定义一个串 \(S\) 是好的,当且仅当 \(S\) 可以不断消去相邻两个相同字符直至消空.给定一个长为 \(n\) 的字符串 \(s\),求有多少个有序 ...
- 微信小程序-页面生命周期
官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page-life-cycle.html
- Flowable-UI
Flowable-UI 安装 手把手教大家画了这样一个流程图,虽然说它不是特别好用,但是也不是不能用,也能用.好了,那么接下来的话,我们这个就先告一个段落,接下来我要跟大家说的第二个东西的话,就是另外 ...
- Git企业开发控制理论和实操-从入门到深入(五)|标签管理
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总 然后就是博主最近最花时间的一 ...
- 双层nn逻辑回归BP过程的另外一种解释
双层nn逻辑回归 吴恩达的双层nn逻辑回归的一些符号说明比较复杂导致视频难以理解,这里简单做一个说明 注意:阅读下面内容需要具备基本的矩阵求导知识 下面是手推过程,有空在进行修改
- MangoDB相关文档阅读小结
以往直到现在我所负责的业务场景没有使用MangoDB的,不过对于NoSQL的流行以及兴趣,阅读了一些文档做了简单的了解.待后续需要使用时再深入研究. 本文不介绍具体的语法. 基本信息 类似Json的B ...
- 解密JavaChassis3:易扩展的多种注册中心支持
本文分享自华为云社区<JavaChassis3技术解密:易扩展的多种注册中心支持>,作者:liubao68. Java Chassis 的早期版本依赖于 Service Center,提供 ...
- Linux-wget命令使用及参数详解
wget简介 Linux系统中的wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,我们经常要下载一些软件或从远程服务器恢复备份到本地服务器.wget支持HTTP,HTT ...