Java面向对象编程--高级

目录

一、static关键字

1.1 静态变量

1.2 静态内存解析

1.3 static的应用与练习

二、单例设计模式

2.1 单例模式

2.2 如何实现单例模式

三、代码块

3.1 详解

3.2 练习,测试

四、final关键字

五、抽象类与抽象方法

5.1 abstract

5.2 练习

六、接口

6.1 接口的理解

6.2 接口的多态性

6.3 抽象类和接口对比

6.4 接口的使用练习

6.4.1 练习1

1. 定义接口

2. 实现接口

3. 使用接口

4. 测试支付系统

5.结果

6.4.2 练习2

1. 接口

2. Developer类

3. 父类Vehicle

4. 三个子类   Bicycle  ElectricVhicle Car

5. VehicleTest测试类

6. 结果


一、static关键字

1.1 静态变量

static(静态的):用来修饰的结构、属性、方法;代码块、内部类

对比静态变量与实例变量:

①个数

  • >静态变量:在内存空间中只有一份, 被类的多个对象所共享。
  • >实例变量:类的每一个实例(或对象)都保存着一份实例变量。

②内存位置

  • >静态变量: jdk6及之前:存放在方法区。jdk7及之后: 存放在堆空间
  • >实例变量:存放在堆空间的对象实体中。

③加载时机

  • >静态变量:随着类的加载而加载,由于类只会加载一次, 所以静态变量也只有一份。
  • >实例变量:随着对象的创建而加载。每个对象拥有一份实例变量。

④调用者

  • >静态变量:可以被类直接调用,也可以使用对象调用。
  • >实例变量:只能使用对象进行调用。

⑤判断是否可以调用---> 从生命周期的角度解释

类变量实例变量
yesno
对象yesyes

⑥消亡时机.

  • 静态变量:随着类的卸载而消亡
  • 实例变量:随着对象的消亡而消亡

1.2 静态内存解析

1.3 static的应用与练习

import java.util.Objects;public class Account {private int id;private String password;//密码private double balance;//金额private static double interestRate;//利率private static double minBalance = 1.0;private static int init = 1001;public Account(){this.id = init;init++;password = "000000";}public Account(String password, double balance) {this.password = password;this.balance = balance;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}public static double getInterestRate() {return interestRate;}public static void setInterestRate(double interestRate) {Account.interestRate = interestRate;}public static double getMinBalance() {return minBalance;}public static void setMinBalance(double minBalance) {Account.minBalance = minBalance;}@Overridepublic String toString() {return "Account{" +"id=" + id +", password='" + password + '\'' +", balance=" + balance +'}';}
}public class Test {public static void main(String[] args) {Account acct1 = new Account();System.out.println(acct1);Account acct2 = new Account("123456",1155);System.out.println(acct2);Account.setInterestRate(0.0123);Account.setMinBalance(10);System.out.println("银行存款的利率:" + Account.getInterestRate());System.out.println("银行最小存款: " + Account.getMinBalance());}
}

二、单例设计模式

2.1 单例模式

何为单例模式?

  • 采取一定的办法保证在整个软件系统中,堆某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

经典设计模式:共23种

2.2 如何实现单例模式

1.饿汉式:

public class boyFirend {private int age;private String name;//1.私有化构造器private boyFirend(){}//2.创建对象私有化private static boyFirend b1 = new boyFirend();//3.public static boyFirend getG1(){return b1;}
}

2.懒汉式:

//懒汉式
public class GirlFirend {private int age;private String name;//1.私有化构造器private GirlFirend(){}//2.创建对象私有化private static GirlFirend g1 = null;//3.public static GirlFirend getG1(){if (g1 == null) {g1 = new GirlFirend();}return g1;}
}

两种模式的对比:

特点:

  • 饿汉式:"立即加载",随着类的加载,当前唯一的实例创建。
  • 懒汉式:"延迟加载",在需要使用时,进行创建

