java的三大特征

1. 封装

概念

面向对象的封装把对象的属性和方法组合在一起,统一提供对外的访问权限,封装就是将对象的使用者和设计者分开,设计者可以设计出外部可以操作 的内容和只能内部操作的内容。使用者只能使用设计好的内容,却看不见设计者是如何实现的。就像计算机是由 cpu、内存和各种外设组成的,对于计算机的用户来说,只能使用这些部件,但是却看不见这些部件的内部结构。

简单来说封装就像是把东西打包在一个盒子里,只留下几个特定的 "开口" 让外部使用。在 Java 中,我们通过将类的属性设为private(私有),并提供public(公共)的方法来访问和修改这些属性。这样可以:

  • 保护数据:防止外部直接修改属性,避免非法数据。

  • 简化使用:外部只需调用方法,无需关心内部实现。

为什么需要封装?

想象一个银行账户类,如果直接暴露balance(余额)属性,任何人都可以随意修改,这会导致安全问题。通过封装,我们可以控制如何修改余额(例如,取款时检查余额是否充足)。

java 复制代码
public class BankAccount {
    private double balance; // 私有属性,外部无法直接访问

    // 构造方法:初始化账户余额
    public BankAccount(double initialBalance) {
        if (initialBalance > 0) {
            this.balance = initialBalance;
        } else {
            System.out.println("初始余额必须大于0");
            this.balance = 0;
        }
    }

    // 存款方法
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("存款成功,当前余额: " + balance);
        } else {
            System.out.println("存款金额必须大于0");
        }
    }

    // 取款方法
    public boolean withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("取款成功,当前余额: " + balance);
            return true;
        } else {
            System.out.println("取款失败:余额不足或金额无效");
            return false;
        }
    }

    // 获取余额(只读访问)
    public double getBalance() {
        return balance;
    }
}

在该代码中我们无法直接对balance(余额)属性进行修改,而是通过下列方法去对balance(余额)属性进行修改

java 复制代码
BankAccount account = new BankAccount(1000.0);
account.deposit(500.0);    // 存款500,余额变为1500
account.withdraw(200.0);   // 取款200,余额变为1300
account.withdraw(2000.0);  // 取款失败:余额不足
System.out.println("当前余额: " + account.getBalance()); // 输出1300

关键点:

  • private 属性balance只能通过类内部的方法访问。
  • public 方法deposit()withdraw()getBalance()是外部与内部数据交互的唯一途径。

修饰符的权限表

在 Java 中,访问修饰符用于控制类、方法、变量的访问权限。以下是 Java 中四种访问修饰符的权限表:

修饰符 同一个类 同一个包 不同包子类 不同包非子类
public
protected
default
private

说明:

  • public:所有类都可以访问。
  • protected:同一个包内的类和不同包中的子类可以访问。
  • default(默认,无修饰符):只有同一个包内的类可以访问。
  • private:只有同一个类内部可以访问。

2. 继承

概念 :

继承就像是子女继承父母的特征一样,一个类(子类)可以继承另一个类(父类)的属性和方法(一个子类只能直接继承一个父类)。通过继承,子类可以:

  • 复用代码:避免重复编写父类已有的功能。
  • 扩展功能:在父类基础上添加新的属性或方法。
  • 建立层次关系:形成 "is-a" 关系(例如,狗是一种动物)。

为什么需要继承?

假设你正在开发一个游戏,有多种角色(战士、法师、弓箭手),他们都有一些共同的属性(生命值、名字)和方法(移动、攻击)。通过创建一个父类Character,可以避免在每个子类中重复编写这些共性代码。

实例:

java 复制代码
// 父类:角色
class Character {
    protected String name;  // 受保护的属性,子类可以直接访问
    protected int health;   // 受保护的属性

    public Character(String name, int health) {
        this.name = name;
        this.health = health;
    }

    public void move() {
        System.out.println(name + "正在移动...");
    }

    public void attack(Character target) {
        System.out.println(name + "攻击了" + target.name);
        target.health -= 10; // 每次攻击减少10点生命值
        System.out.println(target.name + "剩余生命值: " + target.health);
    }

    public String getName() {
        return name;
    }

    public int getHealth() {
        return health;
    }
}

// 子类:战士
class Warrior extends Character {
    private int strength;  // 战士特有的属性:力量

    public Warrior(String name, int strength) {
        super(name, 100);  // 调用父类的构造方法,初始生命值为100
        this.strength = strength;
    }

    // 战士特有的方法:挥舞宝剑
    public void swingSword() {
        System.out.println(name + "挥舞宝剑,造成" + (strength * 2) + "点伤害!");
    }

    // 重写父类的攻击方法
    @Override
    public void attack(Character target) {
        System.out.println(name + "用宝剑砍向" + target.name);
        target.health -= strength * 2;  // 战士的伤害是力量的2倍
        System.out.println(target.name + "剩余生命值: " + target.health);
    }
}

