Java学习笔记(二)面向对象

前言

Java 入门后,数组、方法、面向对象是进阶路上的核心知识点,也是后续学习集合、框架的基础。本文基于实战场景,从定义、格式、示例到避坑指南,全方位拆解这三大模块,所有代码可直接复制运行,新手跟着操作就能轻松掌握,帮你打通 Java 进阶的关键环节~

一、数组:Java 中的 "容器" 神器

1. 数组是什么?

数组是 Java 中用于存储多个同类型元素的容器,比如存储一组整数、字符串等,访问效率极高,适合批量处理数据。

2. 数组的两种初始化方式

2.1 动态初始化(指定长度,系统给默认值)
复制代码
// 格式1(推荐)
数据类型[] 数组名 = new 数据类型[长度];
// 格式2(兼容C语言写法)
数据类型 数组名[] = new 数据类型[长度];

// 示例:定义长度为3的int数组
public class ArrayDemo01 {
    public static void main(String[] args) {
        int[] arr1 = new int[3]; // 默认值:[0, 0, 0]
        int arr2[] = new int[3]; // 效果同上
        System.out.println(arr1[0]); // 输出:0(int数组默认值)
    }
}
2.2 静态初始化(指定元素,系统定长度)
复制代码
// 格式1
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3};
// 格式2(推荐,简洁)
数据类型[] 数组名 = {元素1, 元素2, 元素3};

// 示例:定义存储11、22、33的int数组
public class ArrayDemo02 {
    public static void main(String[] args) {
        int[] arr3 = new int[]{11, 22, 33};
        int[] arr4 = {11, 22, 33}; // 推荐写法
        System.out.println(arr4[1]); // 输出:22
    }
}

3. 数组的核心用法(新手必会)

3.1 访问 / 修改元素(通过索引)

数组索引从 0 开始,格式:数组名[索引]

复制代码
public class ArrayDemo03 {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33};
        // 访问元素
        System.out.println(arr[0]); // 输出:11(第一个元素)
        // 修改元素
        arr[1] = 222;
        System.out.println(arr[1]); // 输出:222
    }
}
3.2 获取数组长度

通过数组名.length获取,避免索引越界

复制代码
public class ArrayDemo04 {
    public static void main(String[] args) {
        String[] names = {"张三", "李四", "王五"};
        System.out.println(names.length); // 输出:3(数组长度)
    }
}
3.3 数组默认值规则
数据类型 默认值
int/byte/short/long 0
float/double 0.0
boolean false
String / 引用类型 null

4. 数组的 3 个常见操作(实战案例)

4.1 遍历数组(循环输出所有元素)
复制代码
// 需求:遍历数组{11,22,33,44,55}
public class ArrayDemo05 {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33, 44, 55};
        // for循环遍历(推荐)
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]); // 依次输出11、22、33、44、55
        }
    }
}
4.2 获取数组最大值
复制代码
// 需求:找出数组{5,15,2000,10000,4000}的最大值
public class ArrayDemo06 {
    public static void main(String[] args) {
        int[] arr = {5, 15, 2000, 10000, 4000};
        int max = arr[0]; // 假设第一个元素是最大值
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i]; // 更新最大值
            }
        }
        System.out.println("最大值:" + max); // 输出:10000
    }
}
4.3 反转数组(首尾元素交换)
复制代码
// 需求:反转数组{1,2,3,4,5},结果为{5,4,3,2,1}
public class ArrayDemo07 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        for (int i = 0; i < arr.length / 2; i++) {
            // 首尾元素交换
            int temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }
        // 遍历验证
        for (int num : arr) {
            System.out.print(num + " "); // 输出:5 4 3 2 1
        }
    }
}

5. 数组的 2 个常见异常(避坑指南)

5.1 数组索引越界异常(ArrayIndexOutOfBoundsException)
  • 原因:访问了不存在的索引(比如长度为 2 的数组,访问索引 2)

  • 示例:

    public class ArrayDemo08 {
    public static void main(String[] args) {
    int[] arr = {11, 22};
    System.out.println(arr[2]); // 报错:索引2不存在
    }
    }

  • 解决:确保索引范围在0 ~ 数组长度-1之间