优缺点:

  • 饿汉式:(优点)写法简单,使用更快,线程安全(缺点)内存中占用时间长。
  • 懒汉式:(优点)节省内存空间(缺点)线程不安全

三、代码块

3.1 详解

用来初始化类或对象的信息(即初始化类或对象的成员变量)

代码块修饰:只能使用static进行修饰

代码块分类:

  • 静态代码块;使用static修饰
  • 非静态代码块:不适用static修饰

格式:

{

//内容

}

static{

//内容

}

3.2 练习,测试

class User {private String userName;private String password;private long registrationTime;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public long getRegistrationTime() {return registrationTime;}{System.out.println("新用户注册");registrationTime = System.currentTimeMillis();}public User() {userName = System.currentTimeMillis() +"";password = "123456";}public User(String userName, String password) {this.userName = userName;this.password = password;}public String getInfo() {return"用户名='" + userName  +", 密码='" + password  +", 注册时间=" + registrationTime ;}
}
public class Test {public static void main(String[] args) {User u1 = new User();System.out.println(u1.getInfo());User u2 = new User("张三","654321");System.out.println(u2.getInfo());}
}

注意:运行上,由父及子,静态先行。记住:执行的先后顺序:默认-显式-代码块-构造器-对象

小测试:(请给出运行结果)

public class Test {public static void main(String[] args) {Sub s = new Sub();}
}class Base{Base(){method(100);}{System.out.println("base");}public void method(int i){System.out.println("base :" + i);}
}class Sub extends Base{Sub(){super.method(70);}{System.out.println("Sub");}public void method(int j){System.out.println("sub :" + j);}
}

答案:

四、final关键字

final关键字: 修饰符,用于限制类、方法和变量的行为。

可在哪些位置赋值:

  • 显示
  • 代码块中
  • 构造器中

final作用:

修饰类:表此类不能被继承

final class FinalClass {void display() {System.out.println("This is a final class.");}
}// class SubClass extends FinalClass { // 这行代码会导致编译错误
// }

修饰方法:此方法不能被重写

class Parent {final void show() {System.out.println("This is a final method.");}
}class Child extends Parent {// void show() { // 这行代码会导致编译错误//     System.out.println("Trying to override a final method.");// }
}

修饰变量:成员和局部变量都可修饰,此时“变量”其实变成了“常量”,不可更改。

final int x = 10;
// x = 20; // 这行代码会导致编译错误final StringBuilder a1 = new StringBuilder("Hello");
// a1 = new StringBuilder("World"); // 这行代码会导致编译错误
a1.append(", World!"); // 这行是允许的,因为a1引用的对象内容是可以改变的

final搭配static使用:等于全局常量

class Constants {static final int MAX_USERS = 100;static final String APP_NAME = "MyApp";
}

习题练习:

报错:++x导致x的值改变

五、抽象类与抽象方法

5.1 abstract

abstract:抽象的

abstract修饰类:

  • 此类为抽象类。
  • 抽象类不能实例化。
  • 抽象类中包含构造器,因为子类实例化,直接或间接调用父类的构造器。
  • 抽象类可无抽象方法,有抽象方法一定为抽象类。

abstract修饰方法

  • 此方法为抽象方法。
  • 抽象方法只有方法声明,没有方法体。
  • 抽象方法的功能确定,不知具体实现。
  • 抽象方法必须重写父类中的所有抽象方法,才能实例化,否则,此子类还是抽象类。

abstract不能使用的场景:属性,构造器,代码块

5.2 练习

场景:编写工资系统,不同类型的员工(多态)按月发工资,如果某个月是某个employee对象的生日,则当月的工资增加100

代码:

