第六知识单元

综合应用

Java程序设计 第14讲,主讲人:李欣

Created: 2023-12-06 Wed 00:05

0.1. 互动课堂

Click to host the seminar.

0.2. 签到

https://xin.blue/tool/attendance/

1. 例题

编写Java代码实现一个计数器类 Counter ,包含域 counterValue 用来保存计数器的当前数值, 方法 increment() 使计数器加一、方法 decrement() 使计数器减一、方法 reset() 使计数器清零。

public class Exercise {
    public static void main (String[] args) {
        Counter n = new Counter();
        System.out.println("计数器加1:" + n.increment());
        System.out.println("计数器减1:" + n.decrement());
        System.out.println("计数器清零:" + n.reset());
        System.out.println("计数器加1:" + n.increment());
        System.out.println("计数器减1:" + n.decrement());
    }
}
class Counter {
    private static int counterValue = 5;
    int increment() {
        return ++counterValue;
    }
    int decrement() {
        return --counterValue;
    }
    int reset() {
        counterValue = 0;
        return 0;
    }   
}
计数器加1:6
计数器减1:5
计数器清零:0
计数器加1:1
计数器减1:0

2. 例题

编程实现矩形类,其中包括计算矩形周长和面积的方法。

public class Exercise {
    public static void main (String[] args) {
        Rectangle rectangle1 = new Rectangle (3, 12);
        Rectangle rectangle2 = new Rectangle (8, 21);
        System.out.println("矩形1周长:" + rectangle1.perimeter());
        System.out.println("矩形1面积:" + rectangle1.area());
        System.out.println("矩形2周长:" + rectangle2.perimeter());
        System.out.println("矩形2面积:" + rectangle2.area());
    }
}
class Rectangle {
    private int length;
    private int width;
    Rectangle(int l, int w) {
        this.length = l;
        this.width = w;
    }
    int perimeter () {
        return (length + width) * 2;
    }
    int area () {
        return length * width;
    }
}
矩形1周长:30
矩形1面积:36
矩形2周长:58
矩形2面积:168

3. 例题

使用上题的矩形类,编程统计若干块土地的相关信息,由用户输入每块儿土地的长与宽,程序将相关结果输出。

import java.util.*;
public class Exercise {
    public static void main (String[] args) {
        Rectangle rectangle1 = new Rectangle();
        Rectangle rectangle2 = new Rectangle();
        System.out.print("输入第一块土地长与宽:");
        Scanner in = new Scanner (System.in);
        int rectangle1Length = in.nextInt();
        int rectangle1Width = in.nextInt();
        System.out.println("周长:" + 
                           rectangle1.perimeter(rectangle1Length, rectangle1Width));
        System.out.println("面积:" + 
                           rectangle1.area(rectangle1Length, rectangle1Width));
        System.out.print("输入第二块土地长与宽:");
        int rectangle2Length = in.nextInt();
        int rectangle2Width = in.nextInt();
        System.out.println("周长:" + 
                           rectangle2.perimeter(rectangle2Length, rectangle2Width));
        System.out.println("面积:" + 
                           rectangle2.area(rectangle2Length, rectangle2Width));
    }
}
class Rectangle {
    private int length;
    private int width;
    Rectangle(int l, int w) {
        this.length = l;
        this.width = w;
    }
    Rectangle () {
    }
    int perimeter (int length, int width) {
        return (length + width) * 2;
    }
    int area (int length, int width) {
        return length * width;
    }
}
// Output
// 输入第一块土地长与宽:2 3
// 周长:10
// 面积:6
// 输入第二块土地长与宽:4 5
// 周长:18
// 面积:20

4. 例题

定义一个表示学生的类 Student ,包括域 id name gender classId age , 方法 getId() getName() getGender() getClassId() getAge() setAge(int age)

// Student.java
class Student {
    private String id; // 学号
    private String name; // 姓名
    private boolean gender; // 性别
    private String classId; // 班级
    private int age; // 年龄
    // 获得学号
    public String getId() {
        return id;
    }
    // 获得姓名
    public String getName() {
        return name;
    }
    // 获得性别
    public boolean getGender() {
        return gender;
    }
    // 获得班级
    public String getClassId() {
        return classId;
    }
    // 获得年龄
    public int getAge() {
        return age;
    }
    // 修改年龄
    public void setAge(int age) {
        this.age = age;
    }
}

