C# NAudio 音频库

C# NAudio 音频库

  • NAudio安装
  • NAudio简述
  • 简单示例1
  • 录制麦克风
  • 录制系统声卡
  • WAV格式播放
  • MP3格式播放
  • AudioFileReader读取播放音频
  • MediaFoundationReader 读取播放音频

NAudio安装

项目=>NuGet包管理器 搜索NAudio点击安装,自动安装依赖库。
在这里插入图片描述
安装成功后工具箱会新增NAudio.WinForms控件
在这里插入图片描述

NAudio简述

NAudio为.NET平台下的开源库,采用ML-PL协议,开源地址:https://github.com/naudio/NAudio支持多种音频操作,可实现多种API播放与录制、多种不同音频格式、音频格式转换(重采样、位深、声道等)、音频编码、多通道播放、音频效果处理等等。

快速入门
深入研究

常用类:

  • WaveIn 表示波形输入, 继承了 IWaveIn, 例如麦克风输入, 或者计算机正在播放的音频流。
  • WaveOut 表示波形输出, 继承了 IWavePlayer, 用来播放音频, 以 IWaveProvider 作为播放源播放音频, 通过拓展方法也支持以 ISampleProvider 作为播放源播放音频。
  • WaveStream 表示波形流, 它继承了 IWaveProvider, 可以用来作为播放源。
  • WaveFileReader 继承了 WaveStream, 用来读取波形文件。
  • WaveFileWriter 继承了Stream, 用来写入文件, 常用于保存音频录制的数据。
  • AudioFileReader 通用的音频文件读取器, 可以读取波形文件, 也可以读取其他类型的音频文件例如 Aiff, MP3

常用接口:

  • IWaveProvider 波形提供者, 上面已经提到, 是音频播放的提供者, 通过拓展方法可以转换为 ISampleProvider。
  • ISampleProvider 采样提供者, 上面已经提到, 通过拓展方法可以作为 WaveOut 的播放源。

简单示例1

自定义录音机类:Recorder.cs

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NAudioDemo
{
    internal class Recorder
    {
        public WaveIn mWaveIn;
        public WaveFileWriter mWaveFileWriter;
        public int secondsRecorded;

        /// <summary>
        /// 开始录音
        /// </summary>
        /// <param name="filePath"></param>
        public void RecorderStart(string filePath)
        {
            // 创建WaveIn对象
            mWaveIn = new WaveIn();

            // 添加DataAvailable事件处理回调
            mWaveIn.DataAvailable += OnDataAvailable;

            // 创建WaveFileWriter对象
            mWaveFileWriter = new WaveFileWriter(filePath, mWaveIn.WaveFormat);

            // 开始录音
            mWaveIn.StartRecording();
        }

        /// <summary>
        /// 停止录音
        /// </summary>
        public void RecorderStop()
        {
            mWaveIn?.StopRecording();

            mWaveIn?.Dispose();

            mWaveFileWriter?.Close();
            mWaveFileWriter = null;
        }


        /// <summary>
        /// 录音数据回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDataAvailable(object sender, WaveInEventArgs e)
        {
            // 写入录音数据
            mWaveFileWriter.Write(e.Buffer, 0, e.BytesRecorded);           

            // 计算已录制的秒数
            secondsRecorded = (int)mWaveFileWriter.Length / mWaveFileWriter.WaveFormat.AverageBytesPerSecond;
        }
  
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


using System.IO;
using NAudio.Wave;
using System.Drawing.Text;
using System.Media;
using NAudio.Dsp;

namespace NAudioDemo
{
    public partial class Form1 : Form
    {             
        // 创建录音机类实例
        Recorder recorder = new Recorder();
        
        public Form1()
        {
            InitializeComponent();
        }
                
        private void Form1_Load(object sender, EventArgs e)
        {
            
        }
   
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = true;
            recorder.RecorderStart(@"D:\1.wav");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            button1.Enabled = true;
            button2.Enabled = false;
            recorder.RecorderStop();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            SoundPlayer player = new SoundPlayer(@"D:\1.wav");
            player.Play();           
        }
    }
}

在这里插入图片描述

录制麦克风

  • 借助 WaveIn 类, 我们可以轻易的捕获麦克风输入, 在每一次录制到数据时, 将数据写入到文件或其他流, 这就实现了保存录音

  • 在保存波形文件时需要借助 WaveFileWriter, 当然, 如果你想保存为其他格式, 也可以使用其它的 Writer, 例如 CurWaveFileWriter 以及AiffFileWriter, 美中不足的是没有直接写入到 MP3 的 FileWriter

  • 需要注意的是, 桌面程序可以直接使用 WaveIn, 其回调基于 Windows 消息, 所以无法在控制台应用中使用 WaveIn

  • 如果要在控制台应用中实现录音, 只需要使用 WaveInEvent, 它的回调基于事件而不是 Windows 消息, 所以可以通用

  • 示例代码:
    WaveIn cap = new WaveIn(); // cap, capture
    WaveFileWriter writer = new WaveFileWriter();
    cap.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded); // 订阅事件
    cap.StartRecording(); // 开始录制
    cap.StopRecording(); // 停止录制
    writer.Close(); // 关闭 FileWriter, 保存数据

  • 另外, 除了使用 WaveIn, 你还可以使用 WasapiCapture, 它与 WaveIn 的使用方式是一致的, 可以用来录制麦克风

  • Wasapi 全称 Windows Audio Session Application Programming Interface (Windows音频会话应用编程接口)

  • 具体 WaveIn, WaveInEvent, WasapiCapture 的性能, 笔者还没有测试过, 但估计不会有太大差异.

  • 提示: WasapiCapture 和 WasapiLoopbackCapture 位于 NAudio.Wave 命名空间下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using NAudio;
