Java 方法与对象

104 阅读1分钟

方法重载

同一个类中, 允许多个同名方法存在, 但是参数列表不一样 (参数类型, 顺序, 个数 ...) 返回类型 and 参数名👈无要求

(从人的角度 能区分开,匹配两个方法即可)

如:

calculate(int n1, int n2)
calculate(int n1, double n2)
calculate(double n2, int n1)
caluclate(int n1, int n2, int n3)

可变参数

同一个类中多个同名同功能但参数个数不同的方法, 封装成一个方法~

可变参数 ...xx 通常放在形参的后面 (当有普通类型的参数时) (不然会有歧义)~

一个形参列表只能有一个可变参数

public class test1 {

    public static void main(String[] args) {
        Method method = new Method();
        
       System.out.println(method.showScore("sam", 1.2, 20.3, 123.1));
       System.out.println(method.showScore("sam", 1.2,20.3));
       System.out.println(method.showScore("sam", 1.2,20.3,213.2,1231.1));
    }

}

class Method{
    public String showScore(String name, double... score) {
        double sum = 0.0;
        for (int i = 0; i < score.length; i++) {
            sum += score[i];
        }
        return name + sum;
    } 
}

变量的作用域

Java中 主要的变量分为 属性(成员变量, 全局变量)和局部变量

局部变量指的是在成员方法中定义的变量 (除了属性之外的变量) 其作用域在于它的代码块中~

全局变量可以不赋值, 直接使用, 因为其有默认值(在堆中开辟空间), 作用范围为全局;

而局部变量则需要赋值后才能使用(在栈中开辟空间), 因为没用默认值

注意细节

  1. 属性和局部变量可以重名, 访问时遵循就近原则
  2. 在同一个作用域中, 如在同一个成员方法中, 两个局部变量 不能重名~
  3. 属性的生命周期长, 随着对象的创建而创建, 随着对象销毁而销毁。而局部变量的生命周期是随着代码块的, 即调用方法~
  4. 作用范围不同, 全局变量/属性 能够被本类使用 or 其他类(通过创建对象 对象调用)
    局部变量: 只能在本类中的方法中使用
  5. 修饰符不同 全局变量/属性可以使用修饰符, 局部变量不可以使用

构造器

一般用于对新对象的初始化(属性) (到构造器的时候, 对象已经存在了~)

  1. 构造器的修饰符可以是 默认, 可以是private, public, protected
  2. 没有返回值 (不能写void)
  3. 方法名要与类名一致
  4. 参数列表和成员方法一样的规则
  5. 构造器的调用由系统完成 (内置无参构造, 可以重载该方法 定制化~)

注意事项

  1. 一个类可以定义多个不同的构造器, 即构造器重载
  2. 构造器名要与类名一致
  3. 构造器没用返回值
  4. 构造器是完成对象的初始化, 那时对象已存在, 而不是创建对象
  5. 在创建对象的时候, 系统会自动调用该类的构造方法
  6. 若没有定义构造器, 系统会自动给类生成一个默认无参的构造器; 但若定义了自己的构造器, 默认的构造器就会被覆盖, 就不能使用默认的无参构造器, 除非显示的定义一下, 即 类名() {}

javap xx(.class 文件) 反汇编命令

class Dog {
    // 默认构造器
    /*
     *  Dog(){} 
     */
    public Dog(String name) { // 自己定义的构造器

    }
    public Dog(){} //一旦定义了其他构造器就会覆盖无参构造, 无参若想要用 则需要显式调用
}
public class test1 {
    public static void main(String[] args) {
        Person person1 = new Person(); // 无参构造
        System.out.println(person1.name + person1.age); // name -> null age -> 18
        Person person2 = new Person("sam", 20); // 自己定义的构造器
        System.out.println(person2.name+person2.age);
    }
}

class Person {
    int age;     // 默认值 0
    String name; // 默认值 null

    public Person() { // 无参构造器
        this.age = 18;
    }

    public Person(String pName, int pAge) {
        name = pName;
        age = pAge;
    }
}

对象创建分析

class Person{
	int age = 90;
    String name;
    Person(String n, int a){ // 构造器
        name = n; // 属性赋值
        age = a;
    }
}
Person p = new Person("Tom",29);

流程分析:

  1. (方法区) 加载Person类的信息 (Person.class), 只会加载一次
  2. 在堆中分配空间 -> 地址
  3. 完成对象初始化(属性),执行顺序: 先默认初始化(属性), 显式初始化(即属性定义的时候带有初始化), 再是看 构造器的初始化
  4. 会把对象在堆中的地址返回给new 对象的变量名 (对象的引用)