5. 例题

在上题的基础上为 Student 类定义构造方法并初始化所有的域, 增加一个 toString() 方法把 Student 类对象的所有域信息组合成一个字符串。 编程创建 Student 类的对象并测试新增的功能。

// Test.java
public class Test {
    public static void main(String[] args) {
        Student s = new Student("2021000000", "张三", true, "计-21", 18);
        System.out.println(s);
    }
}
class Student {
    private String id; // 学号
    private String name; // 姓名
    private boolean gender; // 性别
    private String classId; // 班级
    private int age; // 年龄
    Student(String id, String name, boolean gender, String classId, int age) {
        this.id = id; // 学号
        this.name = name; // 姓名
        this.gender = gender; // 性别
        this.classId = classId; // 班级
        this.age = age; // 年龄
    }
    // 获得学号
    public String getId() {
        return id;
    }
    // 获得姓名
    public String getName() {
        return name;
    }
    // 获得性别
    public boolean getGender() {
        return gender;
    }
    // 获得班级
    public String getClassId() {
        return classId;
    }
    // 获得年龄
    public int getAge() {
        return age;
    }
    // 修改年龄
    public void setAge(int age) {
        this.age = age;
    }
    public String toString() {
        return "学生学号:" + getId() + "\n" +
            "学生姓名:" + getName() + "\n" +
            "学生性别:" + (getGender() ? "男" : "女") + "\n" +
            "学生班级:" + getClassId() + "\n" +
            "学生年龄:" + getAge();
    }
}
学生学号:2021000000
学生姓名:张三
学生性别:男
学生班级:计-21
学生年龄:18

6. 例题

定义一个父类 Animal ,包含 public 成员属性 name age 与方法 showProfile() , 接着定义其子类 Cat 并包含一个成员方法 sleep() 。 编程创建 Cat 类的对象,为该对象的 name age 属性赋值, 并调用父类中定义的方法 showProfile() 与子类中定义的方法 sleep()

public class Exercise {
    public static void main( String[] args ) {
        Cat myCat = new Cat();
        myCat.name = "Shiro";
        myCat.age = 3;
        myCat.showProfile();
        myCat.sleep();
    }
}
class Animal {
    public String name;
    public int age;
    public void showProfile() {
        System.out.println( "名字:" + name + ",年龄:" + age );
    }
}
class Cat extends Animal {
    public void sleep() {
        System.out.println( name + "开始睡觉。" );
    }
}
名字:Shiro,年龄:3
Shiro开始睡觉。

shiro.png

Figure 1: Shiro开始睡觉的真实写照

7. 例题

在上题的基础上定义一个 Animal 的子类 Dog ,包含成员方法 run() 。 编程分别创建一个 Cat 类的对象和一个 Dog 类的对象并分别为两个对象的属性赋值, 分别调用它们的 showProfile() 方法,然后调用各对象特有的方法 sleep()run()

public class Exercise {
    public static void main( String[] args ) {
        Cat myCat = new Cat();
        Dog myDog = new Dog();
        myCat.name = "洋葱";
        myCat.age = 3;
        myDog.name = "土豆";
        myDog.age = 4;
        myCat.showProfile();
        myDog.showProfile();
        myCat.sleep();
        myDog.run();
    }
}
class Dog extends Animal {
    public void run() {
        System.out.println( name + "开始奔跑。" );
    }
}
名字:洋葱,年龄:3
名字:土豆,年龄:4
洋葱开始睡觉。
土豆开始奔跑。

8. 例题

在上题的基础上为 Animal 类增加成员方法 speak() ,并在子类 CatDog 中分别覆盖重写该方法, 编程创建两个子类的对象并调用 showProfile()speak() 方法。