using NAudio.Wave;


namespace NAudioDemo2
{
    public partial class Form2 : Form
    {

        private WaveIn waveIn = null;
        private WaveFileWriter writer = null;


        public Form2()
        {
            InitializeComponent();
            button2.Enabled = false;
            button3.Enabled = false;
        }

        /// <summary>
        /// 设置保存文件名称
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            saveFileDialog1.Filter = "audio files (*.wav)|*.wav| all files (*.*)|*.*"; // 文件类型过滤
            saveFileDialog1.DefaultExt = "*.wav"; // 默认文件扩展名
            //saveFileDialog1.FileName = "1.wav"; // 默认文件名

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            { 
                string fName = saveFileDialog1.FileName; // 获取文件名
                textBox1.Text = fName;
                button2.Enabled = true;
            }
        }

        /// <summary>
        /// 开始录音
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
                      
            //waveIn = new WaveIn { WaveFormat = new WaveFormat(44100, 1) };
            waveIn = new WaveIn();
            waveIn.WaveFormat = new WaveFormat(44100, 1);
           
            writer = new WaveFileWriter(textBox1.Text.Trim(), waveIn.WaveFormat);

            waveIn.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded);

            waveIn.StartRecording();

            button2.Enabled = false;
            button3.Enabled = true;
        }

        /// <summary>
        /// 停止录音
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            waveIn.StopRecording();
            waveIn.Dispose();
            waveIn = null;

            writer.Flush();
            writer.Close();
            writer.Dispose();

            button2.Enabled = true;
            button3.Enabled = false;
        }
    }
}

录制系统声卡

录制声卡输出, 也就是录制计算机正在播放的声音, 借助 WasapiLoopbackCapture 即可简单实现, 使用方式与 WasapiCapture 无异
WasapiLoopbackCapture cap = new WasapiLoopbackCapture();
WaveFileWriter writer = new WaveFileWriter();
cap.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded);
cap.StartRecording();

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NAudioDemo2
{
    public partial class Form3 : Form
    {
        private WasapiLoopbackCapture loopCap = new WasapiLoopbackCapture();
        private WaveFileWriter fileWriter;

        public Form3()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "wave file *.wav|*.wav|all filse *.*|*.*";
            saveFileDialog.DefaultExt = ".wav";

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string fName = saveFileDialog.FileName;
                textBox1.Text = fName;            
            }
        }

        /// <summary>
        /// 录制声卡开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            fileWriter = new WaveFileWriter(textBox1.Text.Trim(), loopCap.WaveFormat) ;
            loopCap.DataAvailable += (s, args) => fileWriter.Write(args.Buffer, 0, args.BytesRecorded);

            loopCap.StartRecording();
        }

        /// <summary>
        /// 录制声卡停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            loopCap.StopRecording();
            fileWriter.Flush();
            fileWriter.Close();
            fileWriter.Dispose();
        }
    }
}