//Employee类
public abstract class Employee {private String name;private int number;private MyDate birthday;public Employee() {}public Employee(String name, int number, MyDate birthday) {this.name = name;this.number = number;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}public abstract double earnings();@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", number=" + number +", birthday='" + birthday.toDateString() + '\'' +'}';}
}//HourEmployee类
public class HourEmployee extends Employee{private double wage;private int hour;public HourEmployee() {}public HourEmployee(String name, int number, MyDate birthday, double wage, int hour) {super(name, number, birthday);this.wage = wage;this.hour = hour;}public double getWage() {return wage;}public void setWage(double wage) {this.wage = wage;}public int getHour() {return hour;}public void setHour(int hour) {this.hour = hour;}@Overridepublic double earnings() {return wage * hour;}@Overridepublic String toString() {return "HourEmployee{" +super.toString() +'}';}
}//MyDate类
public class MyDate {private int year;private int month;private int day;public MyDate() {}public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}public String toDateString(){return year + "年" + month + "月" + day +"日";}
}//PayrollSystem类
import java.util.Scanner;public class PayrollSystem {public static void main(String[] args) {Scanner scan = new Scanner(System.in);Employee[] emps = new Employee[2];emps[0] = new SalariedEmployee("张胜男", 1001,new MyDate(1992, 12, 30), 2000);emps[1] = new HourEmployee("李四", 1002,new MyDate(1992, 10, 10),15 ,240);System.out.println("请输入当前的月份: ");int month = scan.nextInt();for (int i = 0; i < emps.length; i++) {System.out.println(emps[i].toString());if (month == emps[i].getBirthday().getMonth()){double a = 100.0;double b =emps[i].earnings() + a;System.out.println("工资为:"+ b);System.out.println("生日快乐,加薪100");}else{System.out.println("工资为:"+emps[i].earnings());}scan.close();}}
}//SalariedEmployee类
public class SalariedEmployee extends Employee{private double monthlySalary;public SalariedEmployee() {}@Overridepublic  double earnings(){return monthlySalary;}public SalariedEmployee(String name, int number, MyDate birthday, double monthlySalary) {super(name, number, birthday);this.monthlySalary = monthlySalary;}public double getMonthlySalary() {return monthlySalary;}public void setMonthlySalary(double monthlySalary) {this.monthlySalary = monthlySalary;}@Overridepublic String toString() {return "SalariedEmployee{" +super.toString() +'}';}
}

六、接口

6.1 接口的理解

1. 接口的本质是契约、标准、规范,就像我们的法律一样。制定好后大家都要遵守。

2.定义接口的关键字: interface

3.接口内部结构的说明:

可以声明:

  • 属性:必须使用public static final修饰
  • 方法: jdk8之前:声明抽象方法,修饰为public abstractjdk8 :声明静态方法、默认方法
  • jdk9 :声明私有方法

不可以声明:构造器

4.接口与类的关系:实现关系

5.格式:

  • class A extends SuperA implements B C{}
  • A相较于SuperA来讲,叫做子类A相较于B, C来讲,叫做实现类。

6.满足此关系之后,说明:

  • 类可以实现多个接口。
  • 类针对于接口的多实现,一定程度上就弥补了类的单继承的局限性。
  • 类必须将实现的接口中的所有的抽象方法都重写(或实现),方可实例化。否则,此实现类必须声明为抽象类。

7.接口与接口的关系:继承关系,且可以多继承

6.2 接口的多态性

接口名  变量名  = new   实现类对象;

以下为举例:Computer是类,transferData()方法,USB是接口,printer打印机

  • 创建接口实现类的对象

Computer computer = new Computer();

Printer printer = new printer();

  • 创建接口实现类的匿名对象

computer.transferData (new Computer);

  • 创建接口匿名实现类的对象

USB usb1 = new USB(){

     //重写接口中方法

}

computer.transferData (usb1);

  • 创建接口匿名实现类的匿名对象

computer.transferData (new USB(){

     //重写接口中方法

});

6.3 抽象类和接口对比

6.4 接口的使用练习

6.4.1 练习1

假设要创建一个,不同的支付方式(如信用卡、支付宝)需要实现相同的接口。

1. 定义接口

定义一个支付接口 Payment,包括方法 pay()refund()

