Java基础:面向对象编程2

1 Java中的变量

Java 变量就好像一个容器,可以保存程序在运行过程中的值,它在声明的时候会定义对应的数据类型(Java 分为两种数据类型:基本数据类型和引用数据类型)。变量按照作用域的范围又可分为三种类型:局部变量,成员变量和静态变量。

1.1 局部变量

1.1.1 局部变量的特点

  1. 作用域

    • 局部变量的作用域仅限于声明它的方法、构造方法或语句块内部。一旦超出这个范围,变量将不再可用。
  2. 生命周期

    • 局部变量的生命周期从声明它的语句开始,到包含它的方法、构造方法或语句块执行结束时结束。
  3. 访问修饰符

    • 局部变量不能使用访问修饰符(如 public, private, protected),因为它们的作用域仅限于方法内部。
  4. 存储位置

    • 局部变量通常存储在栈(Stack)上。栈是一种后进先出(LIFO)的数据结构,用于存储方法调用和局部变量。
  5. 初始化

    • 局部变量必须在使用前进行初始化,否则编译器会报错。这是因为局部变量没有默认值,不像类的成员变量(实例变量)那样有默认值。

1.1.2 示例代码分析

在示例中:

public class LocalVariable {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;
        int c = a + b;
        System.out.println(c);
    }
}
  • a, b, c 都是局部变量,它们在 main 方法中声明和使用。
  • 这些变量的作用域仅限于 main 方法内部。
  • main 方法执行完毕后,这些变量将被销毁,不再占用内存。

1.1.2 其他注意事项

  1. 嵌套块中的局部变量

    • 如果在方法内部有嵌套的代码块(如 if 语句、for 循环等),每个代码块都可以有自己的局部变量。这些变量的作用域仅限于它们所在的代码块。
  2. 变量名冲突

    • 如果在嵌套的代码块中声明了与外部代码块同名的局部变量,内部代码块中的变量将“遮蔽”外部代码块中的同名变量。

示例:嵌套块中的局部变量

public class LocalVariableExample {
    public static void main(String[] args) {
        int a = 10;
        if (a > 5) {
            int b = 20; // 局部变量 b 仅在 if 语句块中有效
            System.out.println(a + b); // 输出 30
        }
        // System.out.println(b); // 编译错误,b 在此处不可见
    }
}

在这个示例中,变量 b 仅在 if 语句块中有效,超出这个范围后,b 将不再可用。

1.2 成员变量

1.2.1 成员变量的特点

  1. 声明位置

    • 成员变量声明在类中,但在方法、构造方法和语句块之外。它们属于类的实例(对象),而不是方法或代码块。
  2. 生命周期

    • 成员变量的生命周期与对象的生命周期一致。当对象被创建时,成员变量也随之创建;当对象被销毁时,成员变量也随之销毁。
  3. 访问方式

    • 成员变量只能通过类的实例(对象)来访问。例如,在示例中,通过 iv.data 访问成员变量 data
  4. 访问修饰符

    • 成员变量可以使用访问修饰符(如 public, private, protected)来控制其可见性。通常情况下,成员变量应该设为私有(private),并通过公共的 getter 和 setter 方法来访问和修改。
  5. 默认值

    • 成员变量具有默认值。数值型变量的默认值是 0,布尔型变量的默认值是 false,引用类型变量的默认值是 null

1.2.2 示例代码分析

在示例中:

public class InstanceVariable {
    int data = 88;
    public static void main(String[] args) {
        InstanceVariable iv = new InstanceVariable();
        System.out.println(iv.data); // 88
    }
}
  • data 是一个成员变量,它声明在类 InstanceVariable 中,但在方法体外。
  • iv 是一个引用类型的变量,它引用了一个 InstanceVariable 类的实例(对象)。
  • 通过 new InstanceVariable() 创建了一个对象,并将其引用赋值给 iv
  • 通过 iv.data 可以访问成员变量 data,并输出其值 88

1.2.3 其他注意事项

  1. 初始化

    • 成员变量可以在声明时直接初始化,也可以在构造方法中进行初始化。如果未显式初始化,它们将使用默认值。
  2. 静态变量

    • 除了成员变量,Java 中还有静态变量(类变量)。静态变量使用 static 关键字声明,它们属于类本身,而不是类的实例。静态变量在类加载时创建,并且在整个程序运行期间都存在。

