Selaa lähdekoodia

feat: 完善c260727授课代码——补充匿名内部类完整实现(Usb/Tableware/Compute/Sort),更新gitingore,删除已废弃的内部类练习旧文件

WanJL 18 tuntia sitten
vanhempi
commit
359d23a031

+ 30 - 0
授课代码/c260727/.gitignore

@@ -0,0 +1,30 @@
+### IntelliJ IDEA ###
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+.kotlin
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 6 - 5
授课代码/c260727/src/course/Compute.java

@@ -1,11 +1,12 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Compute
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
-public class Compute {
+public abstract class Compute {
+    public abstract int add(int a,int b);
 }

+ 66 - 4
授课代码/c260727/src/course/Demo01.java

@@ -1,11 +1,73 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Demo01
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description 匿名内部类
+ * @create 2026/7/27
  */
 public class Demo01 {
+    /*
+        Java中的内部类分为三大类:
+            成员内部类:
+                |-普通成员内部类
+                |-静态成员内部类
+            局部内部类
+            匿名内部类
+
+        匿名内部类,顾名思义,就是这个类没有名字,是匿名,一般就是定义之后,直接使用。
+        匿名内部类的前提:
+            存在一个类或接口,这里的类可以是普通类也可以是抽象类
+        匿名内部类的格式:
+            new 类名(){       // 类名可以是普通父类、抽象父类、或 接口
+                重写类的方法。
+            };
+            new 接口名(){       // 类名可以是普通父类、抽象父类、或 接口
+                重写接口的方法。
+            };
+
+        匿名内部类的本质是一个继承了某个类或实现了某个接口的【子类的匿名对象】
+        匿名内部类可以使用多态的形式来接收
+        Compute compute = new Compute() {
+            @Override
+            public int add(int a, int b) {
+                return a + b;
+            }
+        };
+        compute.add(15,3);
+
+        匿名内部类直接调用方法
+        new Compute() {
+            @Override
+            public int add(int a, int b) {
+                return a + b;
+            }
+            public void method(){
+                System.out.println("匿名内部类特有的方法");
+            }
+        }.mthod();
+
+        匿名内部类在开发中的使用:
+            比如发现某个方法需接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码。
+
+     */
+    public static void main(String[] args) {
+        //创建Usb接口的匿名内部类
+        Usb usb=new Usb(){
+            @Override
+            public void startUsb() {
+                System.out.println("启动鼠标");
+            }
+
+            @Override
+            public void closeUsb() {
+                System.out.println("关闭鼠标");
+            }
+        };
+        usb.startUsb();
+        usb.closeUsb();
+
+
+    }
 }

+ 12 - 4
授课代码/c260727/src/course/NoteBook.java

@@ -1,11 +1,19 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title NoteBook
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class NoteBook {
+    /**
+     * 使用USB设备
+     * @param usb 接口,实际参数要传入的是实现类对象/匿名内部类对象
+     */
+    public void useUSB(Usb usb){
+        usb.startUsb();
+        usb.closeUsb();
+    }
 }

+ 13 - 4
授课代码/c260727/src/course/Person.java

@@ -1,11 +1,20 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Person
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class Person {
+    /**
+     * 吃饭
+     * @param tableware 吃饭使用的餐具
+     */
+    public void eat(Tableware tableware){
+        tableware.openTableware();
+        tableware.useTableware();
+        System.out.println("开始干饭......");
+    }
 }

+ 5 - 4
授课代码/c260727/src/course/Sort.java

@@ -1,11 +1,12 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Sort
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public interface Sort {
+    Student compare(Student s1,Student s2);
 }

+ 37 - 4
授课代码/c260727/src/course/Student.java

@@ -1,11 +1,44 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Student
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class Student {
+    private String id;
+    private String name;
+    private Integer age;
+
+    public Student(String id, String name, Integer age) {
+        this.id = id;
+        this.name = name;
+        this.age = age;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getAge() {
+        return age;
+    }
+
+    public void setAge(Integer age) {
+        this.age = age;
+    }
 }

+ 7 - 5
授课代码/c260727/src/course/Tableware.java

@@ -1,11 +1,13 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Tableware
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
-public class Tableware {
+public interface Tableware {
+    void openTableware();
+    void useTableware();
 }

+ 18 - 4
授课代码/c260727/src/course/Test01.java

@@ -1,11 +1,25 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Test01
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class Test01 {
+    public static void main(String[] args) {
+        NoteBook nb=new NoteBook();
+        nb.useUSB(new Usb() {
+            @Override
+            public void startUsb() {
+                System.out.println("使用USB临时设备");
+            }
+
+            @Override
+            public void closeUsb() {
+                System.out.println("关闭USB临时设备");
+            }
+        });
+    }
 }

+ 22 - 4
授课代码/c260727/src/course/Test02.java

@@ -1,11 +1,29 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Test02
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class Test02 {
+    public static void main(String[] args) {
+        Person person=new Person();
+        //如果直接创建 Tableware 接口的实现类,那么除了自己之外,这个实现类也可能会被其他人使用
+        //如果不想不能让其他人使用当前要用的那个接口实现类,就可以使用匿名内部类
+        Tableware tableware = new Tableware() {
+            @Override
+            public void openTableware() {
+                System.out.println("打开一次性筷子");
+            }
+
+            @Override
+            public void useTableware() {
+                System.out.println("使用一次性筷子");
+            }
+        };
+        // 调用这个接口的匿名内部类
+        person.eat(tableware);
+    }
 }

+ 21 - 4
授课代码/c260727/src/course/Test03.java

@@ -1,11 +1,28 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Test03
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class Test03 {
+    public static void main(String[] args) {
+        Student s1 = new Student("1001", "张三", 20);
+        Student s2 = new Student("1002", "李四", 25);
+        Sort sort = new Sort() {
+
+            @Override
+            public Student compare(Student s1, Student s2) {
+                if (Integer.getInteger(s1.getId()) < Integer.getInteger(s2.getId()))
+                    return s1;
+                else
+                    return s2;
+            }
+        };
+        Student max = sort.compare(s1, s2);
+        System.out.println(max.getName());
+
+    }
 }

+ 6 - 4
授课代码/c260727/src/course/Usb.java

@@ -1,11 +1,13 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title Usb
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public interface Usb {
+    void startUsb();
+    void closeUsb();
 }

+ 14 - 5
授课代码/c260727/src/course/筷子.java

@@ -1,11 +1,20 @@
 package course;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title 筷子
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
-public class 筷子 {
+public class 筷子 implements Tableware{
+    @Override
+    public void openTableware() {
+
+    }
+
+    @Override
+    public void useTableware() {
+
+    }
 }

+ 178 - 4
授课代码/c260727/src/homework_0724/p2_myarray/MyArray.java

@@ -1,11 +1,185 @@
 package homework_0724.p2_myarray;
 
+import java.util.Arrays;
+
 /**
+ * @author WanJl
+ * @version 1.0
  * @title MyArray
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class MyArray {
+    //内部真正存储数据的数组
+    private int[] data;
+    //当前已存储的元素个数(不是数组长度)
+    private int size;
+
+    /**
+     * 无参构造,默认初始化容量为 10 的数组
+     */
+    public MyArray() {
+        this.data=new int[10];
+    }
+
+    /**
+     * 指定初始容量,如果传入的容量 ≤ 0,则使用默认容量 10
+     * @param capacity
+     */
+    public MyArray(int capacity) {
+        if (capacity<=0) {
+            this.data=new int[10];
+        }else {
+            this.data=new int[capacity];
+        }
+    }
+
+    /**
+     * 1. 添加元素 — add(int element)
+     * 如果内部数组已满,自动扩容为当前容量的 1.5 倍(data.length * 3 / 2)
+     * 扩容步骤:创建新数组 → 复制旧元素 → 替换 data 引用
+     * 将新元素存入 data[size],size 自增 1
+     * @param element
+     */
+    public void add(int element){
+        int[] newArr;
+        if(size>=data.length){  //内部数组已满--已存储元素等于数组长度
+            newArr=new int[data.length*3/2];
+        }else {
+            newArr=new int[data.length];
+        }
+        //复制旧数组的元素到新数组
+        for (int i = 0; i < size; i++) {
+            newArr[i]=data[i];
+        }
+        //插入最新元素到数组末尾
+        newArr[size]=element;
+        //元素个数++
+        size++;
+        //替换 data 引用
+        this.data=newArr;
+    }
+
+    /**
+     * 2. 获取元素 — get(int index)
+     * 下标越界时输出 "下标越界,无法获取元素",返回 -1
+     * 否则返回 data[index]
+     * @param index
+     * @return
+     */
+    public int get(int index){
+        if (index>=size){
+            System.out.println("下标越界,无法获取元素");
+            return -1;
+        }
+        return data[index];
+    }
+
+    /**
+     * 3. 修改元素 — set(int index, int element)
+     * 下标越界时输出 "下标越界,无法修改元素"
+     * 否则将 data[index] 赋值为 element
+     * @param index
+     * @param element
+     */
+    public void set(int index, int element){
+        if (index>=size){
+            System.out.println("下标越界,无法修改元素");
+        }else {
+            //完成赋值
+            data[index]=element;
+        }
+    }
+
+    /**
+     * 9. 删除指定位置的元素 — remove(int index)
+     * 下标越界时输出 "下标越界,无法删除元素",返回 -1
+     * 否则:保存被删除的值 → 后面元素前移一位 → size-- → 返回被删除的值
+     * @param index
+     * @return
+     */
+    public int remove(int index){
+        if (index>=size){
+            System.out.println("下标越界,无法删除元素");
+            return -1;
+        }
+        //保存被删除的值
+        int del=data[index];
+        //建立新的数组
+        int[] newArr=new int[data.length];
+        //循环--复制旧数组的Index之前的元素到新数组的对应位置
+        for (int i = 0; i < size-1; i++) {
+            if (i<index){
+                newArr[i]=data[i];
+            }else {
+                newArr[i]=data[i+1];
+            }
+        }
+        //新数组替换旧数组
+        data=newArr;
+        //size-1
+        size--;
+        return del;
+    }
+
+    /**
+     * 11. 数组排序 — sort(boolean ascending)
+     * true 升序,false 降序
+     * 使用冒泡排序,只对 data[0] ~ data[size-1] 排序
+     * @param ascending
+     */
+    public void sort(boolean ascending){
+        for (int i = 0; i < size-1; i++) {
+            for (int j = 0; j < size-1-i; j++) {
+                if (ascending){
+                    if (data[j]>data[j+1]){
+                        exchange(j, j+1);
+                    }
+                }else {
+                    if (data[j]<data[j+1]){
+                        exchange(j, j+1);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 私有的交换函数
+     * @param a 索引值1
+     * @param b 索引值2
+     */
+    private void exchange(int a,int b){
+        int t=data[a];
+        data[a]=data[b];
+        data[b]=t;
+    }
+
+
+    /**
+     * print()
+     * 遍历输出格式:[元素1, 元素2, 元素3, ...]
+     * 空数组输出 []
+     */
+    public void print(){
+        if (size>0){
+            System.out.print("[");
+            for (int i = 0; i <size; i++) {
+                System.out.print(data[i]);
+                if (i<size-1)
+                    System.out.print(", ");
+            }
+            System.out.println("]");
+        }else {
+            System.out.println("[]");
+        }
+    }
+
+    /**
+     * 返回 size 属性值
+     * @return
+     */
+    public int size(){
+        return this.size;
+    }
 }

+ 24 - 4
授课代码/c260727/src/homework_0724/p2_myarray/MyArrayTest.java

@@ -1,11 +1,31 @@
 package homework_0724.p2_myarray;
 
 /**
+ * @author WanJl
+ * @version 1.0
  * @title MyArrayTest
- * @description 
- * @author WanJl 
- * @version 1.0 
- * @create 2026/7/27 
+ * @description
+ * @create 2026/7/27
  */
 public class MyArrayTest {
+    public static void main(String[] args) {
+        MyArray array=new MyArray();
+        array.add(15);
+        array.add(20);
+        array.add(18);
+        array.add(44);
+        array.add(92);
+        array.add(35);
+        array.add(66);
+        array.add(79);
+        array.print();
+        //System.out.println(array.size());
+        //int remove = array.remove(4);
+        //System.out.println("被删除的是:"+remove);
+       // array.print();
+        array.sort(false);
+        array.print();
+
+
+    }
 }

+ 153 - 0
授课代码/c260727/src/homework_0724/p2_myarray/题目.md

@@ -0,0 +1,153 @@
+## 第 2 题:综合大挑战——MyArray 可变数组(动态数组底层实现)⭐⭐⭐⭐⭐
+
+**包名**:`p2_myarray`
+
+**知识点**:构造方法、数组扩容、方法封装、增删改查、元素前移、冒泡排序
+
+> 模仿 `ArrayList` 的底层原理,自己动手实现一个可变数组(动态数组)。
+
+### 需求背景
+
+Java 中普通数组 `int[]` 一旦创建,长度就固定了,无法动态增减元素。请自行实现一个 **可变整型数组** `MyArray` 类,内部使用 `int[]` 存储数据,对外提供便捷的增删改查方法。
+
+### 实体类说明:MyArray
+
+**私有属性**:
+
+| 属性   | 类型    | 说明                                 |
+| ------ | ------- | ------------------------------------ |
+| `data` | `int[]` | 内部真正存储数据的数组               |
+| `size` | `int`   | 当前已存储的元素个数(不是数组长度) |
+
+**构造方法**:
+
+| 构造方法                | 说明                                                |
+| ----------------------- | --------------------------------------------------- |
+| `MyArray()`             | 无参构造,默认初始化容量为 **10** 的数组            |
+| `MyArray(int capacity)` | 指定初始容量,如果传入的容量 ≤ 0,则使用默认容量 10 |
+
+### 核心方法列表(共 11 个)
+
+#### 1. 添加元素 — `add(int element)`
+
+- 如果内部数组已满,自动扩容为当前容量的 **1.5 倍**(`data.length * 3 / 2`)
+- 扩容步骤:创建新数组 → 复制旧元素 → 替换 `data` 引用
+- 将新元素存入 `data[size]`,`size` 自增 1
+
+#### 2. 获取元素 — `get(int index)`
+
+- 下标越界时输出 `"下标越界,无法获取元素"`,返回 `-1`
+- 否则返回 `data[index]`
+
+#### 3. 修改元素 — `set(int index, int element)`
+
+- 下标越界时输出 `"下标越界,无法修改元素"`
+- 否则将 `data[index]` 赋值为 `element`
+
+#### 4. 获取长度 — `size()`
+
+- 返回 `size` 属性值
+
+#### 5. 获取容量 — `capacity()`
+
+- 返回 `data.length`
+
+#### 6. 判断是否为空 — `isEmpty()`
+
+- `size == 0` 返回 `true`,否则 `false`
+
+#### 7. 查找元素下标 — `indexOf(int element)`
+
+- 从前向后遍历,找到第一个匹配的元素下标,没找到返回 `-1`
+
+#### 8. 判断是否包含 — `contains(int element)`
+
+- 调用 `indexOf()`,根据返回值是否为 `-1` 判断
+
+#### 9. 删除指定位置的元素 — `remove(int index)`
+
+- 下标越界时输出 `"下标越界,无法删除元素"`,返回 `-1`
+- 否则:保存被删除的值 → 后面元素前移一位 → `size--` → 返回被删除的值
+
+#### 10. 删除指定值的元素 — `removeByValue(int element)`
+
+- 调用 `indexOf()` 获取下标
+- 下标为 `-1` 则输出 `"未找到该元素,删除失败"`,返回 `false`
+- 否则调用 `remove(index)`,返回 `true`
+
+#### 11. 数组排序 — `sort(boolean ascending)`
+
+- `true` 升序,`false` 降序
+- 使用**冒泡排序**,只对 `data[0] ~ data[size-1]` 排序
+
+### 辅助方法
+
+#### `print()`
+
+- 遍历输出格式:`[元素1, 元素2, 元素3, ...]`
+- 空数组输出 `[]`
+
+#### `clear()`
+
+- 将 `size` 置为 `0`(内部数组保留)
+
+### 测试类要求
+
+**`MyArrayTest` 类**:
+
+```java
+public class MyArrayTest {
+    public static void main(String[] args) {
+        // 1. 创建一个初始容量为 3 的 MyArray 对象
+        MyArray arr = new MyArray(3);
+
+        // 2. 输出初始状态
+        System.out.println("初始容量:" + arr.capacity());   // 3
+        System.out.println("是否为空:" + arr.isEmpty());     // true
+
+        // 3. 添加 5 个元素(触发自动扩容)
+        for (int i = 1; i <= 5; i++) {
+            arr.add(i * 10);  // 添加 10, 20, 30, 40, 50
+        }
+        arr.print();           // [10, 20, 30, 40, 50]
+
+        // 4. 测试各个方法
+        System.out.println("元素个数:" + arr.size());        // 5
+        System.out.println("当前容量:" + arr.capacity());     // 6
+        System.out.println("下标2的元素:" + arr.get(2));     // 30
+        System.out.println("是否包含40:" + arr.contains(40)); // true
+        System.out.println("50的下标:" + arr.indexOf(50));   // 4
+
+        // 5. 测试修改
+        arr.set(1, 99);
+        arr.print();           // [10, 99, 30, 40, 50]
+
+        // 6. 测试删除
+        int deleted = arr.remove(2);
+        System.out.println("被删除的元素:" + deleted);       // 30
+        arr.print();           // [10, 99, 40, 50]
+
+        // 7. 测试按值删除
+        arr.removeByValue(10);
+        arr.print();           // [99, 40, 50]
+
+        // 8. 测试升序排序
+        arr.sort(true);
+        arr.print();           // [40, 50, 99]
+
+        // 9. 测试降序排序
+        arr.sort(false);
+        arr.print();           // [99, 50, 40]
+
+        // 10. 测试越界访问
+        System.out.println(arr.get(10));  // 下标越界,无法获取元素 → -1
+        arr.remove(10);                   // 下标越界,无法删除元素 → -1
+    }
+}
+```
+
+### 思考题
+
+1. 如果 `add()` 方法中每次只扩容 1 个容量(`data.length + 1`),当添加大量元素时性能会怎样?为什么选择 1.5 倍?
+2. `remove()` 方法中为什么要将后面的元素向前移动?如果删除的是最后一个元素还需要移动吗?
+3. 如何将 `MyArray` 改造为支持任意类型的 `MyArrayList<T>`?