考试范围

选择题 ,10小题,每题2分,共20分
考点分散,没必要复习,因为好像书上的内容不多
题目类似,数组创建对不对,类创建类型对不对,抽象类,上转型等等

读程序写答案,5题,每题6分,共30分
未超出上课习题范围,重点4,5,6,7,异常也有,重中之重第5章,构造方法,继承,多态等等

简答题,2小题,每题6分,共12分
有编程,编程相关,建议看做过的作业或实验

设计题,共12分
画类图,陈述
重点:第5章教材,课件(知识稍微深入一点);面向抽象编程
三个小问题,有概念

编程题,2小题,14+12分,共26分

第一题:
面向抽象编程,基于接口编程
有要求:用反射?

第二题:
可视化编程与数据库
登录界面,进入数据库,校验数据;
ui创建,驱动连接,连接数据库,数据库的增删改查

驱动给了,url基本给了

p.s

第15章a卷没有?b卷有?

像停车场,菜单大作业肯定不会考

第一章(Java入门)

  • Java程序的开发步骤:编写源文件——编译源文件——字节码——执行字节码(使用解释器)
  • 一个Java应用程序必须有一个类含有 public static void main(String args[]) 方法
  • 一个java源程序至多只能有一个公共类的定义。
  • JDK提供的编译器:javac.exe

