Java 基本语法详解(四)

AI的出现,是否能替代IT从业者? 10w+人浏览 1.6k人参与

Java 基本语法详解(四)

十、面向对象核心特性(封装、继承、多态)

面向对象有三大核心特性:封装、继承、多态,它们是 Java 代码设计的核心思想,能提升代码的安全性、复用性和灵活性。

1. 封装(隐藏细节,暴露接口)

封装指将类的成员变量(属性)隐藏在类内部,通过私有访问修饰符(private) 限制外部直接访问,再提供公共的 “getter/setter 方法” 供外部间接操作,实现对属性的控制(如合法性校验),避免数据被随意修改。

(1)封装的实现步骤
  1. 用private修饰成员变量,禁止外部直接访问;

  2. 提供public的getXxx()方法(获取属性值)和setXxx()方法(设置属性值);

  3. 在setXxx()方法中添加逻辑校验(如年龄不能为负数)。

示例:封装 Student 类
public class Student {
    // 1. 用private修饰成员变量(隐藏细节)
    private String name;   // 姓名
    private int age;       // 年龄(需校验:不能为负数)
    private String studentId; // 学号

    // 2. 无参数构造方法
    public Student() {}

    // 3. 有参数构造方法(调用setter方法,复用校验逻辑)
    public Student(String name, int age, String studentId) {
        this.setName(name);
        this.setAge(age);
        this.setStudentId(studentId);
    }

    // 4. getter方法(获取name值)
    public String getName() {
        return name;
    }

    // 5. setter方法(设置name值,可添加校验)
    public void setName(String name) {
        // 校验:姓名不能为null或空字符串
        if (name == null || "".equals(name)) {
            System.out.println("姓名不能为空!");
            this.name = "未知姓名"; // 赋予默认值
        } else {
            this.name = name;
        }
    }

    // getter方法(获取age值)
    public int getAge() {
        return age;
    }

    // setter方法(设置age值,校验年龄合法性)
    public void setAge(int age) {
        if (age < 0 || age > 150) { // 年龄范围:0-150
            System.out.println("年龄不合法!赋予默认值18");
            this.age = 18;
        } else {
            this.age = age;
        }
    }

    // getter/setter方法(studentId)
    public String getStudentId() {
        return studentId;
    }

    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }

    // 成员方法:自我介绍
    public String introduce() {
        return "大家好!我是" + getName() + ",今年" + getAge() + "岁,学号是" + getStudentId();
    }
}
示例:使用封装后的 Student 类
public class EncapsulationDemo {
    public static void main(String[] args) {
        // 1. 通过无参数构造+setter方法创建对象
        Student student1 = new Student();
        student1.setName(""); // 触发姓名校验:姓名不能为空!
        student1.setAge(-5);  // 触发年龄校验:年龄不合法!赋予默认值18
        student1.setStudentId("2023001");
        System.out.println(student1.introduce()); // 输出:大家好!我是未知姓名,今年18岁,学号是2023001

        // 2. 通过有参数构造方法创建对象(复用setter校验)
        Student student2 = new Student("李四", 200, "2023002"); // 年龄200不合法
        System.out.println(student2.introduce()); // 输出:大家好!我是李四,今年18岁,学号是2023002
    }
}

2. 继承(复用代码,建立类层级)

继承指一个类(子类)继承另一个类(父类)的属性和方法,子类可直接使用父类的非私有成员,还可扩展新的属性和方法,实现代码复用。Java 中用extends关键字实现继承,且单继承(一个子类只能有一个直接父类)。

(1)继承的核心概念
  • 父类(超类 / 基类):被继承的类(如 “Person” 类);

  • 子类(派生类):继承父类的类(如 “Student” 类,Student extends Person);

  • 继承内容:子类继承父类的public、protected成员(属性 / 方法),private成员无法直接继承(需通过父类的 getter/setter 访问);

  • super关键字:子类中用于访问父类的成员(如super.name访问父类属性,super()调用父类构造方法)。

示例:继承的实现(Person 父类 → Student 子类)
// 父类:Person(抽取共性属性和方法)
public class Person {
    protected String name; // 受保护的属性(子类可直接访问)
    private int age;       // 私有属性(子类需通过getter/setter访问)