WAV格式播放

NAudio 中, 通过 WaveFileReader 来读取波形数据, 在实例化时, 你可以指定文件名或者是输入流, 这意味着你可以读取内存流中的音频数据.
WaveFileReader reader = new WaveFileReader(filepath);
WaveOut wout = new WaveOut();
wout.Init(reader); // 通过 IWaveProvider 为音频输出初始化
wout.Play(); // 至此, wout 将从指定的 reader 中提供的数据进行播放

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NAudioDemo2
{
    public partial class Form4 : Form
    {
        private WaveOut wout_wav;
        WaveFileReader reader;

        public Form4()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "audio file *.wav|*.wav";
            ofd.DefaultExt = "*.wav";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string fName = ofd.FileName;
                textBox1.Text = fName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            reader = new WaveFileReader(textBox1.Text.Trim());
            wout_wav = new WaveOut();
            wout_wav.Init(reader);
            wout_wav.Play();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            wout_wav.Pause();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            wout_wav.Resume();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            wout_wav.Stop();
            wout_wav.Dispose();
            reader.Close();
        }
    }
}

MP3格式播放

播放 MP3 音乐其实与播放波形音乐没有太大区别, 只不过将 WaveFileReader 换成Mp3FileReader 罢了
Mp3FileReader reader = new Mp3FileReader(filepath);
WaveOut wout = new WaveOut();
wout.Init(reader);
wout.Play();

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NAudioDemo2
{
    public partial class Form5 : Form
    {
        Mp3FileReader reader;
        WaveOut wout_mp3;

        public Form5()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "audio file *.mp3|*.mp3";
            ofd.DefaultExt = "*.mp3";

            if (ofd.ShowDialog() == DialogResult.OK)
            { 
                string fName = ofd.FileName;
                textBox1.Text = fName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            reader = new Mp3FileReader(textBox1.Text);
            wout_mp3 = new WaveOut();
            wout_mp3.Init(reader);
            wout_mp3.Play();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            wout_mp3.Pause();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            wout_mp3.Resume();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            wout_mp3.Stop();
            wout_mp3.Dispose();
            reader.Close();
            reader.Dispose();
        }
    }
}

AudioFileReader读取播放音频

通过AudioFileReader读取音频文件可以播放.mp3, .wav, .flac等多种格式
AudioFileReader reader = new AudioFileReader (@“d:\1.mp3”);
WaveOut wout = new WaveOut ();
wout.Init(reader );
wout.Play();
wout.Pause();
wout.Resume();
wout.Stop();

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NAudioDemo2
{
    public partial class Form6 : Form
    {
        AudioFileReader reader;
        WaveOut wout;

        public Form6()
        {
            InitializeComponent();
        }

        private void Form6_Load(object sender, EventArgs e)
        {
        
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "audio file *.mp3|*.mp3|all files *.*|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            { 
                string fName = ofd.FileName;
                textBox1.Text = fName; 
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            reader = new AudioFileReader(textBox1.Text.Trim());
            wout = new WaveOut();
            wout.Init(reader);
            wout.Play();

        }

        private void button3_Click(object sender, EventArgs e)
        {
            wout.Pause();  
        }

        private void button4_Click(object sender, EventArgs e)
        {
            wout.Resume();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            wout.Stop();
            wout.Dispose();
            reader.Close();
            reader.Dispose();
        }
    }
}

MediaFoundationReader 读取播放音频