第二章(基本数据类型与数组)

  • True,False,Null不是关键字
  • char类型用单引号括起
  • 输入、输出数据:Scanner reader=new Scanner(System.in);
  • 输入重定向:File file = new File(“cost.txt");Scanner sc = new Scanner(file);

第三章(运算符、表达式和语句)

  • instanceof 运算符是二目运算符,左面的操作元是一个对象;右面是一个。当左面的对象是右面的类或子类创建的对象时,该运算符运算的结果是true ,否则是false。

第四章(类与对象)

  • 面向对象程序设计

    • 基本组成单位是类
    • 程序在运行时由类生成对象,对象是面向对象程序的核心
    • 对象之间通过发送消息进行通信,互相协作完成相应功能
  • 类是组成Java源文件的基本元素,一个源文件是有若干个类组成的。

  • 类体可以有两种重要的成员:成员变量和方法。
  • 成员变量分为实例变量和类变量。类变量被该类的所有对象共享;不同对象的实例变量互不相同;可以通过类名直接访问类变量。
  • 除构造方法外,其它方法分为实例方法和类方法。类方法不仅可以由该类的对象调用,也可以用类名调用;而实例方法必须由对象来调用。
  • 实例方法即可以操作实例变量也可以操作类变量,当对象调用实例方法时,方法中的成员变量就是指分配给该对象的成员变量,其中的实例变量和其它对象的不相同,即占有不同的内存空间;而类变量和其它对象的相同,即占有相同的内存空间。类方法只能操作类变量,当对象调用类方法时,方法中的成员变量一定都是类变量,也就是说该对象和所有的对象共享类变量。
  • 在编写Java源文件时,可以使用import语句引入有包名的类;也可以使用静态导入引入有包名类的类变量。
  • 对象访问自己的变量以及调用方法受访问权限的限制。

  • 访问控制符

    • public: 任何其它类、对象只要可以看到这个类的话,那么它就可以存取变量的数据,或使用方法。

    • protected:同一类,同一包可以使用。不同包的类要使用,必须是该类的子类。

    • private: 不允许任何其他类存取和调用。
    • default: (前边没有修饰字的情况)在同一包中出现的类才可以直接使用它的数据和方法。
  • 没定义构造器,每个类有一个默认的不带参数的构造器。定义自己的构造器之后,默认的构造器就不存在了。

UML图

泛化

表示类与类之间的继承关系,接口与接口之间的继承关系,或类对接口的实现关系。一般化的关系是从子类指向父类的,与继承或实现的方法相反。

(1)继承
继承表示是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。

表示方法:
继承使用空心三角形+实线表示。

img

(2)实现
实现表示一个class类实现interface接口(可以是多个)的功能。
表示方法:
使用空心三角形+虚线表示

img

依赖

对于两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。
表示方法:
依赖关系用虚线箭头表示。

img

关联

对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间为关联关系。
表示方法:
关联关系用实线箭头表示。

img

聚合

表示一种弱的‘拥有’关系,即has-a的关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。 两个对象具有各自的生命周期
表示方法:
聚合关系用空心的菱形+实线箭头表示。

img

组合

组合是一种强的‘拥有’关系,是一种contains-a的关系,体现了严格的部分和整体关系,部分和整体的生命周期一样
表示方法:
组合关系用实心的菱形+实线箭头表示,还可以使用连线两端的数字表示某一端有几个实例。

img

访问权限

img

第五章(子类与继承)

子类的继承性

如果子类和父类在同一个包中,子类继承了其父类中不是 private 的成员变量作为自己的成员变量,也继承了父类中不是 private 的方法作为自己的方法,继承的成员变量或方法的访问权限保持不变。

如果子类和父类不在同一个包中,子类继承了其父类中 protected 和 public 的成员变量和方法。

成员变量的隐藏

如果子类声明的成员变量的名字与从父类继承来的成员变量的名字相同(声明的类型可以不同),子类就会隐藏所继承的成员变量。

但子类对象仍然可以调用从父类继承的方法操作被子类隐藏的成员变量。

方法重写

子类可以通过重写隐藏已继承的方法。

注意:重写不允许方法类型不同,但可以是父方法的子类型;重写不允许降低访问权限;重写方法的参数不一样,会使子类出现方法重载。

super关键字

子类隐藏的成员变量和方法,由关键字 super 负责。

类似 super.x、super.play()。

如果子类的构造方法没有明显的指明使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法。

由于子类不继承父类的构造方法,所以子类在其构造方法中使用 super 来调用父类的构造方法

final关键字

final 关键字可以修饰类、成员变量和方法中的局部变量。

final 类不能被继承,即不能有子类。

如果用 final 修饰父类中的一个方法,那么这个方法不允许子类重写,只能老老实实的继承。

如果成员变量或局部变量被修饰为 final,那么变成常量。

对象的上转型对象

假设 Animal 类是 Tiger 类的父亲,当用子类创建一个对象,并把这个对象的引用放到父类的对象中时:

1
2
Animal a;
a = new Tiger();

1
2
3
Animal a;
Tiger b=new Tiger();
a = b;

则对象a是对象b的上转型对象。

对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。

上转型对象不能操作子类新增的对象和方法,可以访问子类继承或隐藏的成员变量,可以调用子类继承的方法或重写的实例方法。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class E {
public static void main(String[] args) {
B b=new B();
b.m=20;
System.out.println(b.getM());
A a=b;
a.m=-100;
System.out.println(a.getM()); //上转型对象调用的是重写的方法
System.out.println(b.seeM()); //未被重写的方法则会调用隐藏的变量a.m
}
}

class A{
int m;
int getM(){
return m;
}
int seeM(){
return m;
}
}

class B extends A{
int m; //A的变量m被隐藏
int getM(){
return m+100;
}
}
/*
输出:
120
120
-100
*/

/*
结论:上转型对象通过重写的方法会调用继承的变量,通过“.”来直接访问隐藏的变量,未被重写的方法则会调用隐藏的变量
*/

继承与多态

一个类有很多子类,子类都重写父类方法,不同子类的上转型对象调用方法时可能产生不同的行为。

多态的要点:

  1. 多态是方法的多态,不是属性的多态(多态与属性无关)。
  2. 多态的存在要有三个必要条件:继承,方法重写,父类引用指向子类对象
  3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了

abstract类与方法

对于 abstract 方法,只允许声明,不允许实现(没有方法体),而且不允许使用 final 和 abstract 同时修饰一个方法或类,也不允许使用 static 修饰 abstract 方法,即 abstract 必须是实例方法。

  • abstract 类中可以有 abstract 方法,也可以有非 abstract 方法,非 abstract 类不可以有 abstract方法
  • abstract 类不能用 new 运算符创建对象
  • 如果一个非 abstract 类是 abstract 类的子类,那么必须重写父类的 abstract 方法,即去掉 abstract 修饰,并有方法体;如果是 abstract 类,可重写,也可继承
  • abstract 类的对象可以成为其子类对象的上转型对象,该对象就可以调用其子类重写的方法

面向抽象编程

面向抽象编程是指当设计某种重要的类时,不让该类面向具体的类,而是面向抽象类,即所设计类中的重要数据是抽象类声明的对象,而不是具体类声明的对象。

面向抽象编程的核心是让类中每个可能的变化对应的交给抽象类的一个子类去负责,从而让该类的设计者不去关心具体实现,避免所设计的类依赖于具体实现。

接口与实现

接口声明:

1
interface 接口的名字

接口体中包含常量的声明与抽象方法。接口体只有抽象方法,没有普通的方法;所有常量的权限一定都是 public,而且是 static 常量(允许省略 public、final 和 static 修饰符),所有抽象方法的访问权限一定都是 public(允许省略 public abstract 修饰符)

实现接口

1
2
3
class A implements Printable,Addable

class Dog extends Animal implements Eatable,Sleepable
  • 如果一个非抽象类实现接口,该类必须重写接口的所有方法,必须用 public 修饰符修饰,并给出方法体。
  • 抽象类既可以重写接口中的方法,也可以直接拥有接口中的方法。
  • 如果一个类实现接口,可以直接在类体中使用该接口的常量
  • 一个类可以同时实现多个接口
  • 如果父类实现了某个接口,那么子类也就自然实现了该接口,子类不必使用关键字 implement 声明实现这个接口
  • 接口也可以继承,子接口继承父接口中的全部方法和常量

接口回调

接口回调是指:可以把实现某一接口的类创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口方法。实际上,当接口变量调用被类实现的接口方法,就是通知相应的对象调用接口的方法。

理解接口

接口的思想在于要求它可以要求某些类有相同名称的方法,但方法的具体内容(方法体的内容)可以不同,即要求这些类实现接口,以保证这些类一定有接口中所声明的方法(即所谓的方法绑定)

接口与多态

由接口产生的多态就是指不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时可能具有多种形态。

接口参数

如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。

abstract类与接口的比较

  • abstract 类和接口都可以有 abstract 方法
  • 接口中只可以有常量,不能有变量;而 abstract 类中既可以有常量,也可以有变量。
  • abstract 类中也可以有非 abstract 方法,接口不可见。

面向接口编程

可以通过在接口中声明若干个 abstract 方法,表明这些方法的重要性,方法体的内容细节由实现接口的类去完成。使用接口进行程序设计的核心思想是使用接口回调,即接口变量存放该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
实验六中第二个实验。
货车要装载一批货物,货物由三种商品组成:电视、计算机、洗衣机。卡车需要计算出整批货物的重量。
要求有一个ComputeWeight接口,该接口中有一个方法: public double computeWeight()
有三个实现该接口的类:Television、Computer和WashMachine. 这三个类通过实现接口给出自重。
有一个Truck类,该类用ComputeWeight接口类型的数组作为成员(Truck类面向接口),那么该数组的单元就可以存放Television对象的引用、Computer对象的引用或WashMachine对象的引用。
程序要求:①Truck中这三种物品的总量范围为30~50,随机生成;②用对象数组来管理;③根据随机数生成Television、Computer和WashMachine三类对象;④输出Truck对象所装载的货物的总重量。
*/

public interface ComputeWeight {
public double computeWeight();
}
public class Computer implements ComputeWeight{
double weight=20;
public double computeWeight(){
return weight;
}
}
public class Television implements ComputeWeight{
double weight=50;
public double computeWeight(){
return weight;
}
}
public class WashMachine implements ComputeWeight{
double weight=35;
public double computeWeight(){
return weight;
}
}
public class Truck{
ComputeWeight[] goods; //ComputeWeight接口类型的数组作为成员
Truck(ComputeWeight[] goods){
this.goods=goods;
}
public double getWeight() {
double sum = 0;
for(int i = 0;i<goods.length;i++){
sum+=goods[i].computeWeight();
}
return sum;
}
}

public class Main {
public static void main(String[] args) {
Random r = new Random();
int n= r.nextInt(21)+30;
ComputeWeight[] goods=new ComputeWeight[n];
for(int i=0;i<goods.length;i++){
int type = r.nextInt(3);
switch (type){
case 0:
goods[i]=new Television();
break;
case 1:
goods[i]=new Computer();
break;
case 2:
goods[i]=new WashMachine();
break;
default:
break;
}
}
Truck truck=new Truck(goods);
System.out.println("货车装载的货物的总重量:"+truck.getWeight()+"kg");
}
}

内部类与异常类

内部类

Java 支持在一个类中定义另一个类,这样的类称作内部类。包含内部类的类称为内部类的外嵌类

  • 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法
  • 内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员
  • 内部类仅限于它的外嵌类使用,其他类不可以用某个类的内部类声明对象
  • 内部类的外嵌类的成员变量在内部类中仍然有效

匿名类

异常类

JDBC 与 MYSQL数据库

连接数据库

加载 JDBC-MySQL 数据库驱动

1
2
3
try{
Class.forName("com.mysql.jdbc.Driver");
}catch(Exception e){}

连接数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Connection con;
String url = "jdbc:mysql://192.168.100.1:3306/students?user=root&password=&useSSL=true";
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
con=DriverManager.getConnection(url);
}
catch(SQLException e){
System.out.println(e);
}
//或者
Connection con;
String url = "jdbc:mysql://192.168.100.1:3306/students?useSSL=true";
String user = "root";
String password=""
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
con=DriverManager.getConnection(url,user,password);
}
catch(SQLException e){
System.out.println(e);
}

