【Java零基础·第6章】面向对象(二):构造器、封装、对象数组

一、类与对象的复习

在Java世界里,类就像一个模板,定义了一类事物的共同特征和行为;而对象则是这个模板的具体实例。比如"汽车"是一个类,而你家的那辆红色小轿车就是一个对象。

包的作用

包(Package)就像文件夹,主要作用是:

  • 避免类名冲突
  • 便于管理大量类
  • 控制访问权限

定义包的语法很简单:

package com.example.myapp; // 通常是公司域名倒写+项目名

成员变量的分类

特性静态变量(类变量)实例变量(对象变量)
修饰符有static无static
存储位置方法区堆内存
初始化时机类加载时创建对象时(new)
访问方式类名.变量名对象.变量名

示例:

public class Student {
    // 静态变量(所有学生共享的学校名称)
    public static String schoolName = "阳光中学";
    
    // 实例变量(每个学生独有的属性)
    public String name; // 姓名
    public int age;     // 年龄
}

使用方式:

// 访问静态变量
System.out.println(Student.schoolName);

// 访问实例变量
Student student = new Student();
student.name = "张三";
System.out.println(student.name);

成员方法的分类

特性静态方法实例方法
修饰符有static无static
能否用this不能
访问成员只能访问静态成员可访问所有成员
调用方式类名.方法名()对象.方法名()

示例:

public class Calculator {
    // 静态方法(工具方法)
    public static int add(int a, int b) {
        return a + b;
    }
    
    // 实例方法(需要对象状态的方法)
    private int result;
    public void accumulate(int num) {
        this.result += num; // 使用this访问实例变量
    }
}

二、构造器:对象的"出生证明"

构造器是一种特殊的方法,专门用于创建对象时初始化对象。

构造器的特点

  1. 名称必须与类名完全相同(包括大小写)
  2. 没有返回值类型(连void都不能写)
  3. 当你没写任何构造器时,编译器会自动生成一个无参构造器
  4. 一旦手动编写了构造器,默认的无参构造器就会消失

构造器示例

package com.example.oop;

public class Book {
    private String title;  // 书名
    private String author; // 作者
    private double price;  // 价格
    
    // 无参构造器
    public Book() {
        // 可以在这里设置默认值
        this.title = "未知书名";
        this.author = "未知作者";
    }
    
    // 有参构造器
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }
    
    // 全参构造器
    public Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }
    
    // getter和setter方法
    public String getTitle() {
        return title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
    
    // 其他getter和setter省略...
    
    public String getInfo() {
        return "《" + title + "》 作者:" + author + " 价格:" + price + "元";
    }
}

使用构造器创建对象:

public class TestBook {
    public static void main(String[] args) {
        // 使用无参构造器
        Book book1 = new Book();
        System.out.println(book1.getInfo());
        
        // 使用有参构造器
        Book book2 = new Book("Java编程思想", "Bruce Eckel");
        book2.setPrice(108.0);
        System.out.println(book2.getInfo());
        
        // 使用全参构造器
        Book book3 = new Book("深入理解Java虚拟机", "周志明", 89.0);
        System.out.println(book3.getInfo());
    }
}

三、封装:对象的"隐私保护"

封装是面向对象的三大特征之一,就像我们用快递盒包装物品一样,隐藏内部细节,只暴露必要的接口。

为什么需要封装?

  1. 保护数据安全,防止不合理的修改
  2. 隐藏实现细节,便于维护
  3. 控制访问权限,明确边界

四种权限修饰符

Java提供了四种权限修饰符,控制类和成员的可见范围:

修饰符本类本包其他类其他包的子类其他包的非子类
private×××
缺省(默认)××
protected×
public

封装的实现方式

  1. 将属性私有化(使用private修饰)
  2. 提供公共的getter和setter方法

示例:

package com.example.encapsulation;

public class BankAccount {
    // 属性私有化
    private String accountNumber; // 账号
    private double balance;       // 余额
    
    // 构造器
    public BankAccount(String accountNumber) {
        this.accountNumber = accountNumber;
        this.balance = 0.0; // 新账户初始余额为0
    }
    
    // 存款方法(带业务逻辑的setter)
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("存款成功!存入:" + amount + "元,当前余额:" + balance + "元");
        } else {
            System.out.println("存款金额必须大于0!");
        }
    }
    
    // 取款方法
    public void withdraw(double amount) {
        if (amount <= 0) {
            System.out.println("取款金额必须大于0!");
            return;
        }
        
        if (amount > balance) {
            System.out.println("余额不足!当前余额:" + balance + "元");
            return;
        }
        
        balance -= amount;
        System.out.println("取款成功!取出:" + amount + "元,当前余额:" + balance + "元");
    }
    
    // getter方法(只允许获取,不允许直接修改)
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public double getBalance() {
        return balance;
    }
}

使用示例:

public class TestBankAccount {
    public static void main(String[] args) {
        BankAccount account = new BankAccount("6222021234567890123");
        
        // 尝试直接访问私有属性(编译错误)
        // System.out.println(account.balance);
        
        // 通过公共方法操作
        account.deposit(1000);
        account.withdraw(300);
        account.withdraw(800); // 余额不足的情况
        account.deposit(-500); // 存入负数的情况
        
        System.out.println("账号:" + account.getAccountNumber());
        System.out.println("最终余额:" + account.getBalance() + "元");
    }
}