通过MediaFoundationReader 读取音频文件可以播放.mp3, .wav, .flac等多种格式
MediaFoundationReader reader = new MediaFoundationReader (@“d:\1.mp3”);
WaveOut wout = new WaveOut ();
wout.Init(reader );
wout.Play();
wout.Pause();
wout.Resume();
wout.Stop();

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NAudioDemo2
{
    public partial class Form7 : Form
    {
        MediaFoundationReader reader;
        WaveOut wout;

        public Form7()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog  ofd = new OpenFileDialog();
            ofd.Filter = "audio file *.mp3|*.mp3|all files *.*|*.*";
            ofd.DefaultExt = "*.mp3";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string fName = ofd.FileName;
                textBox1.Text = fName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            reader = new MediaFoundationReader(textBox1.Text.Trim());
            wout = new WaveOut();
            wout.Init(reader);
            wout.Play();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            wout.Pause();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            wout.Resume();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            wout.Stop();
            wout.Dispose();
            reader.Close();
            reader.Dispose();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/153800.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网站安全攻防战:守护数据的钢铁堡垒

在数字化时代&#xff0c;网站的安全性至关重要&#xff0c;因为它不仅关乎用户的隐私信息&#xff0c;还涉及到业务的正常运行。一旦网站受到攻击&#xff0c;可能导致数据泄露、服务中断等问题&#xff0c;因此网站安全应成为企业和个人关注的焦点。本文将探讨网站安全的重要…

GBase8a-GDCA-第一次阶段测试

文章目录 主要内容 总结 主要内容 GBase8a-第一阶段测试答案 总结 以上是今天要讲的内容&#xff0c;GBase8a-GDCA-第一次阶段测试题及答案。

NewStarCTF2023 Week3 Reverse方向 题目STL WP

分析 代码不多&#xff0c;逻辑挺清楚的。 先用Z3解出V7&#xff1a; from z3 import *s Solver() v1, v2, v3, v4, v5, v6 BitVecs(v1 v2 v3 v4 v5 v6, 32) v7, v8, v9, v10, v11 BitVecs(v7 v8 v9 v10 v11, 32)s.add((v1 << 15) ^ v1 0x2882D802120E) s.add((v2 …

Linux_安装docker

安装包管理工具yum-utils&#xff0c;并设置docker储存库&#xff08;如果已有&#xff0c;不用安装&#xff09; # 安装包管理工具 sudo yum install -y yum-utils # 安装docker储存库 sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/cen…

ERP管理系统为何成为制造业的必备工具

ERP管理系统为何成为制造业的必备工具&#xff1f; 全球化和数字化快速发展&#xff0c;制造业面临着越来越多的挑战和机遇。为了提高生产效率、降低成本、优化资源配置&#xff0c;许多制造业企业开始引入ERP管理系统。那么&#xff0c;为何ERP管理系统成为制造业的必备工具呢…

109. 有序链表转化为二叉搜索树

题目 题解 分治。 class Solution:def getMedian(self, left: ListNode, right: ListNode) -> ListNode:找到链表的中间节点slow fast leftwhile fast ! right and fast.next ! right:slow slow.nextfast fast.next.nextreturn slowdef buildTree(self, left: ListNod…

Python爬虫实战(进阶篇)—7获取每日菜价(附完整代码)

文章目录 专栏导读背景前期准备1、网址&#xff1a;2、分析&#xff1a; 请求url、请求方法、请求参数测试一个完整代码写入Excel视频展示不足&#xff1a;结尾 专栏导读 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门针…

问题汇总20231103

文章目录 前言问题汇总1.所有操作系统在CPU层面上是不是都为时间片轮转的形式处理程序&#xff1f;只是任务调度的调度算法不同&#xff1f;那多线程的本质也是时间片吗&#xff1f;只不过很小&#xff1f;2.Mcu和mpu的本质区别3.下载HAL库步骤4.RAM,ROM,SRAM,SDRAM,DDR内存5.编…

Spring事务和事务的传播机制

目录 Spring中事务的实现 MySQL中的事务使用 Spring 编程式事务 TransactionTemplate 编程式事务 TransactionManager编程式事务 Spring声明式事务 Transactional 参数说明 事务因为程序异常捕获不会自动回滚的解决方案 Transactional 原理 Spring 事务隔离级别 Spring…

Apipost 推出IDEA插件一键生成API文档

今天给大家推荐一款IDEA插件&#xff1a;Apipost-Helper-2.0&#xff0c;写完代码IDEA内一键生成API文档&#xff0c;无需安装、打开任何其他软件&#xff1b;写完代码IDEA内一键调试&#xff0c;无需安装、打开任何其他软件&#xff1b;生成API目录树&#xff0c;双击即可快速…

单片机编程原则

多任务编程的概念 方式一&#xff1a;实时操作系统&#xff08;不建议新手使用&#xff09; 方式二 &#xff1a;裸机多任务模型 逻辑多任务的基本原理 把三个任务分别分为一个一个的片段 然后先执行任务一的第一个切片 执行第二个任务的第一个片段 执行第三个任务的第一个片…

How to design a database storage model for water network information system

How to design a database storage model for water network information system 1、领域划分2、基础域2.1、概述2.2、E-R图2.3、SQL脚本 1、领域划分 序号中文名称英文名称代号备注1基础域basea012资产域assertsa023监测域monitora034水权域quotaa045灌溉域irrigationa056排涝…

JVM bash:jmap:未找到命令 解决

如果我们在使用JVM的jmap命令时遇到了"bash: jmap: 未找到命令"的错误&#xff0c;这可能是因为jmap命令没有在系统的可执行路径中。 要解决这个问题&#xff0c;可以尝试以下几种方法&#xff1a; 1. 检查Java安装&#xff1a;确保您已正确安装了Java Development …

数字孪生技术能够为旅游业带来什么新变化?

随着科技的不断发展&#xff0c;数字孪生技术逐渐融入各个行业&#xff0c;为旅游业的高质量发展提供了新的动力和可能性。数字孪生&#xff0c;即对现实世界的精确数字建模&#xff0c;通过实时数据同步、模拟分析&#xff0c;为旅游业带来了诸多创新和改变。 在数字孪生的理…

ES Kibana 简介

ES & Kibana 简介 来源&#xff1a;微信公众号《鲜枣课堂》 1998年9月4日&#xff0c;Google公司在美国硅谷成立。正如大家所知&#xff0c;它是一家做搜索引擎起家的公司。 无独有偶&#xff0c;一位名叫Doug?Cutting的美国工程师&#xff0c;也迷上了搜索引擎。他做了…

3. hdfs概述与高可用原理

简述 HDFS&#xff08;Hadoop Distributed File System&#xff09;是一种Hadoop分布式文件系统&#xff0c;具备高度容错特性&#xff0c;支持高吞吐量数据访问&#xff0c;可以在处理海量数据&#xff08;TB或PB级别以上&#xff09;的同时最大可能的降低成本。 HDFS适用于…

0门槛!用ChatGPT只花1天批量生成300个爆火TikTok视频

目录 1 2让天下没有难做的开发和运维&#xff0c;DevOps终于有了专属大模型 3关于 DevOpsGPT 1 不露脸&#xff0c;不怕视频也能从TikTok赚到钱?在过去30天&#xff0c;有人通过这个方式预计至少获得了超过1万美金的广告分成收益。这些成功账号的共同特点是&#xff0c;所有…

探究多态的原理与实现:虚函数表、动态绑定与抽象类

文章目录 一、多态概念二、多态实现&#xff08;具体&#xff09;2.1 虚函数2.2 虚函数 重写2.3 override关键字 与 final关键字2.4 重载、重写&#xff08;覆盖&#xff09;、重定义&#xff08;隐藏&#xff09;的区别 三、抽象类3.1 概念3.2 实现继承 && 接口继承 四…

通过使用阿里云服务器,搭建Java程序的运行环境

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Linux》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一…

ACM练习——第四天

ok&#xff0c;今天又是三节课的一天。 刚刚吃完饭的我一刻也不敢耽误&#xff0c;直接开干&#xff01;&#xff01;&#xff01; 这些题和力扣上的&#xff0c;为了练习数据结构的题是不一样的。 直接上嘴脸 题目 第一次放学 (nowcoder.com)来自牛客网 思路 先看他的输入…