用Access_JDBC30.jar连接access数据库

1
2
3
4
try{
Class.forName("com.hxtt.sql.access.AccessDriver").newInstance();
this.conn = DriverManager.getConnection("jdbc:Access:///E:/javatest/lab9/src/userinfo.accdb");
}

顺序查询

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class AccTest {
Connection conn;
Statement sql;
ResultSet rs;
public void Create() throws Exception {
try {
Class.forName("com.hxtt.sql.access.AccessDriver").newInstance();
this.conn = DriverManager.getConnection("jdbc:Access:///E:/javatest/lab9/src/userinfo.accdb"); //连接代码
}
catch (Exception e){
e.printStackTrace();
System.exit(1);
}
}
public void Show() throws Exception{
try{
sql = conn.createStatement(); //声明一个SQL语句对象
rs=sql.executeQuery("SELECT * FROM userinfo"); //查询userinfo表
System.out.println("代码 姓名 密码 电子邮件地址");
System.out.println("---------------------------------------");
while(rs.next()){
String code=rs.getString(1);
String name=rs.getString(2);
String password =rs.getString(3);
String email=rs.getString(4);
System.out.println(code+" "+name+" "+password+" "+email);
}
System.out.println("---------------------------------------");
System.out.println("");
}
catch (Exception e){
e.printStackTrace();
System.exit(1);
}
}

更新、添加与删除操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public void Insert() throws Exception{
try{
sql = conn.createStatement();
String sqlStr="Insert into userinfo(code,name,password,email) values('7107','林航锌','290633','lhx2000129@163.com')"; //插入数据
//update userinfo set password='123456' where code = '7107' //更新数据
//delete from userinfo where code = '7107' //删除数据
int ok = sql.executeUpdate(sqlStr); //数据的更新、添加或删除操作
}
catch (SQLException e){
e.printStackTrace();
System.exit(1);
}
}
}

