3.2 Java中类与对象(构造方法、封装、访问权限控制、传递、静态变量)


3.2.1 类的定义

在Java中,类的定义是创建对象的基础。类定义了对象的属性(成员变量)和方法(成员函数),以及对象的行为和状态。以下是类定义的基本步骤和组成部分:

1. 类的声明

使用class关键字来声明一个类。类名通常采用大驼峰命名法(首字母大写,不使用下划线)。

public class ClassName {
    // 类体
}

在这里插入图片描述

2. 成员变量

成员变量是类的一部分,用于存储对象的状态。它们可以是私有的(private)或公有的(public),具体取决于访问权限的需求。

private int age; // 私有成员变量
public String name; // 公有成员变量

3. 构造方法

构造方法是在创建对象时用于初始化对象的特殊方法。它的名称必须与类名相同,并且没有返回类型。

public ClassName(int initialAge) {
    age = initialAge;
}

4. 方法

方法定义了对象的行为。它们可以是公有的或私有的,具体取决于是否需要在类的外部调用。

public void displayInfo() {
    System.out.println("Name: " + name + ", Age: " + age);
}

5. 静态变量和静态方法

静态变量和方法属于类本身,而不是类的任何特定对象。它们可以通过类名直接访问。

public static int count = 0; // 静态变量

public static void displayCount() {
    System.out.println("Number of objects: " + count);
}

6. 访问修饰符

Java提供了四种访问修饰符来控制成员的可见性:

  • public:可以被任何其他类访问。
  • private:只能被定义它的类访问。
  • protected:可以被同一包内的类或不同包中的子类访问。
  • 默认(无修饰符):可以被同一包内的类访问。

7. 完整的类定义示例

public class Person {
    private String name;
    private int age;

    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 公有方法
    public void displayInfo() {
        System.out.println("Name: " + name + ", Age: " + age);
    }

    // 私有方法
    private void think() {
        System.out.println(name + " is thinking.");
    }

    // 静态方法
    public static void main(String[] args) {
        Person person1 = new Person("Alice", 30);
        person1.displayInfo();
    }
}

在这个示例中,Person类有两个私有成员变量nameage,一个构造方法,一个公有方法displayInfo,一个私有方法think,以及一个静态方法mainmain方法用于创建Person对象并调用其方法。

3.2.2 对象的创建与使用

好的,让我们更详细地探讨Java中对象的创建和使用。

对象的创建

  1. 定义类:首先,你需要定义一个类,这个类将作为创建对象的基础。
public class Car {
    // 属性(成员变量)
    private String brand; // 品牌
    private int year;     // 生产年份

    // 构造方法
    public Car(String brand, int year) {
        this.brand = brand;
        this.year = year;
    }

    // 方法
    public void start() {
        System.out.println(brand + " starts.");
    }

    public void stop() {
        System.out.println(brand + " stops.");
    }

    // Getter和Setter方法
    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }
}
  1. 实例化对象:使用new关键字和类的构造方法来创建对象。这将分配内存并初始化对象。
public class Main {
    public static void main(String[] args) {
        // 创建Car类的对象
        Car myCar = new Car("Toyota", 2020);
    }
}

对象的使用

  1. 调用方法:一旦对象被创建,就可以使用它的公有方法。
myCar.start(); // 输出: Toyota starts.
myCar.stop();  // 输出: Toyota stops.
  1. 访问属性:可以通过公有的getter和setter方法来访问和修改对象的私有属性。
// 访问属性
String carBrand = myCar.getBrand(); // 获取品牌
int carYear = myCar.getYear();       // 获取生产年份

// 修改属性
myCar.setBrand("Honda");
myCar.setYear(2019);
  1. 对象的内存管理:Java使用自动垃圾回收机制来管理对象的内存。当对象没有任何引用指向它时,垃圾回收器会在适当的时候回收其占用的内存。

封装

封装是面向对象编程的一个核心概念,它允许隐藏对象的内部状态和实现细节,只通过方法暴露接口。

public class Car {
    private String brand; // 私有属性,外部无法直接访问

    // 构造方法
    public Car(String brand) {
        this.brand = brand;
    }

    // 公有方法
    public void start() {
        System.out.println(brand + " starts.");
    }

    // Getter方法
    public String getBrand() {
        return brand;
    }

    // Setter方法
    public void setBrand(String brand) {
        this.brand = brand;
    }
}

构造方法的重载

构造方法的重载允许你为类定义多个构造方法,每个构造方法可以有不同的参数列表。

public class Car {
    private String brand;
    private int year;

    // 无参构造方法
    public Car() {
        this.brand = "Unknown";
        this.year = 0;
    }

    // 带品牌参数的构造方法
    public Car(String brand) {
        this.brand = brand;
        this.year = 0;
    }

    // 带品牌和年份参数的构造方法
    public Car(String brand, int year) {
        this.brand = brand;
        this.year = year;
    }
}

创建多个对象

可以创建多个对象,每个对象都有自己的属性和方法。

public class Main {
    public static void main(String[] args) {
        Car car1 = new Car("Toyota", 2020);
        Car car2 = new Car("Honda", 2019);

        car1.start();
        car2.start();
    }
}