public interface Payment {void pay(double amount);void refund(double amount);
}
2. 实现接口

实现 CreditCardPaymentAliPay 两种支付方式。

public class CreditCardPayment implements Payment {@Overridepublic void pay(double amount) {System.out.println("使用信用卡支付 " + amount + "元");}@Overridepublic void refund(double amount) {System.out.println("退款到信用卡" + amount + "元");}
}public class AliPay implements Payment {@Overridepublic void pay(double amount) {System.out.println("使用支付宝支付 " + amount + "元");}@Overridepublic void refund(double amount) {System.out.println("退款到支付宝 " + amount + "元");}
}
3. 使用接口

创建一个简单的支付处理类,使用接口来处理支付逻辑。

public class PaymentProcessor {private Payment payment;public PaymentProcessor(Payment payment) {this.payment = payment;}public void processPayment(double amount) {payment.pay(amount);}public void processRefund(double amount) {payment.refund(amount);}
}
4. 测试支付系统

在主程序中,创建不同的支付方式并测试。

public class Main {public static void main(String[] args) {// 使用信用卡支付Payment creditCardPayment = new CreditCardPayment();PaymentProcessor creditCardProcessor = new PaymentProcessor(creditCardPayment);creditCardProcessor.processPayment(100.0);creditCardProcessor.processRefund(50.0);// 使用支付宝支付Payment aliPayPayment = new AliPay();PaymentProcessor aliPayProcessor = new PaymentProcessor(aliPayPayment);aliPayProcessor.processPayment(200.0);aliPayProcessor.processRefund(80.0);}
}
5.结果

6.4.2 练习2

模拟场景:

UML类图:(UML类图讲解可跳转: ​​​​​​构造器和UML类图_类图中怎么创建加号-CSDN博客)

代码实现:

1. 接口
interface IPower {public void power();
}
2. Developer类
package test2;public class Developer {private int age;public  String name;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void takingVehicle(Vehicle vehicle){vehicle.run();}
}
3. 父类Vehicle
package test2;public abstract class Vehicle {private String brand;private String color;public Vehicle() {}public Vehicle(String brand, String color) {this.brand = brand;this.color = color;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public abstract void run();
}
4. 三个子类   

Bicycle-ElectricVhicle-Car

package test2;public class Car extends Vehicle implements IPower{private String carName;public Car() {}public Car(String brand, String color, String carName) {super(brand, color);this.carName = carName;}public String getCarName() {return carName;}public void setCarName(String carName) {this.carName = carName;}@Overridepublic void run() {System.out.println("汽车靠内燃机驱动");}@Overridepublic void power() {System.out.println("动力来自汽油");}
}package test2;public class ElectricVhicle extends Vehicle implements IPower{public ElectricVhicle() {}public ElectricVhicle(String brand, String color) {super(brand, color);}@Overridepublic void run() {System.out.println("电动车电机驱动");}@Overridepublic void power() {System.out.println("动力来自电力");}
}package test2;public class Bicycle extends Vehicle{public Bicycle() {}public Bicycle(String brand, String color) {super(brand, color);}@Overridepublic void run() {System.out.println("靠脚蹬骑自行车");}
}
5. VehicleTest测试类
package test2;public class VehicleTest {public static void main(String[] args) {Developer developer = new Developer();Vehicle[] vehicles = new Vehicle[3];vehicles[0] = new Bicycle("凤凰牌","黄色");vehicles[1] = new ElectricVhicle("理想","蓝色");vehicles[2] = new Car("奔驰","黑色","京A88888");for (int i = 0; i < vehicles.length; i++) {developer.takingVehicle(vehicles[i]);if (vehicles[i] instanceof IPower) {((IPower) vehicles[i]).power();}System.out.println();}}
}
6. 结果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

以JavaScript的学习角度看Axios,并以spring boot+vue3为例具体分析实现

什么是Axios Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;用于在浏览器和 后端 中发送异步的 HTTP 请求。它功能强大、易用&#xff0c;常用于与 API 交互&#xff0c;发送 GET、POST、PUT、DELETE 等请求。 Axios 的主要特点&#xff1a; 支持 Promise Axios 基于 …

【花卉识别系统】Python+卷积神经网络算法+人工智能+深度学习+图像识别+算法模型

一、介绍 花朵识别系统。本系统采用Python作为主要编程语言&#xff0c;基于TensorFlow搭建ResNet50卷积神经网络算法模型&#xff0c;并基于前期收集到的5种常见的花朵数据集&#xff08;向日葵、玫瑰、蒲公英、郁金香、菊花&#xff09;进行处理后进行模型训练&#xff0c;最…

GitHub简介与安装使用入门教程

1、Git与GitHub的简介 Git是目前世界上最先进的分布式控制系统&#xff0c;它允许开发者跟踪和管理源代码的改动历史记录等&#xff0c;可以将你的代码恢复到某一个版本&#xff0c;支持多人协作开发。它的核心功能包括版本控制、分支管理、合并和冲突解决等&#xff0c;其操作…

【原创】java+springboot+mysql疫苗追踪管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

2024最新版安装教程!Python安装+PyCharm安装使用教程!!(非常简单)

Python下载安装 一、进入Python官网首页&#xff0c;下载最新版的Python 官方网址&#xff1a;Download Python | Python.org 鼠标悬浮在Downloads&#xff0c;选择最新版本 注意&#xff1a;由于Python官网服务器设立在国外&#xff0c;所以下载速度非常慢&#xff0c;我这…

STM32 SPI串行总线

目录 STM32的SPI通信原理 SPI串行总线概述 SPI串行总线互连方式 STM32F1 SPI串行总线的工作原理 SPI串行总线的特征 SPI串行总线的内部结构 SPI串行总线时钟信号的相位和极性 STM32的SPI接口配置 STM32的SPI接口数据发送与接收过程 SPI的HAL 驱动函数 STM32的SPI通信…

Linux高级编程_32_磁盘映射

文章目录 磁盘映射相关函数mmap函数作用&#xff1a; munmap函数作用&#xff1a; truncate 函数作用&#xff1a; 语法&#xff1a;使用步骤&#xff1a; 磁盘映射 概述&#xff1a; > 存储映射 I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。…

H7-TOOL的LUA小程序教程第14期:任意波形信号发生器,0-20mA输出和微型数控电源(2024-10-11,已更新)

LUA脚本的好处是用户可以根据自己注册的一批API&#xff08;当前TOOL已经提供了几百个函数供大家使用&#xff09;&#xff0c;实现各种小程序&#xff0c;不再限制Flash里面已经下载的程序&#xff0c;就跟手机安装APP差不多&#xff0c;所以在H7-TOOL里面被广泛使用&#xff…

vue3学习:数字时钟遇到的两个问题

在前端开发学习中&#xff0c;用JavaScript脚本写个数字时钟是很常见的案例&#xff0c;也没什么难度。今天有时间&#xff0c;于是就用Vue的方式来实现这个功能。原本以为是件非常容易的事&#xff0c;没想到却卡在两个问题上&#xff0c;一个问题通过别人的博文已经找到答案&…

Java—继承性与多态性

目录 一、this关键字 1. 理解this 2. this练习 二、继承性 2.1 继承性的理解 2.1.1 多层继承 2.2 继承性的使用练习 2.2.1 练习1 2.2.2 练习2 2.3 方法的重写 2.4 super关键字 2.4.1 子类对象实例化 三、多态性 3.1 多态性的理解 3.2 向下转型与多态练习 四、Ob…

03 django管理系统 - 部门管理 - 部门列表

部门管理 首先我们需要在models里定义Dept类 # 创建部门表 class Dept(models.Model):name models.CharField(max_length100)head models.CharField(max_length100)phone models.CharField(max_length15)email models.EmailField()address models.CharField(max_length2…

k8s : 在master节点部署服务

部署多个work节点过于麻烦&#xff0c;于是打算直接在master节点部署服务测试 解决办法&#xff1a; k8s集群init后&#xff0c;你的master节点会被固定分配污点taint信息&#xff0c;这个污点的作用是让没有设置容忍的pod不会被调度到这个节点&#xff0c;因此我们的服务一般…

【Python】selenium获取鼠标在网页上的位置,并定位到网页位置模拟点击的方法

在使用Selenium写自动化爬虫时&#xff0c;遇到验证码是常事了。我在写爬取测试的时候&#xff0c;遇到了点击型的验证码&#xff0c;例如下图这种&#xff1a; 这种看似很简单&#xff0c;但是它居然卡爬虫&#xff1f;用简单的点触验证码的方法来做也没法实现 平常的点触的方…

十一、数据库的设计规范

文章目录 1. 为什么需要数据库设计2. 范式2.1 范式介绍2.2 范式都包括哪些2.3 键和相关属性的概念2.4 第一范式(1st NF)2.5 第二范式(2nd NF)2.6 第三范式(3rd NF)2.7 小结3. 反范式化3.1 概述3.2 应用举例3.3 反范式的新问题3.4 反范式的使用场景3.4.1 增加冗余字段的建议3.…

[Linux#65][TCP] 详解 延迟应答 | 捎带应答 | 流量控制 | 拥塞控制

目录 一、延迟应答 二、捎带应答 三. 流量控制 总结 四. 拥塞控制 1. 拥塞控制 2. 慢启动机制&#xff1a; 3.思考 4.拥塞避免算法 5. 快速恢复算法 一、延迟应答 1. 立即应答问题 接收数据的主机若立刻返回ACK应答&#xff0c;可能返回的窗口较小。例如&#xff1…

安装测试hasura

遗憾的是hasura 访问MySQL是收费的&#xff0c;访问PostgreSQL和MS SQL Server是免费的。 安装PG数据库 # 运行Hasura容器 docker run -d --name postgres-hasura -e POSTGRES_PASSWORDPassw0rd -e POSTGRES_DBhasura -p 5433:5432 postgres docker exec -it postgres-hasu…

TDC上YARN Web-UI 查看application日志方法

方法一 #通过浏览器访问tdc&#xff0c;访问的工作节点对于TDC都是外部节点。在提交给yarn任务后&#xff0c;YarnRM的Web UI 可以展示yarnnm上运行的application日志&#xff0c;但是由于跳转的svc地址&#xff0c;无法直接访问。 #在tdc界面上找到yarn实例&#xff0c;进入ya…

数据治理:制造企业转型的关键要素与战略需求

制造业&#xff0c;作为国民经济的主体&#xff0c;是立国之本、兴国之器、强国之基。从工业文明的曙光初现&#xff0c;到今日全球化的激烈竞争&#xff0c;始终昭示着一个真理&#xff1a;没有强大的制造业&#xff0c;就没有国家和民族的强盛。 为全面推进制造强国建设&…

Python精选200Tips:186-190

针对序列&#xff08;时间、文本&#xff09;数据的网络结构 续 P186-- 双向LSTM(Bidirectional Long Short-Term Memory 2005)&#xff08;1&#xff09;模型结构说明&#xff08;2&#xff09;创新性说明&#xff08;3&#xff09;示例代码&#xff1a;IMDB电影评论情感分析 …

污水排放口细粒度检测数据集,污-水排放口的类型包括10类目标,10000余张图像,yolo格式目标检测,9GB数据量。

污水排放口细粒度检测数据集&#xff0c;污-水排放口的类型包括10类目标&#xff08;1 合流下水道&#xff0c;2 雨水&#xff0c;3 工业废水&#xff0c;4 农业排水&#xff0c;5 牲畜养殖&#xff0c;6 水产养殖&#xff0c;7 地表径流&#xff0c;8 废水处理厂&…