5.2 空指针异常(NullPointerException)
  • 原因:数组赋值为null后,仍尝试访问元素

  • 示例:

    public class ArrayDemo09 {
    public static void main(String[] args) {
    int[] arr = {11, 22};
    arr = null; // 数组变为空对象
    System.out.println(arr[0]); // 报错:空指针
    }
    }

  • 解决:避免给数组赋null,或访问前判断是否为null

二、方法:Java 中的 "功能模块"

1. 方法是什么?

方法是将具有独立功能的代码块封装起来的 "模块",比如遍历数组、计算最值,可重复调用,提高代码复用性。

2. 方法的定义格式

复制代码
修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2) {
    方法体; // 具体功能代码
    return 返回值; // 无返回值则省略return
}

// 示例:定义一个计算两数之和的方法
public class MethodDemo01 {
    // 修饰符:public static(固定),返回值类型:int,方法名:add,参数:a和b
    public static int add(int a, int b) {
        int sum = a + b;
        return sum; // 返回计算结果
    }

    public static void main(String[] args) {
        // 调用方法
        int result = add(10, 20);
        System.out.println("和为:" + result); // 输出:30
    }
}

3. 方法的核心概念

  • 修饰符 :目前记住public static(静态方法,方便调用)
  • 返回值类型 :方法执行后返回的数据类型,无返回值用void
  • 参数
    • 形参:定义方法时的参数(如add(int a, int b)中的 a、b)
    • 实参:调用方法时传入的具体值(如add(10, 20)中的 10、20)
  • 方法体:实现功能的代码块

4. 方法重载(同一类中同名不同参)

4.1 定义

同一类中,方法名相同但参数列表不同(参数个数 / 类型不同),与返回值无关。

4.2 示例:比较不同类型的两个数是否相等
复制代码
public class MethodDemo02 {
    public static void main(String[] args) {
        System.out.println(compare(10, 20)); // 调用int类型方法
        System.out.println(compare((short)10, (short)10)); // 调用short类型方法
    }

    // 比较int类型
    public static boolean compare(int a, int b) {
        System.out.println("int类型比较");
        return a == b;
    }

    // 比较short类型(重载)
    public static boolean compare(short a, short b) {
        System.out.println("short类型比较");
        return a == b;
    }

    // 比较long类型(重载)
    public static boolean compare(long a, long b) {
        System.out.println("long类型比较");
        return a == b;
    }
}

5. 方法参数传递(关键知识点)

5.1 基本类型参数(值传递,形参改变不影响实参)
复制代码
public class MethodDemo03 {
    public static void main(String[] args) {
        int num = 100;
        change(num);
        System.out.println("调用后:" + num); // 输出:100(实参未变)
    }

    public static void change(int num) {
        num = 200; // 形参改变,实参不受影响
    }
}
5.2 引用类型参数(地址传递,形参改变影响实参)
复制代码
public class MethodDemo04 {
    public static void main(String[] args) {
        int[] arr = {10, 20, 30};
        changeArr(arr);
        System.out.println("调用后:" + arr[1]); // 输出:200(实参被修改)
    }

    public static void changeArr(int[] arr) {
        arr[1] = 200; // 形参修改数组元素,实参数组同步变化
    }
}

6. 方法实战练习

练习 1:定义方法遍历数组
复制代码
public class MethodDemo05 {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33};
        printArray(arr); // 调用遍历方法
    }

    // 定义遍历数组的方法
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
练习 2:定义方法获取数组最大值
复制代码
public class MethodDemo06 {
    public static void main(String[] args) {
        int[] arr = {5, 15, 2000};
        int max = getMax(arr);
        System.out.println("最大值:" + max); // 输出:2000
    }

    // 定义获取最大值的方法
    public static int getMax(int[] arr) {
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}

三、面向对象:Java 的核心编程思想

1. 面向对象核心概念