可视化与数据库

自己参考书P348,做了个数据库登录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//数据库为register,表名为register,字段为id和password

//登录模型的代码
public class Login {
boolean loginSuccess=false;
String id;
String password;
public void setId(String id){
this.id=id;
}

public void setPassword(String password){
this.password=password;
}

public String getId() {
return id;
}

public String getPassword() {
return password;
}

public void setLoginSuccess(boolean loginSuccess) {
this.loginSuccess = loginSuccess;
}

public boolean getLoginSuccess() {
return loginSuccess;
}
}

//登录处理者的代码
public class HandleLogin {
Connection con;
PreparedStatement preSql; //类似Statement,但PreparedStatement可以防止sql注入
ResultSet rs;
public HandleLogin(){
try{
Class.forName("com.hxtt.sql.access.AccessDriver");//com.mysql.jdbc.Driver
}catch (Exception e){}
String uri="jdbc:mysql://localhost:3306/register?&useSSL=true&serverTimezone=UTC";
try{
con= DriverManager.getConnection(uri,"root","123456");
}catch (SQLException e){}
}
public Login queryVerify(Login loginModel){
String id=loginModel.getId();
String pw= loginModel.getPassword();
String sqlStr="select id,password from register where "+"id = ? and password = ?";
try{
preSql=con.prepareStatement(sqlStr);
preSql.setString(1,id); //定义了字符串中第n个”?“字符的替换
preSql.setString(2,pw);
rs=preSql.executeQuery(); //执行查询
if(rs.next()==true){
loginModel.setLoginSuccess(true); //成功登录
JOptionPane.showMessageDialog(null,"login success","success",JOptionPane.WARNING_MESSAGE); //消息对话框
}
else{ //登录失败
loginModel.setLoginSuccess(false);
JOptionPane.showMessageDialog(null,"login fail","fail",JOptionPane.WARNING_MESSAGE);
}
con.close();
}catch (SQLException e){}
return loginModel;
}
}