    // 父类构造方法
    public Person(String name, int age) {
        this.name = name;
        this.setAge(age); // 调用自身setter校验年龄
    }

    // 父类成员方法:吃饭
    public void eat() {
        System.out.println(name + "正在吃饭");
    }

    // getter/setter方法(age)
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 0 || age > 150) {
            this.age = 18;
        } else {
            this.age = age;
        }
    }
}

// 子类:Student(继承Person,扩展特有属性和方法)
public class Student extends Person {
    // 子类特有属性:学号
    private String studentId;

    // 子类构造方法:必须先调用父类构造方法(super())
    public Student(String name, int age, String studentId) {
        super(name, age); // 调用父类的有参数构造方法(必须在子类构造方法第一行)
        this.studentId = studentId;
    }

    // 子类特有方法:学习(扩展父类功能)
    public void study() {
        // 子类可直接访问父类的protected属性name,或通过getter访问private属性age
        System.out.println(name + "(" + getAge() + "岁)正在学习,学号:" + studentId);
    }

    // 重写父类方法(Override):修改父类方法的实现逻辑
    @Override // 注解:标识该方法是重写父类的方法(语法校验)
    public void eat() {
        System.out.println(name + "正在学校食堂吃饭");
    }
}
示例:使用子类 Student
public class InheritanceDemo {
    public static void main(String[] args) {
        // 创建子类对象
        Student student = new Student("张三", 20, "2023001");

        // 1. 调用子类特有方法
        student.study(); // 输出:张三(20岁)正在学习,学号:2023001

        // 2. 调用重写后的父类方法(多态的体现)
        student.eat(); // 输出:张三正在学校食堂吃饭(而非父类的“正在吃饭”)

        // 3. 调用父类的getter方法(子类继承)
        System.out.println(student.getAge()); // 输出:20
    }
}

3. 多态(一种行为,多种实现)

多态指 “父类引用指向子类对象”,调用方法时会根据对象的实际类型执行对应的实现(即 “动态绑定”),核心是 “方法重写(Override)” 和 “父类引用指向子类对象”,能降低代码耦合度。

(1)多态的实现条件
  1. 存在继承关系(子类继承父类);

  2. 子类重写父类的方法;

  3. 父类引用指向子类对象(如Person p = new Student();)。

示例:多态的应用
// 父类:Animal
public class Animal {
    // 父类方法(被子类重写)
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

// 子类1:Dog(重写makeSound)
public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("小狗汪汪叫");
    }
}

// 子类2:Cat(重写makeSound)
public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("小猫喵喵叫");
    }
}

// 多态测试类
public class PolymorphismDemo {
    public static void main(String[] args) {
        // 1. 父类引用指向子类对象(多态的核心格式)
        Animal animal1 = new Dog(); // animal1实际是Dog对象
        Animal animal2 = new Cat(); // animal2实际是Cat对象

        // 2. 调用方法:根据对象实际类型执行对应实现
        animal1.makeSound(); // 输出:小狗汪汪叫(执行Dog的方法)
        animal2.makeSound(); // 输出:小猫喵喵叫(执行Cat的方法)

        // 3. 多态的优势:统一调用接口(如遍历不同子类对象)
        Animal[] animals = {new Dog(), new Cat()};
        for (Animal animal : animals) {
            animal.makeSound(); // 自动匹配对应子类的方法
        }
    }
}

输出结果:

小狗汪汪叫
小猫喵喵叫
小狗汪汪叫
小猫喵喵叫

十一、访问修饰符(控制访问权限)

Java 提供 4 种访问修饰符,用于控制类、成员变量、成员方法的访问范围,从严格到宽松依次为:private → default(无修饰符) → protected → public。

1. 访问修饰符的作用范围

修饰符同一类中同一包中(非子类)不同包中的子类不同包中的非子类
private
default
protected
public

2. 访问修饰符的使用场景

  • private:用于类的成员变量(封装时隐藏细节),仅类内部可访问;

  • default:默认修饰符(不写),用于同一包内的类之间共享成员;

  • protected:用于父类的成员,供子类(无论是否同包)访问,非子类不可访问;

  • public:用于对外暴露的接口(如类、getter/setter 方法),所有类均可访问。