1.3 静态变量

1.3.1 静态变量的特点

  1. 声明位置

    • 静态变量在类中以 static 关键字声明,但必须在方法、构造方法和语句块之外。它们属于类本身,而不是类的实例。
  2. 共享性

    • 无论一个类创建了多少个对象,类只拥有静态变量的一份拷贝。所有对象共享这个静态变量。
  3. 访问方式

    • 静态变量可以通过类名直接访问,不需要创建类的实例。例如,在示例中,通过 StaticVariable.data 访问静态变量 data
  4. 存储位置

    • 静态变量存储在静态存储区(也称为方法区)。静态存储区在程序开始时创建,在程序结束时销毁。
  5. 生命周期

    • 静态变量的生命周期从程序开始时创建,到程序结束时销毁。
  6. 可见性

    • 静态变量具有与成员变量相似的可见性。为了对类的使用者可见,大多数静态变量声明为 public 类型。
  7. 默认值

    • 静态变量的默认值与实例变量相似。数值型变量的默认值是 0,布尔型变量的默认值是 false,引用类型变量的默认值是 null

1.3.2 示例代码分析

在你的示例中:

public class StaticVariable {
    static int data = 99;
    public static void main(String[] args) {
        System.out.println(StaticVariable.data); // 99
    }
}
  • data 是一个静态变量,它声明在类 StaticVariable 中,并在声明时初始化为 99
  • 通过 StaticVariable.data 可以直接访问静态变量 data,不需要创建类的实例。

1.3.3 其他注意事项

  1. 静态初始化块

    • 静态变量可以在静态语句块中初始化。静态语句块在类加载时执行,并且只执行一次。
  2. 常量

    • 静态变量通常用于声明常量。常量使用 final 关键字修饰,并且通常声明为 public static final

1.3.4 示例:静态变量的初始化和静态初始化块

public class StaticVariableExample {
    public static int data; // 静态变量

    // 静态初始化块
    static {
        data = 99;
        System.out.println("静态初始化块执行");
    }

    public static void main(String[] args) {
        System.out.println(StaticVariableExample.data); // 99
    }
}

在这个示例中:

  • data 是一个静态变量,它在静态初始化块中被初始化为 99
  • 静态初始化块在类加载时执行,并且只执行一次。
  • main 方法中,通过 StaticVariableExample.data 访问静态变量 data

1.4 常量

1.4.1 常量的特点

  1. 不可变性

    • 常量使用 final 关键字修饰,一旦赋值后,其值无法改变。常量的值在声明时必须初始化,否则编译器会报错。
  2. 命名规范

    • 常量的命名通常采用全大写字母,单词之间用下划线分隔(例如:UP_DIRECTION)。这种命名规范有助于区分常量和普通变量。
  3. 作用

    • 代表常数:常量可以用来表示不会改变的数值或字符串,便于修改和维护。例如,圆周率的值可以定义为常量 final double PI = 3.14
    • 增强可读性:常量可以用来表示具有特定含义的值,增强程序的可读性。例如,方向可以用常量 final int UP = 0final int DOWN = 1 表示。

1.4.2 示例代码分析

在示例中:

public class FinalVariable {
    final String CHEN = "沉";
    static final String MO = "默";
    public static void main(String[] args) {
        FinalVariable fv = new FinalVariable();
        System.out.println(fv.CHEN); // 输出 "沉"
        System.out.println(MO); // 输出 "默"
    }
}
  • CHEN 是一个实例常量,使用 final 关键字修饰,值为 "沉"
  • MO 是一个静态常量,使用 static final 关键字修饰,值为 "默"
  • main 方法中,通过 fv.CHEN 访问实例常量 CHEN,通过 MO 访问静态常量 MO

1.4.3 其他注意事项

  1. 初始化时机

    • 实例常量必须在声明时或在构造方法中初始化。
    • 静态常量必须在声明时或在静态初始化块中初始化。
  2. 常量的使用场景

    • 常量通常用于表示不会改变的配置参数、数学常数、枚举值等。

2 Java中的方法

2.1 Java中的方法是什么

方法用来实现代码的可重用性,我们编写一次方法,并多次使用它。通过增加或者删除方法中的一部分代码,就可以提高整体代码的可读性。

只有方法被调用时,它才会执行。Java 中最有名的方法当属 main() 方法,这是程序的入口。