//登录视图
public class LoginView extends JPanel implements ActionListener {
Login login;
JTextField inputID; //文本框
JPasswordField inputPassword; //密码框组件
JButton buttonLogin; //按钮组件
boolean loginSuccess;
LoginView(){
login=new Login();
inputID=new JTextField(12);
inputPassword=new JPasswordField(12);
buttonLogin=new JButton("login");
add(new JLabel("ID:"));
add(inputID);
add(new JLabel("password:"));
add(inputPassword);
add(buttonLogin);
buttonLogin.addActionListener(this); //设置监听器
}

public boolean isLoginSuccess() {
return loginSuccess;
}

@Override
public void actionPerformed(ActionEvent e) {
login.setId(inputID.getText()); //获得id
char[] pw=inputPassword.getPassword();
login.setPassword(new String(pw)); //获得password
HandleLogin handleLogin=new HandleLogin(); //连接数据库
login=handleLogin.queryVerify(login); //数据匹配
loginSuccess=login.getLoginSuccess();
}
}

//测试登录
public class View extends JFrame {
LoginView loginView;
View(){
setSize(600,200); //设置大小
setTitle("login"); //设置标题
loginView=new LoginView();
setLayout(new BorderLayout()); //使用BorderLayout布局,也可用其他的
add(loginView);
}
boolean isLoginSuccess(){
return loginView.isLoginSuccess();
}
public static void main(String[] args) {
View view=new View();
view.setVisible(true); //设置可见
view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗口时,退出程序
}
}

效果如下:

image-20210111184008055

image-20210111184035920

反射