  • :属性(事物的描述信息,如姓名、年龄)和行为(事物能做的事,如吃饭、学习)的集合(抽象概念)
  • 对象:类的具体实例(如 "张三" 是 "学生类" 的对象)
  • 三大特征:封装、继承、多态

2. 类与对象的定义与使用

2.1 定义类(以手机类为例)
复制代码
// 手机类(属性+行为)
public class Phone {
    // 成员变量(属性,私有化,通过get/set访问)
    private String brand; // 品牌
    private int price;    // 价格
    private String color; // 颜色

    // 空参构造(必须手动写,方便创建对象)
    public Phone() {}

    // 全参构造(快速给属性赋值)
    public Phone(String brand, int price, String color) {
        this.brand = brand; // this代表当前对象,解决局部变量与成员变量重名
        this.price = price;
        this.color = color;
    }

    // get方法(获取属性值)
    public String getBrand() {
        return brand;
    }

    // set方法(设置属性值)
    public void setBrand(String brand) {
        this.brand = brand;
    }

    public int getPrice() {
        return price;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    // 成员方法(行为)
    public void call(String name) {
        System.out.println("给" + name + "打电话");
    }

    public void sendMessage(String name) {
        System.out.println("给" + name + "发短信");
    }
}
2.2 创建并使用对象
复制代码
// 测试类
public class PhoneTest {
    public static void main(String[] args) {
        // 方式1:空参构造+set方法赋值
        Phone p1 = new Phone();
        p1.setBrand("华为P40");
        p1.setPrice(3000);
        p1.setColor("土豪金");
        System.out.println(p1.getBrand() + " " + p1.getPrice() + " " + p1.getColor());
        p1.call("张三"); // 调用方法

        // 方式2:全参构造直接赋值
        Phone p2 = new Phone("iPhone12", 5999, "玫瑰红");
        System.out.println(p2.getBrand() + " " + p2.getPrice() + " " + p2.getColor());
        p2.sendMessage("李四");
    }
}

3. 面向对象三大特征

3.1 封装(隐藏细节,对外提供访问方式)
  • 核心 :用private修饰成员变量,通过getXxx()setXxx()方法访问
  • 好处:保护数据安全,避免非法赋值(如给年龄赋值 - 100)
3.2 继承(子类复用父类属性和行为)
3.2.1 定义格式(extends关键字)
复制代码
// 父类(人类)
public class Person {
    private String name;
    private int age;

    // 空参+全参构造、get/set方法省略...

    public void eat() {
        System.out.println("吃饭");
    }
}

// 子类(学生类)继承父类
public class Student extends Person {
    // 子类独有属性
    private String studentId;