2.2 如何声明方法

2.2.1 方法的声明

方法的声明包括以下几个部分:

  1. 访问权限

    • 指定方法的可见性。Java 提供了四种访问权限修饰符:
      • public:该方法可以被所有类访问。
      • private:该方法只能在定义它的类中访问。
      • protected:该方法可以被同一个包中的类,或者不同包中的子类访问。
      • default(不写访问修饰符):该方法只能被同一个包中的类可见。
  2. 返回类型

    • 方法返回的数据类型,可以是基本数据类型(如 int, double)、对象(如 String)、集合(如 List)等。如果方法不需要返回数据,则使用 void 关键字。
  3. 方法名

    • 方法名最好反映出方法的功能。方法名通常是一个动词,并且以小写字母开头。如果方法名包含多个单词,第一个单词通常是动词,后续单词可以是形容词或名词,并采用驼峰命名法。
    • 示例:
      • sum():一个单词的方法名。
      • stringComparison():多个单词的方法名。
  4. 参数列表

    • 参数放在圆括号内,如果有多个参数,可以使用逗号隔开。参数包括参数类型和参数名。如果方法没有参数,圆括号是空的。
    • 示例:
      • int add(int a, int b):包含两个参数的方法。
      • void printMessage():没有参数的方法。
  5. 方法签名

    • 方法签名包括方法名和参数列表。方法签名用于唯一标识一个方法。
  6. 方法体

    • 方法体放在一对花括号 {} 内,包含执行特定任务的代码。

2.2.2 示例代码

下面是一个完整的示例,展示了如何声明和调用一个方法:

public class MethodExample {
    // 声明一个公共方法,计算两个整数的和
    public int add(int a, int b) {
        return a + b;
    }

    // 声明一个私有方法,打印消息
    private void printMessage() {
        System.out.println("Hello, World!");
    }

    // main 方法是程序的入口
    public static void main(String[] args) {
        MethodExample example = new MethodExample();

        // 调用 add 方法
        int result = example.add(5, 3);
        System.out.println("Sum: " + result); // 输出 "Sum: 8"

        // 调用 printMessage 方法
        example.printMessage(); // 输出 "Hello, World!"
    }
}

在这个示例中:

  • add 方法是一个公共方法,接受两个 int 类型的参数,并返回它们的和。
  • printMessage 方法是一个私有方法,没有参数,也没有返回值,用于打印一条消息。
  • main 方法中,我们创建了 MethodExample 类的实例,并调用了 addprintMessage 方法。

2.3 方法有哪几种

2.3.1 方法的分类

方法可以分为以下两种主要类型:

  1. 标准类库方法(预先定义方法)

    • Java 提供了大量预先定义好的方法供我们调用,这些方法通常是标准类库的一部分。这些方法已经由 Java 开发团队实现,可以直接在代码中使用。
    • 例如:
      • String 类的 length()equals()compareTo() 方法。
      • System.out.println() 方法,用于在控制台打印信息。
      • Math 类的 sqrt()pow()abs() 方法,用于数学计算。
  2. 用户自定义方法

    • 当标准类库方法无法满足特定需求时,开发者可以自定义方法。用户自定义方法是由开发者自己编写的,用于实现特定的功能。
    • 用户自定义方法可以分为静态方法和实例方法:
      • 静态方法:使用 static 关键字修饰,属于类本身,不需要创建类的实例即可调用。静态方法通常用于工具类或辅助方法。
      • 实例方法:不使用 static 关键字修饰,属于类的实例,需要通过类的实例来调用。实例方法通常用于操作对象的状态或行为。

2.3.2 示例代码

下面是一个示例,展示了标准类库方法和用户自定义方法的使用:

public class MethodExample {
    // 用户自定义方法:计算两个整数的和
    public int add(int a, int b) {
        return a + b;
    }

    // 用户自定义静态方法:打印消息
    public static void printMessage(String message) {
        System.out.println(message);
    }

    public static void main(String[] args) {
        // 使用标准类库方法:String 类的 length() 方法
        String name = "沉默王二";
        int length = name.length();
        System.out.println("字符串长度: " + length); // 输出 "字符串长度: 4"

        // 使用标准类库方法:System.out.println() 方法
        System.out.println("Hello, World!"); // 输出 "Hello, World!"

        // 使用用户自定义方法:add 方法
        MethodExample example = new MethodExample();
        int result = example.add(5, 3);
        System.out.println("Sum: " + result); // 输出 "Sum: 8"

        // 使用用户自定义静态方法:printMessage 方法
        printMessage("这是一个静态方法的调用"); // 输出 "这是一个静态方法的调用"
    }
}