反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Apple {
private int price;

public int getPrice() {
return price;
}

public void setPrice(int price) {
this.price = price;
}

public static void main(String[] args) throws Exception{
//正常的调用
Apple apple = new Apple();
apple.setPrice(5);
System.out.println("Apple Price:" + apple.getPrice());
//使用反射调用
Class clz = Class.forName("com.chenshuyi.api.Apple"); //获取类的 Class 对象实例
Method setPriceMethod = clz.getMethod("setPrice", int.class);
Constructor appleConstructor = clz.getConstructor(); //根据 Class 对象实例获取 Constructor 对象
Object appleObj = appleConstructor.newInstance(); //使用 Constructor 对象的 newInstance 方法获取反射类对象
setPriceMethod.invoke(appleObj, 14); //利用 invoke 方法调用方法
Method getPriceMethod = clz.getMethod("getPrice"); //获取方法的 Method 对象
System.out.println("Apple Price:" + getPriceMethod.invoke(appleObj));
}
}

期末试卷参考

答案仅供参考

判断题

image-20210102110613779

  1. 应该是
  2. ,可以定义构造方法(抽象类能不能实例化抽象类有没有构造函数 是两个概念。 抽象类可以有构造函数,它的构造函数自然有它的作用,比如:为它的子类所用)
  3. ,静态变量是在程序运行的时候就已经在内存中初始化完毕. 非静态方法调用静态变量没有问题(但注意静态方法不能调用非静态方法和变量,静态方法和静态变量是属于类的,在类加载的时候就会分配内存,可以通过类名直接去访问。非静态成员(变量和方法)属于类的对象,所以只有该对象初始化之后才存在,然后通过类的对象去访问。也就是说如果我们在静态方法中调用非静态成员变量会超前,可能会调用了一个还未初始化的变量。因此编译器会报错。)
  4. ,Java 中不允许类多重继承,只能单一继承,但有些情况单一继承并不能表达出现实世界中的某些逻辑关系,所以就提出了通过接口来实现多重继承。
  5. ,Java的类必须包含一个或一个以上的构造方法,用于构造该类的实例对象,只是构造方法不是必须显示定义的,如果没有定义构造方法,那么该类就有一个默认的无参数构造方法
  6. ,==是一个比较运算符,基本数据类型比较的是值,引用数据类型比较的是地址值。equals()是一个方法,只能比较引用数据类型。重写前比较的是地址值,重写后比较的对象属性
  7. ,但它并不是最理想的代码重用机制,因为继承总是带来一些多余的方法和数据成员,它们总是使得重用类里面某个方法的代码复杂化。

选择题

image-20210102113837723

image-20210102121200514

  1. A(Statement声明SQL语句对象,ResultSet对象存放查询结果)

  2. D(其他选项反过来都是对的)【有人疑问,抽象类实现接口是不需要必须实现接口的所有方法的。个人认为当你自己写的类想用接口中个别方法的时候(注意不是所有的方法),那么你就可以用一个抽象类先实现这个接口(方法体中为空),然后再用你的类继承这个抽象类,这样就可以达到你的目的了,如果你直接用类实现接口,那是所有方法都必须实现的。所以我觉得抽象类实现接口是为了实现类 不实现接口的某些方法,所以抽象类不算“实现接口”】

  3. D

  4. C, java不支持多继承,只支持单继承(即一个类只能有一个父类)。但是java接口支持多继承,即一个子接口可以有多个父接口。

  5. A(public是开放的)

  6. A

  7. A

  8. D

  9. C

  10. A(方法重载是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同。

    方法重写是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型 )

读程序题

1.给出 n 值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class InitDemo {
public static void main(String[] args) {
ParentA obj=new SubA();
obj.Addn(2);
System.out.println("n="+obj.getn());
}
}

class ParentA{
int n=10;
ParentA(){
n++;
}
void Addn(int i){}
int getn(){
return n;
}
}

class SubA extends ParentA{
SubA(){
n++;
}
void Addn(int i){
n+=i;
}
}

子类继承父类,创建子类对象时构造函数的执行顺序为:

父类成员变量显示初始化 —> 父类构造函数 —> 子类成员变量显示初始化 —> 子类构造