// 子类:法师
class Mage extends Character {
    private int mana;  // 法师特有的属性:魔法值

    public Mage(String name, int mana) {
        super(name, 80);  // 调用父类的构造方法,初始生命值为80
        this.mana = mana;
    }

    // 法师特有的方法:施放魔法
    public void castSpell() {
        if (mana >= 20) {
            System.out.println(name + "施放火球术!");
            mana -= 20;
        } else {
            System.out.println(name + "魔法值不足!");
        }
    }
}

如何使用:

java 复制代码
Warrior warrior = new Warrior("张三", 15);
Mage mage = new Mage("李四", 100);

warrior.move();       // 输出:张三正在移动...
warrior.swingSword(); // 输出:张三挥舞宝剑,造成30点伤害!
warrior.attack(mage); // 输出:张三用宝剑砍向李四,李四剩余生命值: 50

mage.castSpell();     // 输出:李四射放火球术!
mage.attack(warrior); // 输出:李四攻击了张三,张三剩余生命值: 90

关键点:

  • extends 关键字Warrior extends Character表示Warrior继承自Character
  • super 关键字:在子类构造方法中调用父类的构造方法。
  • 方法重写 (Override):子类可以修改父类方法的实现(如Warriorattack()方法)。
  • protected 访问修饰符 :父类的protected属性可以被子类直接访问。

3. 多态

概念 :

多态意味着 "多种形态",即同一个方法调用可以表现出不同的行为。多态通过两个机制实现:

  1. 方法重写(Override):子类重写父类的方法。
  2. 父类引用指向子类对象:可以通过父类类型的变量调用子类的重写方法。

为什么需要多态?

假设你正在开发一个图形绘制程序,有圆形、矩形、三角形等多种图形。通过多态,你可以用一个通用的 "绘制" 方法处理所有图形,而不需要为每个图形单独编写处理代码。

实例:

java 复制代码
// 父类:图形
abstract class Shape {
    // 抽象方法:计算面积(没有方法体,子类必须实现)
    public abstract double calculateArea();

    // 具体方法:显示图形信息
    public void displayInfo() {
        System.out.println("这个图形的面积是: " + calculateArea());
    }
}

// 子类:圆形
class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

// 子类:矩形
class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double calculateArea() {
        return width * height;
    }
}

如何使用:

java 复制代码
// 创建不同的图形对象
Shape circle = new Circle(5.0);
Shape rectangle = new Rectangle(4.0, 6.0);

// 调用相同的方法,但表现不同的行为
circle.displayInfo();   // 输出:这个图形的面积是: 78.53981633974483
rectangle.displayInfo(); // 输出:这个图形的面积是: 24.0

// 可以将多个图形放入数组中统一处理
Shape[] shapes = {circle, rectangle};
for (Shape shape : shapes) {
    System.out.println("面积: " + shape.calculateArea());
}

关键点:

  • 抽象类abstract class):不能实例化,用于定义通用接口(如Shape)。
  • 抽象方法abstract method):没有方法体,子类必须实现。
  • 父类引用Shape circle = new Circle(5.0),通过父类类型调用子类方法。
  • 动态绑定:运行时根据实际对象类型决定调用哪个方法(而不是编译时的引用类型)。

三大特征的联系

  1. 封装为继承和多态提供基础:通过封装数据和方法,子类可以安全地继承和扩展父类的功能。
  2. 继承是多态的前提:只有通过继承建立类的层次关系,才能实现父类引用指向子类对象。
  3. 多态是封装和继承的高级应用:通过统一接口处理不同对象,提高代码的灵活性和可维护性。
相关推荐
小屁孩大帅-杨一凡1 小时前
如何解决ThreadLocal内存泄漏问题?
java·开发语言·jvm·算法
学习3人组1 小时前
在 IntelliJ IDEA 系列中phpstorm2025设置中文界面
java·ide·intellij-idea
cainiao0806053 小时前
Java 大视界:基于 Java 的大数据可视化在智慧城市能源消耗动态监测与优化决策中的应用(2025 实战全景)
java
长风破浪会有时呀4 小时前
记一次接口优化历程 CountDownLatch
java
云朵大王4 小时前
SQL 视图与事务知识点详解及练习题
java·大数据·数据库
我爱Jack4 小时前
深入解析 LinkedList
java·开发语言
27669582926 小时前
tiktok 弹幕 逆向分析
java·python·tiktok·tiktok弹幕·tiktok弹幕逆向分析·a-bogus·x-gnarly
用户40315986396636 小时前
多窗口事件分发系统
java·算法
用户40315986396636 小时前
ARP 缓存与报文转发模拟
java·算法
小林ixn6 小时前
大一新手小白跟黑马学习的第一个图形化项目:拼图小游戏(java)
java