总结

通过这些步骤,可以在Java中创建和使用对象,实现面向对象编程的各种功能。对象的创建和使用涉及到类的实例化、属性的访问和修改、方法的调用,以及内存管理等方面。封装、构造方法的重载和垃圾回收是Java中对象创建和使用过程中的重要概念。

3.2.3 对象的引用传递

在Java中,对象的引用传递是指在方法调用时,对象的引用(而不是对象本身)被传递给方法。这意味着方法接收的是对象引用的副本,而这个副本指向原始对象。因此,当方法内部对对象进行修改时,这些修改会影响到原始对象。

引用传递的概念

在Java中,所有的变量都是通过引用传递的。这意味着无论是基本数据类型(如int、double等)还是对象,都是通过它们的引用来传递的。对于基本数据类型,传递的是值的副本,而对于对象,传递的是引用的副本。

示例解释

下面是一个简单的示例,说明对象的引用传递:

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    // 修改对象的状态
    public void changeName(String newName) {
        name = newName;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice");
        System.out.println("Before: " + person.name); // 输出: Before: Alice

        changePersonName(person, "Bob");
        System.out.println("After: " + person.name); // 输出: After: Bob
    }

    public static void changePersonName(Person person, String newName) {
        person.changeName(newName);
    }
}

在这个例子中:

  • Person类有一个私有属性name和一个修改这个属性的方法changeName
  • main方法中,创建了一个Person对象,并初始化其name为"Alice"。
  • changePersonName方法接收一个Person对象的引用和一个新的名字。在这个方法内部,调用了changeName方法来修改对象的name属性。
  • 因为对象是通过引用传递的,所以当changePersonName方法修改了传入的Person对象的name属性时,原始对象的name也被修改了。

引用传递的影响

由于Java中对象是通过引用传递的,所以在方法内部对对象属性的任何修改都会反映到原始对象上。这允许方法能够修改对象的状态,而不仅仅是返回一个新的状态。

注意事项

  • 不可变性:如果你希望对象在方法调用后保持不变,可以考虑使用不可变对象。不可变对象一旦创建,其状态就不能被改变。
  • 深拷贝与浅拷贝:在处理对象的引用传递时,需要考虑深拷贝和浅拷贝的问题。浅拷贝只复制对象的引用,而深拷贝会复制对象及其所有子对象。

通过理解引用传递的概念,你可以更有效地控制对象在方法调用中的行为,以及如何设计方法来处理对象的状态。

3.2.4 访问控制权限

在Java中,访问控制权限是面向对象编程的一个重要概念,它决定了类、方法、构造方法和变量(成员变量)可以被哪些其他代码访问。Java提供了四种访问级别:publicprotectedprivate 和默认(无修饰符)。

1. public

  • 访问级别:可以被任何其他类访问,无论它们是否在同一个包中。
  • 使用场景:当希望类的成员或方法能够被任何其他类访问时使用。
public class MyClass {
    public int publicVariable; // 公有变量,任何地方都可以访问
    public void publicMethod() { // 公有方法,任何地方都可以访问
        // ...
    }
}

2. protected

  • 访问级别:可以被同一包内的类访问,也可以被不同包中的子类访问。
  • 使用场景:当希望类的成员或方法能够被子类访问,但不希望其他包中的类访问时使用。
protected class MyClass {
    protected int protectedVariable; // 受保护变量,同一包内或子类可以访问
    protected void protectedMethod() { // 受保护方法,同一包内或子类可以访问
        // ...
    }
}

3. private

  • 访问级别:只能在定义它的类内部访问。
  • 使用场景:当希望类的成员或方法只被该类自身访问时使用,这是实现封装的一种方式。
class MyClass {
    private int privateVariable; // 私有变量,仅在本类中可以访问
    private void privateMethod() { // 私有方法,仅在本类中可以访问
        // ...
    }
}

4. 默认(无修饰符)

  • 访问级别:可以被同一包内的类访问,但不能被不同包中的类访问。
  • 使用场景:当没有明确指定访问级别,且希望类的成员或方法仅在同一包内可见时使用。
class MyClass {
    int defaultVariable; // 默认访问级别变量,同一包内可以访问
    void defaultMethod() { // 默认访问级别方法,同一包内可以访问
        // ...
    }
}

访问控制权限的注意事项

  • 封装性:通过使用private修饰符,可以隐藏类的内部实现细节,只暴露必要的接口给外部,这是封装的核心。
  • 继承protected修饰符允许子类访问父类的成员,这在实现继承时非常有用。
  • 接口设计public修饰符常用于定义类的公共接口,确保其他类可以按照预期的方式与类交互。
  • 包访问:默认访问级别允许类在同一个包内被访问,这有助于组织代码和控制访问权限。

注意:外部类的访问权限只能是public或default,所以Test类只能使用public修饰或者不写修饰符。局部成员是没有访问权限控制的,因为局部成员只在其所在的作用域内起作用,不可能被其他类访问到,如果在程序中这样编写代码,编译器会报错。

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值