所以该题执行顺序为:

int n=10 --> ParentA() --> SubA() --> obj.Addn(2) --> obj.getn()即int getn()

答案:n=14

2.给出 n,m,t 的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ExceptionDemo {
public static void main(String[] args) {
int n=100,m=200,t=300;
try{
m=Integer.parseInt("1234");
n=Integer.parseInt("ab85"); //发生异常,转向 catch
t=123; //t 没有机会赋值
}
catch (NumberFormatException e){
System.out.println("异常:"+e.getMessage());
n=222; //执行了
}
finally { //无论 try 是否异常,都会执行,除非前面执行了程序退出代码,如 System.exit(0);
n=333;
System.out.println("n="+n+",m="+m+"t="+t);
}
}
}

答案:n=333,m=1234,t=300

3.求输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//标号表示debug执行行的顺序
abstract class Component{
public abstract void display();
}

class Window extends Component{ //2 创建子类对象
public void display(){
System.out.println("Display a Window!"); //17 第二次输出
} //18
}
class ComponentDecorator extends Component{
private Component component;
public ComponentDecorator(Component component){ //6
this.component=component; //7
} //8
public void display(){
component.display(); //16 调用子类Window重写的display方法
} //19
}
class ScrollBarDecorator extends ComponentDecorator{
public ScrollBarDecorator(Component component){
super(component); //5 父类中没有无參构造方法,子类中只能显示调用super
}//9
public void display(){ //子类重写了方法,父类的方法被隐藏
this.setScrollBar(); //12 调用 setScrollBar()方法
super.display(); //15 调用父类被隐藏的方法display()
} //20
public void setScrollBar(){
System.out.println("Add scroll bar for Component!"); //13 第一次输出
} //14
}

public class DecoratorTest {
public static void main(String[] args) {
Component component,componentSB;
component = new Window(); //1,3 子类构造
componentSB = new ScrollBarDecorator(component); //4,10 子类构造
componentSB.display(); //11
} //21
}

答案:

Add scroll bar for Component!
Display a Window!

4.求输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Father{
void sport(){
System.out.println("打篮球!");
}
}
class Son extends Father{
void sport(){ //重写方法
System.out.println("踢足球!");
}
}
public class Test {
public static void main(String[] args) {
Father person=new Son(); //上转型对象
person.sport();
}
}

答案:

踢足球!

5.求输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class TestCircle {
public static void main(String[] args) {
Circle c1=new Circle();
Circle c2=new SecCircle();
c2.radius=9;
Circle c3=new Circle(5);
System.out.println(""+c3.numberObjects); //可以通过对象访问
/*
也可以直接通过类名访问,下面输出也是一样的
System.out.println(""+Circle.numberObjects);
System.out.println(""+SecCircle.numberObjects);
*/
}
}
class Circle{
double radius;
static int numberObjects=0; //类变量,所有对象共享类变量
Circle(){
radius=1.0;
numberObjects++; //c1,c2创建时,分别加1
}
Circle(double newRadius){
radius=newRadius;
numberObjects++; //c3创建时加1
}
}
class SecCircle extends Circle{
}

答案:3

总结

简答题主要考的范围是重点4,5,6,7章。

有考到子类与父类、继承、构造方法、重写、super关键字、final关键字、上转型对象、抽象类、类变量、异常等,必须对相关知识熟悉。

简答题

1.写出遍历 double 类型的一维数组 score 的两种不同 for 语法结构的循环语句

1
2
3
4
5
6
for(int i= 0;i < score.length;i++){
System.out.println(score[i]);
}
for (double i:score){
System.out.println(i);
}

2.写出迭代器遍历LinkedList<Character> cArr的程序段

1
2
3
for (Iterator i = cArr.iterator(); i.hasNext();) {
System.out.println(i.next());
}

