You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

6.5 KiB

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

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(爬取接口)

import java.util.List;

public interface MovieCrawler {
    // 爬取电影数据
    List<Movie> crawl();
}

3. 抽象类:AbstractMovieCrawler.java

public abstract class AbstractMovieCrawler implements MovieCrawler {
    // 通用打印方法
    protected void log(String msg) {
        System.out.println("[日志] " + msg);
    }
}

4. 实现类:DoubanCrawler.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<Movie> crawl() {
        List<Movie> 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(分析接口)

import java.util.List;

public interface MovieAnalyzer {
    void analyze(List<Movie> movies);
}

6. 实现类:MovieAnalyzerImpl.java

import java.util.List;

public class MovieAnalyzerImpl implements MovieAnalyzer {
    @Override
    public void analyze(List<Movie> movies) {
        System.out.println("===== 数据分析 =====");
        System.out.println("电影总数:" + movies.size());
        double avg = movies.stream().mapToDouble(Movie::getRating).average().orElse(0);
        System.out.println("平均评分:" + avg);
    }
}

7. 主程序(多态体现)

import java.util.List;

public class Main {
    public static void main(String[] args) {
        // ======================
        // 多态:接口指向实现类
        // ======================
        MovieCrawler crawler = new DoubanCrawler();
        MovieAnalyzer analyzer = new MovieAnalyzerImpl();

        // 爬取 & 分析
        List<Movie> movies = crawler.crawl();
        analyzer.analyze(movies);
    }
}

七、接口与多态扩展说明

  1. 如果需要新增其他网站爬虫

    • 新建 ImdbCrawler 实现 MovieCrawler
    • 主程序只需修改:
      MovieCrawler crawler = new ImdbCrawler();
      
    • 其他代码完全不用改动。
  2. 多态优势

    • 易于扩展
    • 降低耦合
    • 符合面向对象设计原则

八、实验结果

  1. 成功爬取豆瓣电影 TOP250 数据。
  2. 成功输出电影总数、平均评分。
  3. 成功使用接口、抽象类、多态完成程序设计。
  4. 程序结构清晰,具备良好扩展能力。

九、实验总结

  1. 掌握了接口用于定义规范,抽象类用于复用代码。
  2. 理解了多态就是“同一接口,不同实现”。
  3. 学会了在实际项目中使用面向对象思想优化代码结构。
  4. 扩展新功能只需新增实现类,不改动原有代码,体现了良好的可扩展性。

需要我帮你再美化、加截图说明、或精简成课堂上交版本吗?