public class Exercise {
    public static void main( String[] args ) {
        Cat myCat = new Cat();
        Dog myDog = new Dog();
        myCat.name = "洋葱";
        myCat.age = 3;
        myDog.name = "土豆";
        myDog.age = 4;
        myCat.showProfile();
        myDog.showProfile();
        myCat.speak();
        myDog.speak();
    }
}
class Animal {
    public String name;
    public int age;
    public void showProfile() {
        System.out.println( "名字:" + name + ",年龄:" + age );
    }
    public void speak() {
        System.out.println( "......" );
    }
}
class Cat extends Animal {
    public void sleep() {
        System.out.println( name + "开始睡觉。" );
    }
    public void speak() {
        System.out.println( "喵~" );
    }
}
class Dog extends Animal {
    public void run() {
        System.out.println( name + "开始奔跑。" );
    }
    public void speak() {
        System.out.println( "汪~" );
    }
}
名字:洋葱,年龄:3
名字:土豆,年龄:4
喵~
汪~

9. 例题

在上题的基础上编程创建一个长度为4的 Animal 类的数组, 并创建该数组中的偶数元素为 Cat 类的对象,奇数元素为 Dog 类的对象,调用数组中所有对象的 speak() 方法。

public class Exercise {
    public static void main( String[] args ) {
        Animal[] myPets = new Animal[4];
        myPets[0] = new Cat();
        myPets[1] = new Dog();
        myPets[2] = new Cat();
        myPets[3] = new Dog();
        for( Animal pet : myPets )
            pet.speak();
    }
}
喵~
汪~
喵~
汪~

10. 例题

编写一个只含有一个方法 int method(int n) 的接口 InterfaceA , 再编写一个类 ClassA 来实现接口 InterfaceA 。 实现接口方法 int method(int n) 时,要求计算 \(1\) 到 \(n\) 的和。

class ClassA implements InterfaceA {
    @Override
    public int method( int n ) {
        int sum = 0;
        for( int i = 0; i <= n; i++ ) {
            sum += i;
        }
        return sum;
    }
}
interface InterfaceA {
    int method( int n );
}

11. 例题

在上题的基础上,编写另一个类 ClassB 来实现接口 InterfaceA , 实现接口方法 int method(int n) 时,要求计算 \(n\) 的阶乘 \(n!\) , 最后使用接口回调的方式来测试 \(n = 4\) 时的程序执行情况。

class Exercise {
    public static void main(String[] args) {
        InterfaceA a = new ClassA();
        System.out.println(a.method(4));
        InterfaceA b = new ClassB();
        System.out.println(b.method(4));
    }
}
class ClassB implements InterfaceA {
    @Override
    public int method( int n ) {
        int ji = 1;
        for( int j = 1; j <= n; j++ ) {
            ji *= j;
        }
        return ji;
    }
}
class ClassA implements InterfaceA {
    @Override
    public int method( int n ) {
        int sum = 0;
        for( int i = 0; i <= n; i++ ) {
            sum += i;
        }
        return sum;
    }
}
interface InterfaceA {
    int method( int n );
}
10
24

12. 例题

设计一个名为 MyPoint 的类,包含以 \(x\) 坐标和 \(y\) 坐标表示的点。

设计该类的具体需求包括:

  1. 数据属性 \(x\) 和 \(y\) ,用于表示坐标,
  2. setX setYgetX getY 方法,分别用于设置及获取数据属性 \(x\) 和 \(y\) ;
  3. 创建点 \((0, 0)\) 的无参构造方法;
  4. 创建特定坐标点的构造方法;
  5. distance 方法,返回从该点到 MyPoint 类型的指定点之间的距离;
  6. distance 方法,返回从该点到由 \(x\) 和 \(y\) 确定的点之间的距离,体会方法重载;
  7. 编写一个测试程序,创建两个点的对象,并显示他们之间的距离。
class Test {
    public static void main(String[] args) {
        MyPoint p1 = new MyPoint();
        MyPoint p2 = new MyPoint(3, 4);
        System.out.println(p1.distance(p2));
    }
}
class MyPoint {
    private double x;
    private double y;
    MyPoint() {
        x = 0;
        y = 0;
    }
    MyPoint(double x, double y) {
        this.x = x;
        this.y = y;
    }
    public void setX(double x) {
        this.x = x;
    }
    public void setY(double y) {
        this.y = y;
    }
    public double getX() {
        return x;
    }
    public double getY() {
        return y;
    }
    public double distance(MyPoint p) {
        return Math.sqrt(Math.pow(p.getX() - x, 2) + Math.pow(p.getY() - y, 2));
    }
    public double distance(double x, double y) {
        return Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2));
    }
}
5.0