3.对类 Student 的对象数组 stu[],要按属性 name(String类型)来排序,请给出为解决该问题的类 Student的实现框架(与之无关的属性,方法可节略不写),及排序语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//方法1 lambda表达式
public class Test {
public static void main(String[] args) {
Student[] stu = new Student[] { new Student("zhangsan", 22),
new Student("lisi", 24), new Student("wangwu", 22),
new Student("zhaoliu", 23) };
System.out.println("----------before sorted---------");
for (Student e : stu)
System.out.println(e);
System.out.println("----------after sorted---------");
Arrays.sort(stu,(o1,o2)->{
return (o1.getName().compareTo(o2.getName()));
});
for (Student e : stu)
System.out.println(e);
}
}

//方法2 Comparable
public class Student implements Comparable<Student>{
//...
@Override
public int compareTo(Student o) {
return (this.getName().compareTo(o.getName()));
}
}
public class Test {
public static void main(String[] args) {
//...
Arrays.sort(myStudent);
//...
}
}

//方法3 Comparator
Arrays.sort(stu, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//升序排序,降序反写
return o1.getName().compareTo(o2.getName());
}
});

4.给出main()的主句的执行流程(调用与返回)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//标号表示debug执行行的顺序
class Father{
Father(){ //4
System.out.println("In constructor Father"); //5
} //6
}
class FirstGen extends Father{
FirstGen(){
System.out.println("In constructor FirstGen");
}
}
class SecondGen extends Father{
SecondGen(){ //3
System.out.println("In constructor SecondGen"); //7
} //8
}
public class ExecueOrder {
public static void main(String[] args) { //1
Father jpe=new SecondGen(); //2,8
} //9
}

主要考数组与排序,相关知识点数组、for循环、对象数组、迭代器、接口与排序等

编程

image-20210103111259913

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public abstract class Geometry {
abstract double getArea();
}

public class Pillar {
Geometry bottom;
double height;
public Pillar(Geometry bottom,double height){
this.bottom=bottom;
this.height=height;
}
public double getVolume(){
return bottom.getArea()*height;
}
}

public class Circle extends Geometry{
double r;
public Circle(double r){
this.r=r;
}
public double getArea(){
return(3.14*r*r);
}
}

public class Rectangle extends Geometry{
double a,b;
public Rectangle(double a,double b){
this.a=a;
this.b=b;
}
public double getArea(){
return a*b;
}
}

public class Triangle extends Geometry{
double a,b,c;
public Triangle(double a,double b,double c){
this.a=a;
this.b=b;
this.c=c;
}
public double getArea(){
double z =(a+b+c)/2f;
double S = Math.sqrt(z*(z-a)*(z-b)*(z-c));
return S;
}
}

public class Test {
public static void main(String[] args) {
Pillar pillar;
try{
Random r = new Random(1);
Class circle=Class.forName("fuck.Circle");
Field[] fs= circle.getDeclaredFields(); //获得成员变量
System.out.println("Number of parameters:" + fs.length); //输出成员变量个数
Constructor cons=circle.getConstructor(double.class); //获取有参构造
Geometry obj1=(Geometry)cons.newInstance(r.nextDouble()*5); //通过有参构造创建对象
Method getAreaMethod=circle.getMethod("getArea"); //获得方法
System.out.println("Area:" + getAreaMethod.invoke(obj1)); //输出底面积
pillar=new Pillar(obj1,r.nextInt(10));
System.out.println("Volume:"+pillar.getVolume()); //输出体积

//依次测试剩下两类,代码类似同上...
}
catch (Exception e){
e.printStackTrace();
}
}
}

类关系图见书本P135页

复习资料

2020电子科技大学Java程序设计作业

北邮《Java技术》期末复习题(含答案)

2019年秋季北邮《Java技术》期末考试复习题

考后回顾

无话可说、好自为之、自求多福:)

编程题基本上都蒙对了,代码大差不差的套就完事了

一定要理解面向对象编程还有面向抽象与接口编程,还有反射等等,否则……

恶意压分严重:)