在这个示例中:

  • add 方法是一个用户自定义的实例方法,用于计算两个整数的和。
  • printMessage 方法是一个用户自定义的静态方法,用于打印消息。
  • main 方法中,我们使用了标准类库方法(如 String 类的 length() 方法和 System.out.println() 方法),以及用户自定义方法(如 add 方法和 printMessage 方法)。

2.4 什么是实例方法

2.4.1 实例方法的特点

  1. 非静态方法

    • 实例方法没有使用 static 关键字修饰,属于类的实例。因此,在调用实例方法之前,必须创建类的对象。
  2. 调用方式

    • 实例方法的调用方式是 对象名.方法名()。例如,instanceMethodExample.add(1, 2) 调用 InstanceMethodExample 类的实例方法 add()
  3. 访问实例变量

    • 实例方法可以直接访问类的实例变量(成员变量)。例如,this.name 访问当前对象的 name 变量。

2.4.2 示例代码

下面是一个示例,展示了如何声明和调用实例方法:

public class InstanceMethodExample {
    public static void main(String[] args) {
        // 创建 InstanceMethodExample 对象
        InstanceMethodExample instanceMethodExample = new InstanceMethodExample();

        // 调用实例方法 add
        int result = instanceMethodExample.add(1, 2);
        System.out.println("Sum: " + result); // 输出 "Sum: 3"
    }

    // 实例方法:计算两个整数的和
    public int add(int a, int b) {
        return a + b;
    }
}

在这个示例中:

  • add 方法是一个实例方法,用于计算两个整数的和。
  • main 方法中,我们创建了 InstanceMethodExample 类的实例 instanceMethodExample,并通过该实例调用了 add 方法。

2.4.3 特殊类型的实例方法:getter 和 setter 方法

  1. getter 方法

    • getter 方法用于获取私有变量(private 修饰的字段)的值。getter 方法的命名通常以 get 开头,后跟变量名(首字母大写)。
  2. setter 方法

    • setter 方法用于设置私有变量的值。setter 方法的命名通常以 set 开头,后跟变量名(首字母大写)。

2.4.4 示例:getter 和 setter 方法

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

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

    // setter 方法:设置 name 的值
    public void setName(String name) {
        this.name = name;
    }

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

    // setter 方法:设置 age 的值
    public void setAge(int age) {
        this.age = age;
    }

    // getter 方法:获取 sex 的值
    public int getSex() {
        return sex;
    }

    // setter 方法:设置 sex 的值
    public void setSex(int sex) {
        this.sex = sex;
    }

    public static void main(String[] args) {
        // 创建 Person 对象
        Person person = new Person();

        // 使用 setter 方法设置属性值
        person.setName("沉默王二");
        person.setAge(30);
        person.setSex(1);

        // 使用 getter 方法获取属性值
        System.out.println("Name: " + person.getName()); // 输出 "Name: 沉默王二"
        System.out.println("Age: " + person.getAge());   // 输出 "Age: 30"
        System.out.println("Sex: " + person.getSex());   // 输出 "Sex: 1"
    }
}

在这个示例中:

  • Person 类包含三个私有变量:nameagesex
  • 每个私有变量都有一个对应的 getter 方法和 setter 方法。
  • main 方法中,我们创建了 Person 类的实例 person,并使用 setter 方法设置属性值,使用 getter 方法获取属性值。

2.5 什么是静态方法

2.5.1 静态方法的特点

  1. 静态方法的声明

    • 静态方法使用 static 关键字修饰,属于类本身,而不是类的实例。因此,静态方法可以直接通过类名调用,不需要创建类的实例。
  2. 调用方式

    • 静态方法的调用方式是 类名.静态方法名()。例如,StaticMethodExample.add(1, 2) 调用 StaticMethodExample 类的静态方法 add()
  3. 访问限制

    • 静态方法只能访问静态变量和静态方法,不能直接访问实例变量和实例方法。如果需要访问实例变量或实例方法,必须通过类的实例来调用。
  4. 工具类

    • 静态方法通常用于工具类或辅助方法,这些方法不需要访问类的实例变量,也不需要创建类的实例。例如,Math 类中的许多方法(如 sqrt()pow()abs())都是静态方法。