    // 子类独有方法
    public void study() {
        System.out.println("学习Java");
    }
}

// 测试类
public class ExtendDemo {
    public static void main(String[] args) {
        Student s = new Student();
        s.setName("王五"); // 继承父类的set方法
        s.eat(); // 继承父类的eat方法
        s.study(); // 子类独有方法
    }
}
3.2.2 方法重写(子类改写父类方法)

当子类需要修改父类方法的实现时使用,用@Override注解标识:

复制代码
public class NewPhone extends Phone {
    // 重写父类的call方法
    @Override
    public void call(String name) {
        System.out.println("开启视频通话,给" + name + "打电话");
    }
}

// 测试
public class OverrideDemo {
    public static void main(String[] args) {
        NewPhone np = new NewPhone();
        np.call("张三"); // 输出:开启视频通话,给张三打电话(重写后的逻辑)
    }
}
3.3 多态(同一对象不同时刻的不同状态)
3.3.1 实现条件
  1. 有继承关系
  2. 有方法重写
  3. 父类引用指向子类对象(父类名 对象名 = new 子类名()
3.3.2 示例(猫狗案例)
复制代码
// 父类(动物类)
public abstract class Animal {
    public abstract void eat(); // 抽象方法,子类必须重写
}

// 子类(猫类)
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

// 子类(狗类)
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

// 测试多态
public class PolymorphismDemo {
    public static void main(String[] args) {
        // 父类引用指向子类对象(多态)
        Animal a1 = new Cat();
        a1.eat(); // 输出:猫吃鱼(执行子类逻辑)

        Animal a2 = new Dog();
        a2.eat(); // 输出:狗吃骨头(执行子类逻辑)
    }
}

4. 抽象类与接口(进阶重点)

4.1 抽象类(不能实例化,含抽象方法)
复制代码
// 抽象类(用abstract修饰)
public abstract class Teacher {
    // 抽象方法(无方法体,子类必须重写)
    public abstract void teach();

    // 普通方法(可含方法体)
    public void sleep() {
        System.out.println("睡觉");
    }
}

// 子类(基础班老师)
public class BasicTeacher extends Teacher {
    @Override
    public void teach() {
        System.out.println("教JavaSE");
    }
}
4.2 接口(扩展功能,纯抽象方法)
复制代码
// 接口(用interface修饰)
public interface Jumpping {
    void jump(); // 抽象方法,默认public abstract
}

// 类实现接口(用implements)
public class Cat implements Jumpping {
    @Override
    public void jump() {
        System.out.println("猫跳火圈");
    }
}

5. 综合案例:运动员与教练

复制代码
// 父类(人类)
public class Person {
    private String name;
    private int age;

    // 空参+全参构造、get/set方法省略...

    public void eat() {
        System.out.println("吃饭");
    }
}

// 接口(英语能力)
public interface English {
    void speakEnglish();
}

// 教练类(继承Person,实现English)
public class Coach extends Person implements English {
    @Override
    public void speakEnglish() {
        System.out.println("教练说英语");
    }

    public void teach() {
        System.out.println("教练教课");
    }
}

// 运动员类(继承Person)
public class Player extends Person {
    public void train() {
        System.out.println("运动员训练");
    }
}

// 测试类
public class SportDemo {
    public static void main(String[] args) {
        Coach c = new Coach();
        c.setName("张教练");
        c.eat(); // 继承父类
        c.teach(); // 独有方法
        c.speakEnglish(); // 实现接口

        Player p = new Player();
        p.setName("李运动员");
        p.train();
    }
}

四、新手避坑指南

  1. 数组索引越界 :遍历数组时,循环条件用i < arr.length,而非i <= arr.length
  2. 方法调用错误:调用带参数的方法时,实参类型、个数必须与形参一致
  3. 继承中构造方法 :子类构造方法默认调用父类空参构造,若父类无空参构造,需用super(参数)调用父类带参构造
  4. 多态访问成员:成员变量 "编译看父类,运行看父类",成员方法 "编译看父类,运行看子类"
  5. 抽象类与接口:抽象类可含普通方法,接口(JDK8 前)只能含抽象方法,子类必须重写所有抽象方法

总结

数组、方法、面向对象是 Java 进阶的 "三大基石":数组解决批量数据存储,方法提高代码复用,面向对象让代码更易维护和扩展。建议新手先通过案例熟练数组和方法的使用,再深入理解面向对象的三大特征,结合实战案例(如猫狗、运动员教练)巩固知识点。

后续会更新集合、IO 流、异常处理等进阶内容,关注我,一起从 Java 新手成长为开发大佬~ 若操作中遇到问题,欢迎在评论区留言

相关推荐
weixin_409383122 小时前
简单四方向a*学习记录10 重写前面的所有逻辑
学习
是梦终空2 小时前
计算机毕业设计252—基于Java+Springboot+vue3+协同过滤推荐算法的农产品销售系统(源代码+数据库+2万字论文)
java·spring boot·vue·毕业设计·源代码·协同过滤算法·农产品销售系统
2301_764441332 小时前
使用python构建的应急物资代储博弈模型
开发语言·python·算法
丿BAIKAL巛2 小时前
Java前后端传参与接收全解析
java·开发语言
cc蒲公英3 小时前
javascript有哪些内置对象
java·前端·javascript
guslegend3 小时前
Spring AOP高级应用与源码剖析
java
Rover.x3 小时前
head table is mandatory
java·apache
yanghuashuiyue3 小时前
Java过滤器-拦截器-AOP-Controller
java·开发语言
shoubepatien3 小时前
JAVA —— 03
java·jvm