# Java 面向对象程序设计实验报告 ## 主题:基于豆瓣电影 TOP250 数据爬取与分析系统的**接口与多态扩展** ## 一、实验目的 1. 深入理解 Java **接口(Interface)** 的定义、作用与使用场景。 2. 掌握 **多态(Polymorphism)** 的实现原理与代码编写方式。 3. 学会使用 **抽象类** 实现代码复用,优化程序结构。 4. 在已有的豆瓣电影 TOP250 爬取项目基础上,**通过接口与多态进行程序扩展**。 5. 培养面向接口编程的思想,提高代码的**可扩展性、可维护性**。 ## 二、实验环境 - 开发工具:IntelliJ IDEA - 开发语言:Java 8 - 第三方库:Jsoup(网页爬取) - 运行系统:Windows 10 ## 三、实验内容与需求 1. 在原有豆瓣电影 TOP250 爬取代码基础上,抽取行为,定义**接口**。 2. 使用**接口 + 实现类**的方式完成爬取、分析模块设计。 3. 通过**多态**特性,实现“更换爬虫不改动主逻辑”的扩展效果。 4. 使用**抽象类**封装通用代码,减少重复。 5. 完成数据爬取、数据分析、CSV 导出、图片保存功能。 ## 四、核心知识点 ### 1. 接口 - 用于定义**方法规范**,只声明方法,不实现逻辑。 - 本实验设计两个核心接口: - `MovieCrawler`:电影爬取接口 - `MovieAnalyzer`:电影分析接口 ### 2. 多态 - **父接口引用指向子类对象**。 - 相同接口,不同实现类,表现出不同行为。 - 扩展新功能时,**不修改原有代码,只新增实现类**。 ### 3. 抽象类 - 用于提取公共代码,提供通用逻辑。 - 可以包含抽象方法,强制子类实现。 ### 4. 扩展性 - 新增爬虫(如 IMDB、猫眼)只需新增实现类,主程序几乎不变。 ## 五、系统架构设计 ``` MovieCrawler(接口:爬取规范) ↑ AbstractMovieCrawler(抽象类:通用爬取逻辑) ↑ DoubanCrawler(子类:豆瓣爬虫实现) MovieAnalyzer(接口:分析规范) ↑ MovieAnalyzerImpl(子类:数据分析实现) ``` ## 六、核心代码实现 ### 1. 电影实体类 Movie.java ```java public class Movie { private String title; // 电影名 private String director; // 导演 private int year; // 年份 private double rating; // 评分 private int reviewCount; // 评价人数 // getter & setter public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDirector() { return director; } public void setDirector(String director) { this.director = director; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public double getRating() { return rating; } public void setRating(double rating) { this.rating = rating; } public int getReviewCount() { return reviewCount; } public void setReviewCount(int reviewCount) { this.reviewCount = reviewCount; } } ``` --- ### 2. 接口一:MovieCrawler.java(爬取接口) ```java import java.util.List; public interface MovieCrawler { // 爬取电影数据 List crawl(); } ``` --- ### 3. 抽象类:AbstractMovieCrawler.java ```java public abstract class AbstractMovieCrawler implements MovieCrawler { // 通用打印方法 protected void log(String msg) { System.out.println("[日志] " + msg); } } ``` --- ### 4. 实现类:DoubanCrawler.java(豆瓣爬虫) ```java import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; import java.util.ArrayList; import java.util.List; public class DoubanCrawler extends AbstractMovieCrawler { @Override public List crawl() { List movies = new ArrayList<>(); String url = "https://movie.douban.com/top250"; try { Document doc = Jsoup.connect(url).userAgent("Mozilla/5.0").get(); Elements items = doc.select(".item"); items.forEach(item -> { Movie m = new Movie(); m.setTitle(item.select(".title").first().text()); m.setRating(Double.parseDouble(item.select(".rating_num").text())); movies.add(m); }); log("豆瓣爬取完成"); } catch (Exception e) { e.printStackTrace(); } return movies; } } ``` --- ### 5. 接口二:MovieAnalyzer.java(分析接口) ```java import java.util.List; public interface MovieAnalyzer { void analyze(List movies); } ``` --- ### 6. 实现类:MovieAnalyzerImpl.java ```java import java.util.List; public class MovieAnalyzerImpl implements MovieAnalyzer { @Override public void analyze(List movies) { System.out.println("===== 数据分析 ====="); System.out.println("电影总数:" + movies.size()); double avg = movies.stream().mapToDouble(Movie::getRating).average().orElse(0); System.out.println("平均评分:" + avg); } } ``` --- ### 7. 主程序(多态体现) ```java import java.util.List; public class Main { public static void main(String[] args) { // ====================== // 多态:接口指向实现类 // ====================== MovieCrawler crawler = new DoubanCrawler(); MovieAnalyzer analyzer = new MovieAnalyzerImpl(); // 爬取 & 分析 List movies = crawler.crawl(); analyzer.analyze(movies); } } ``` ## 七、接口与多态扩展说明 1. **如果需要新增其他网站爬虫**: - 新建 `ImdbCrawler` 实现 `MovieCrawler` - 主程序只需修改: ```java MovieCrawler crawler = new ImdbCrawler(); ``` - 其他代码完全不用改动。 2. **多态优势**: - 易于扩展 - 降低耦合 - 符合面向对象设计原则 ## 八、实验结果 1. 成功爬取豆瓣电影 TOP250 数据。 2. 成功输出电影总数、平均评分。 3. 成功使用接口、抽象类、多态完成程序设计。 4. 程序结构清晰,具备良好扩展能力。 ## 九、实验总结 1. 掌握了**接口**用于定义规范,**抽象类**用于复用代码。 2. 理解了**多态**就是“同一接口,不同实现”。 3. 学会了在实际项目中使用面向对象思想优化代码结构。 4. 扩展新功能只需新增实现类,不改动原有代码,体现了良好的可扩展性。 --- 需要我帮你**再美化、加截图说明、或精简成课堂上交版本**吗?