示例:访问修饰符的应用
// 包1:com.example.demo1
package com.example.demo1;

public class Person {
    private String privateField = "私有属性"; // 仅Person类内部可访问
    String defaultField = "默认属性";         // 同包可访问
    protected String protectedField = "受保护属性"; // 同包或子类可访问
    public String publicField = "公共属性";   // 所有类可访问

    // 测试访问权限(同一类中均可访问)
    public void testAccess() {
        System.out.println(privateField);   // ✅
        System.out.println(defaultField);   // ✅
        System.out.println(protectedField); // ✅
        System.out.println(publicField);    // ✅
    }
}

// 包1中的非子类(同包,可访问default、protected、public)
package com.example.demo1;

public class NonSubClassInSamePackage {
    public void accessPerson() {
        Person person = new Person();
        // System.out.println(person.privateField); // ❌ private不可访问
        System.out.println(person.defaultField);   // ✅
        System.out.println(person.protectedField); // ✅
        System.out.println(person.publicField);    // ✅
    }
}

// 包2中的子类(不同包,可访问protected、public)
package com.example.demo2;
import com.example.demo1.Person;

public class SubClassInDifferentPackage extends Person {
    public void accessParent() {
        // System.out.println(privateField); // ❌ private不可访问
        // System.out.println(defaultField); // ❌ default不可访问(不同包)
        System.out.println(protectedField); // ✅ 子类可访问protected
        System.out.println(publicField);    // ✅
    }
}

十二、常用 API 基础(以 String 类为例)

API(Application Programming Interface)是 Java 提供的预定义类库,包含大量实用方法,无需手动实现。java.lang.String是最常用的 API 类之一,用于处理字符串(不可变字符序列)。

1. String 类的核心特性

  • 不可变性:String 对象创建后,其内容不可修改(若修改会创建新的 String 对象);

  • 常用构造方法

  • String():创建空字符串;

  • String(String original):根据传入的字符串创建对象;

  • String(char[] value):将字符数组转为字符串。

2. String 类的常用方法

方法名功能描述示例结果
length()获取字符串长度“Java”.length()4
charAt(int index)获取指定索引的字符(索引从 0 开始)“Java”.charAt(1)‘a’
equals(Object obj)比较字符串内容是否相等(区分大小写)“Java”.equals(“java”)false
equalsIgnoreCase(String str)比较字符串内容(不区分大小写)“Java”.equalsIgnoreCase(“java”)true
contains(CharSequence s)判断字符串是否包含指定子串“Hello Java”.contains(“Java”)true
indexOf(String str)查找子串首次出现的索引(未找到返回 - 1)“Hello Java”.indexOf(“Java”)6
substring(int beginIndex)从指定索引开始截取子串(到末尾)“Hello Java”.substring(6)“Java”
replace(CharSequence old, CharSequence new)替换字符串中的子串“Hello Java”.replace(“Java”, “World”)“Hello World”
split(String regex)按指定正则表达式分割字符串,返回字符串数组“a,b,c”.split(“,”)[“a”, “b”, “c”]
toUpperCase()将字符串转为大写“Java”.toUpperCase()“JAVA”
toLowerCase()将字符串转为小写“Java”.toLowerCase()“java”
示例:String 类常用方法的使用
public class StringApiDemo {
    public static void main(String[] args) {
        String str = "Hello Java!";

        // 1. 获取长度
        System.out.println("字符串长度:" + str.length()); // 输出:7

        // 2. 获取指定索引字符
        System.out.println("索引3的字符:" + str.charAt(3)); // 输出:'l'

        // 3. 比较内容
        String str2 = "hello java!";
        System.out.println("equals比较:" + str.equals(str2)); // 输出:false
        System.out.println("忽略大小写比较:" + str.equalsIgnoreCase(str2)); // 输出:true

        // 4. 包含子串
        System.out.println("是否包含'Java':" + str.contains("Java")); // 输出:true

        // 5. 截取子串
        System.out.println("从索引6截取:" + str.substring(6)); // 输出:"Java!"

        // 6. 替换子串
        String newStr = str.replace("Java", "World");
        System.out.println("替换后:" + newStr); // 输出:"Hello World!"
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值