Java面向对象的基本特性

引言

面向对象编程(Object-Oriented Programming,简称OOP)是当今最流行的编程范式之一,而Java作为一种纯粹的面向对象编程语言,其设计理念和核心特性都围绕着面向对象的思想。Java面向对象编程的三大基本特性——封装、继承和多态,构成了Java语言的基石,理解这些特性对于掌握Java编程至关重要。本文将深入探讨这三大特性的概念、实现方式、应用场景以及最佳实践,帮助读者全面理解Java面向对象编程的精髓。

封装(Encapsulation)

封装的概念

封装是面向对象编程的基本特性之一,它指的是将数据(属性)和行为(方法)包装在一个单元中,并对外部隐藏实现细节,只暴露必要的接口。封装的核心思想是"信息隐藏"(Information Hiding),即对象应该隐藏其内部状态和实现细节,只通过公共接口与外界交互。

封装的主要目标包括:

  1. 保护数据完整性:通过限制直接访问对象的属性,确保数据只能通过受控方式修改,从而维护数据的有效性和一致性。

  2. 降低耦合度:通过隐藏实现细节,减少系统各部分之间的依赖,使得系统更加模块化和可维护。

  3. 提高安全性:防止外部代码直接操作对象的内部状态,避免不当操作导致的错误。

  4. 增强灵活性:允许开发者修改内部实现而不影响外部代码,只要保持公共接口不变。

封装的实现方式

在Java中,封装主要通过以下机制实现:

1. 访问修饰符

Java提供了四种访问修饰符,用于控制类、属性和方法的可见性:

  • private:最严格的访问级别,只能在声明它的类内部访问。

  • 默认(无修饰符):包级私有,可以在同一个包内访问。

  • protected:可以在同一个包内以及不同包的子类中访问。

  • public:最宽松的访问级别,可以在任何地方访问。

public class Person {
    // 私有属性,外部无法直接访问
    private String name;
    private int age;
    
    // 包级私有属性,同包内可访问
    String address;
    
    // 受保护属性,子类可访问
    protected String phoneNumber;
    
    // 公共属性,任何地方可访问
    public String email;
    
    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 公共方法,提供对私有属性的访问
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        // 可以在setter中添加验证逻辑
        if (age >= 0 && age <= 150) {
            this.age = age;
        } else {
            throw new IllegalArgumentException("Age must be between 0 and 150");
        }
    }
}
2. getter和setter方法

为了控制对私有属性的访问,通常提供公共的getter和setter方法:

  • getter方法:用于获取属性值,通常命名为getXxx()

  • setter方法:用于设置属性值,通常命名为setXxx(),可以在其中添加验证逻辑。

public class BankAccount {
    private String accountNumber;
    private double balance;
    
    public BankAccount(String accountNumber, double initialBalance) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }
    
    // getter方法
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public double getBalance() {
        return balance;
    }
    
    // 没有setter方法for accountNumber,使其只读
    
    // 不直接提供setBalance方法,而是提供业务方法
    public void deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Deposit amount must be positive");
        }
        balance += amount;
    }
    
    public void withdraw(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Withdrawal amount must be positive");
        }
        if (amount > balance) {
            throw new IllegalArgumentException("Insufficient funds");
        }
        balance -= amount;
    }
}
3. 不可变类

封装的一种极端形式是创建不可变类(Immutable Class),其对象一旦创建就不能修改。不可变类通常具有以下特点:

  • 所有属性都是私有的且final的。

  • 不提供修改状态的方法。

  • 确保所有可变组件不会被修改。

public final class ImmutablePerson {
    private final String name;
    private final int age;
    private final List<String> hobbies;  // 可变组件
    
    public ImmutablePerson(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        // 创建防御性副本,避免外部引用修改内部状态
        this.hobbies = new ArrayList<>(hobbies);
    }
    
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    public List<String> getHobbies() {
        // 返回防御性副本,避免通过getter修改内部状态
        return new ArrayList<>(hobbies);
    }
    
    // 不提供setter方法
    
    // 如需修改,返回新对象
    public ImmutablePerson withName(String newName) {
        return new ImmutablePerson(newName, this.age, this.hobbies);
    }
    
    public ImmutablePerson withAge(int newAge) {
        return new ImmutablePerson(this.name, newAge, this.hobbies);
    }
    
    public ImmutablePerson withHobby(String newHobby) {
        List<String> newHobbies = new ArrayList<>(this.hobbies);
        newHobbies.add(newHobby);
        return new ImmutablePerson(this.name, this.age, newHobbies);
    }
}

封装的实际应用

1. 数据验证和约束

封装允许在setter方法中添加验证逻辑,确保对象状态的有效性:

public class Employee {
    private String id;
    private String name;
    private double salary;
    
    // 构造方法
    public Employee(String id, String name, double salary) {
        setId(id);
        setName(name);
        setSalary(salary);
    }
    
    // getter和setter方法
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        if (id == null || id.trim().isEmpty()) {
            throw new IllegalArgumentException("ID cannot be empty");
        }
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("Name cannot be empty");
        }
        this.name = name;
    }
    
    public double getSalary() {
        return salary;
    }
    
    public void setSalary(double salary) {
        if (salary < 0) {
            throw new IllegalArgumentException("Salary cannot be negative");
        }
        this.salary = salary;
    }
    
    // 业务方法
    public void raiseSalary(double percentage) {
        if (percentage <= 0) {
            throw new IllegalArgumentException("Percentage must be positive");
        }
        salary += salary * percentage / 100;
    }
}
2. 实现细节隐藏

封装允许隐藏实现细节,只暴露必要的接口:

public class CacheManager {
    // 隐藏缓存实现细节
    private Map<String, Object> cache;
    private int maxSize;
    private CacheEvictionPolicy evictionPolicy;
    
    public CacheManager(int maxSize, CacheEvictionPolicy evictionPolicy) {
        this.maxSize = maxSize;
        this.evictionPolicy = evictionPolicy;
        this.cache = new LinkedHashMap<>(16, 0.75f, true);  // 使用访问顺序
    }
    
    // 公共接口
    public void put(String key, Object value) {
        if (cache.size() >= maxSize) {
            evictCache();
        }
        cache.put(key, value);
    }
    
    public Object get(String key) {
        return cache.get(key);
    }
    
    public void remove(String key) {
        cache.remove(key);
    }
    
    public int size() {
        return cache.size();
    }
    
    // 私有实现细节
    private void evictCache() {
        switch (evictionPolicy) {
            case LRU:
                evictLRU();
                break;
            case FIFO:
                evictFIFO();
                break;
            case RANDOM:
                evictRandom();
                break;
        }
    }
    
    private void evictLRU() {
        // LRU实现
        String lruKey = cache.keySet().iterator().next();
        cache.remove(lruKey);
    }
    
    private void evictFIFO() {
        // FIFO实现
        // ...
    }
    
    private void evictRandom() {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值