四、标准JavaBean:规范的Java类

JavaBean是一种遵循特定规范的Java类,就像生产标准零件一样,让类的使用更加统一和方便。

JavaBean规范

  1. 属性私有化(private)
  2. 提供公共的无参构造器
  3. 为每个属性提供公共的getter和setter方法
  4. 重写toString()方法(方便打印)
  5. 重写equals()和hashCode()方法(方便比较)

示例:

package com.example.bean;

import java.util.Objects;

public class User {
    // 属性私有化
    private Long id;
    private String username;
    private String email;
    private int age;
    private boolean vip;
    
    // 无参构造器
    public User() {
    }
    
    // 有参构造器(可选)
    public User(String username, String email) {
        this.username = username;
        this.email = email;
    }
    
    // 全参构造器(可选)
    public User(Long id, String username, String email, int age, boolean vip) {
        this.id = id;
        this.username = username;
        this.email = email;
        this.age = age;
        this.vip = vip;
    }
    
    // getter和setter方法
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    // 其他getter和setter省略...
    
    // 注意:boolean类型的getter通常以is开头
    public boolean isVip() {
        return vip;
    }
    
    public void setVip(boolean vip) {
        this.vip = vip;
    }
    
    // 重写toString()方法
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                ", vip=" + vip +
                '}';
    }
    
    // 重写equals()方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age && 
               vip == user.vip && 
               Objects.equals(id, user.id) && 
               Objects.equals(username, user.username) && 
               Objects.equals(email, user.email);
    }
    
    // 重写hashCode()方法
    @Override
    public int hashCode() {
        return Objects.hash(id, username, email, age, vip);
    }
}

使用示例:

public class TestUser {
    public static void main(String[] args) {
        User user1 = new User();
        user1.setId(1L);
        user1.setUsername("张三");
        user1.setEmail("zhangsan@example.com");
        user1.setAge(25);
        user1.setVip(true);
        
        User user2 = new User(1L, "张三", "zhangsan@example.com", 25, true);
        User user3 = new User(2L, "李四", "lisi@example.com", 30, false);
        
        System.out.println(user1); // 自动调用toString()
        System.out.println("user1和user2是否相等:" + user1.equals(user2));
        System.out.println("user1和user3是否相等:" + user1.equals(user3));
    }
}

五、对象数组:批量管理对象

对象数组就是存储对象引用的数组,就像一个存放多个对象的容器。

对象数组的创建和使用

package com.example.objectarray;

public class Product {
    private String id;
    private String name;
    private double price;
    
    public Product() {
    }
    
    public Product(String id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
    
    // getter和setter方法省略...
    
    @Override
    public String toString() {
        return "商品ID:" + id + ",名称:" + name + ",价格:" + price + "元";
    }
    
    public double getPrice() {
        return price;
    }
}

使用对象数组:

public class TestProductArray {
    public static void main(String[] args) {
        // 1. 静态初始化
        Product[] products1 = {
            new Product("p001", "笔记本电脑", 5999.0),
            new Product("p002", "智能手机", 3999.0),
            new Product("p003", "平板电脑", 2999.0)
        };
        
        // 2. 动态初始化
        Product[] products2 = new Product[3];
        products2[0] = new Product("p004", "无线鼠标", 99.0);
        products2[1] = new Product("p005", "机械键盘", 299.0);
        products2[2] = new Product("p006", "蓝牙耳机", 499.0);
        
        // 3. 遍历对象数组
        System.out.println("所有商品:");
        for (int i = 0; i < products1.length; i++) {
            System.out.println(products1[i]);
        }
        
        for (Product p : products2) { // 增强for循环
            System.out.println(p);
        }
        
        // 4. 对象数组排序(按价格从低到高)
        System.out.println("\n按价格排序后:");
        Product[] allProducts = new Product[products1.length + products2.length];
        // 合并数组
        System.arraycopy(products1, 0, allProducts, 0, products1.length);
        System.arraycopy(products2, 0, allProducts, products1.length, products2.length);
        
        // 冒泡排序
        for (int i = 0; i < allProducts.length - 1; i++) {
            for (int j = 0; j < allProducts.length - 1 - i; j++) {
                if (allProducts[j].getPrice() > allProducts[j + 1].getPrice()) {
                    // 交换对象引用
                    Product temp = allProducts[j];
                    allProducts[j] = allProducts[j + 1];
                    allProducts[j + 1] = temp;
                }
            }
        }
        
        // 打印排序结果
        for (Product p : allProducts) {
            System.out.println(p);
        }
    }
}

总结

本文介绍了Java面向对象编程的几个重要概念:

  1. 构造器:用于初始化对象,是创建对象的重要途径
  2. 封装:通过权限修饰符和getter/setter方法保护数据
  3. JavaBean:规范的Java类,便于统一管理和使用
  4. 对象数组:用于批量管理对象,提高代码效率

这些概念是Java面向对象编程的基础,掌握它们有助于编写更规范、更安全、更易维护的代码。在实际开发中,我们会大量使用这些概念,特别是JavaBean和对象数组,它们在处理数据和业务逻辑时非常有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码力引擎

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值