/** * 实验名称:继承、抽象类、多态、接口的使用 * 实验内容:多格式音乐播放器系统 */ // 一、定义抽象类 MusicFile abstract class MusicFile { private String fileName; private double fileSize; public MusicFile(String fileName, double fileSize) { this.fileName = fileName; this.fileSize = fileSize; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public double getFileSize() { return fileSize; } public void setFileSize(double fileSize) { this.fileSize = fileSize; } // 获取文件类型 public abstract String getFileType(); // 解码音乐 public abstract void decode(); // 播放音乐 public abstract void play(); } // 二、定义播放接口 Playable interface Playable { void play(); void stop(); } // 三、MP3 音乐文件类 class MP3File extends MusicFile implements Playable { public MP3File(String fileName, double fileSize) { super(fileName, fileSize); } @Override public String getFileType() { return "MP3"; } @Override public void decode() { System.out.println("正在解码MP3有损压缩音频..."); } @Override public void play() { System.out.println("正在播放MP3音乐:" + getFileName()); } @Override public void stop() { System.out.println("MP3音乐已停止播放"); } } // 四、WAV 音乐文件类 class WAVFile extends MusicFile implements Playable { public WAVFile(String fileName, double fileSize) { super(fileName, fileSize); } @Override public String getFileType() { return "WAV"; } @Override public void decode() { System.out.println("正在读取WAV的PCM音频数据..."); } @Override public void play() { System.out.println("正在播放WAV音乐:" + getFileName()); } @Override public void stop() { System.out.println("WAV音乐已停止播放"); } } // 五、FLAC 音乐文件类 class FLACFile extends MusicFile implements Playable { public FLACFile(String fileName, double fileSize) { super(fileName, fileSize); } @Override public String getFileType() { return "FLAC"; } @Override public void decode() { System.out.println("正在解码FLAC无损压缩音频..."); } @Override public void play() { System.out.println("正在播放FLAC音乐:" + getFileName()); } @Override public void stop() { System.out.println("FLAC音乐已停止播放"); } } // 六、音乐播放器类 class MusicPlayer { private String playerName; public MusicPlayer(String playerName) { this.playerName = playerName; } public String getPlayerName() { return playerName; } public void setPlayerName(String playerName) { this.playerName = playerName; } // 使用抽象类作为参数,体现多态 public void playMusic(MusicFile musicFile) { System.out.println("\n========== 开始播放 =========="); System.out.println("播放器:" + playerName); System.out.println("文件名称:" + musicFile.getFileName()); System.out.println("文件大小:" + musicFile.getFileSize() + " MB"); System.out.println("文件格式:" + musicFile.getFileType()); // 根据实际对象类型调用对应的方法 musicFile.decode(); musicFile.play(); } // 使用接口作为参数 public void stopMusic(Playable playable) { playable.stop(); System.out.println("========== 播放结束 =========="); } } // 七、测试类(程序入口) public class MusicPlayerTest { public static void main(String[] args) { // 创建播放器对象 MusicPlayer player = new MusicPlayer("我的音乐播放器"); // 父类引用指向子类对象,体现多态 MusicFile mp3 = new MP3File("晴天.mp3", 4.8); MusicFile wav = new WAVFile("钢琴曲.wav", 38.2); MusicFile flac = new FLACFile("夜曲.flac", 25.6); // 使用父类数组统一管理音乐文件 MusicFile[] musicFiles = {mp3, wav, flac}; // 循环播放不同格式的音乐 for (MusicFile music : musicFiles) { // 多态调用解码、播放方法 player.playMusic(music); // 转换为接口类型,调用停止方法 Playable playable = (Playable) music; player.stopMusic(playable); } // 测试接口多态 System.out.println("\n========== 接口多态测试 =========="); Playable p1 = new MP3File("测试1.mp3", 3.5); Playable p2 = new WAVFile("测试2.wav", 15.0); Playable p3 = new FLACFile("测试3.flac", 20.0); p1.stop(); p2.stop(); p3.stop(); // 测试 getter 和 setter System.out.println("\n========== 封装测试 =========="); mp3.setFileName("修改后的歌曲.mp3"); mp3.setFileSize(5.2); System.out.println("修改后文件名:" + mp3.getFileName()); System.out.println("修改后文件大小:" + mp3.getFileSize() + " MB"); player.setPlayerName("新版音乐播放器"); System.out.println("修改后播放器名称:" + player.getPlayerName()); System.out.println("\n所有测试完成!"); } }