2.5.2 示例代码

下面是一个示例,展示了如何声明和调用静态方法:

public class StaticMethodExample {
    public static void main(String[] args) {
        // 调用静态方法 add
        int result = add(1, 2);
        System.out.println("Sum: " + result); // 输出 "Sum: 3"
    }

    // 静态方法:计算两个整数的和
    public static int add(int a, int b) {
        return a + b;
    }
}

在这个示例中:

  • add 方法是一个静态方法,用于计算两个整数的和。
  • main 方法中,我们直接调用了静态方法 add,而不需要创建 StaticMethodExample 类的实例。

2.5.3 静态方法与实例方法的区别

  1. 调用方式

    • 静态方法通过类名调用,实例方法通过对象名调用。
  2. 访问变量

    • 静态方法只能访问静态变量和静态方法,实例方法可以访问实例变量和实例方法。
  3. 生命周期

    • 静态方法在类加载时创建,实例方法在对象创建时创建。

2.5.4 示例:静态方法与实例方法的对比

public class MethodComparison {
    // 静态变量
    static int staticVar = 10;

    // 实例变量
    int instanceVar = 20;

    // 静态方法:访问静态变量
    public static void printStaticVar() {
        System.out.println("静态变量: " + staticVar);
    }

    // 实例方法:访问实例变量
    public void printInstanceVar() {
        System.out.println("实例变量: " + instanceVar);
    }

    public static void main(String[] args) {
        // 调用静态方法
        printStaticVar(); // 输出 "静态变量: 10"

        // 创建类的实例
        MethodComparison example = new MethodComparison();

        // 调用实例方法
        example.printInstanceVar(); // 输出 "实例变量: 20"
    }
}

在这个示例中:

  • printStaticVar 是一个静态方法,用于访问静态变量 staticVar
  • printInstanceVar 是一个实例方法,用于访问实例变量 instanceVar
  • main 方法中,我们直接调用了静态方法 printStaticVar,并通过类的实例调用了实例方法 printInstanceVar

2.6 什么是抽象方法

2.6.1 抽象方法的特点

  1. 没有方法体

    • 抽象方法没有方法体,只有方法声明。抽象方法的声明以分号 ; 结尾,而不是花括号 {}
  2. 必须存在于抽象类中

    • 抽象方法必须在抽象类中声明。抽象类使用 abstract 关键字修饰。
  3. 必须被重写

    • 当一个类继承了抽象类后,必须重写(实现)抽象类中的所有抽象方法。否则,子类也必须声明为抽象类。

2.6.2 抽象类的特点

  1. 不能实例化

    • 抽象类不能被实例化,只能被继承。抽象类可以包含抽象方法和非抽象方法。
  2. 可以包含成员变量和构造方法

    • 抽象类可以包含成员变量、构造方法和普通方法。
  3. 子类必须实现抽象方法

    • 如果一个类继承了抽象类,并且抽象类中有抽象方法,子类必须实现这些抽象方法。

2.6.3 示例代码

下面是一个示例,展示了如何声明和使用抽象方法和抽象类:

// 抽象类
abstract class AbstractDemo {
    // 抽象方法
    abstract void display();
}

// 继承抽象类的子类
public class MyAbstractDemo extends AbstractDemo {
    // 重写抽象方法
    @Override
    void display() {
        System.out.println("重写了抽象方法");
    }

    public static void main(String[] args) {
        // 创建子类的实例
        MyAbstractDemo myAbstractDemo = new MyAbstractDemo();
        // 调用重写的抽象方法
        myAbstractDemo.display(); // 输出 "重写了抽象方法"
    }
}

在这个示例中:

  • AbstractDemo 是一个抽象类,包含一个抽象方法 display()
  • MyAbstractDemo 类继承了 AbstractDemo 类,并重写了 display() 方法。
  • main 方法中,我们创建了 MyAbstractDemo 类的实例,并调用了重写的 display() 方法。

3 思维导图

在这里插入图片描述
在这里插入图片描述

4 参考链接

  1. Java变量:了解局部变量、成员变量、静态变量和常量的特点与用途
  2. Java方法:实例方法、静态方法与抽象方法的区别与应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值