Java 之旅

初级06 - Java对象系统基础

2019-07-28  本文已影响0人  晓风残月1994

面向对象系统更加符合人对客观世界的抽象感知,作为面向对象语言的佼佼者,本篇是关于 Java 的面向对象系统。

1. 什么是对象

2. 对象是由什么组成的?

3. 对象的构造函数

4. 对象的方法

5. 方法的重载(overload)

定义:同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可(参数个数或参数类型不同),另外子类也可以对父类的方法进行重载。

信雅达的方法名是可以重复使用的,通过可接收的参数不同来加以区分/匹配。

存在隐式转换时,根据类型优先匹配最接近的,如果存在 null (Java世界中唯一没有类型的值),则会产生歧义,需要手动把 null 强制转为某个类型。

注意:
判断是否重载:
跟方法的权限修饰符、返回值类型、形参变量名和方法体都没有关系!

看一个具有方法重载时的调用优先级:

public class  Cat {
    public static void main(String[] args) {
        Cat cat =  new Cat();
        cat.foo(1);
    }

    void foo(int i) {
    }
    void foo(Integer i) {
    }
    void foo(Number i) {
    }
    void foo(Object i) {
    }
}

再看下面的例子,此时 null 可能是 Integer 类型也可能是 Object[],两种类型并 没有直接的父子关系:

public class  Cat {
    public static void main(String[] args) {
        Cat cat =  new Cat();
        cat.foo(null);
    }

    void foo(int i) {
    }
    void foo(Integer i) {
    }
    void foo(Number i) {
    }
    void foo(Object i) {
    }
    void foo(Object[] i) {
    }
}

此时产生了歧义,需要强制指定 null 的类型:

// ...
    public static void main(String[] args) {
        Cat cat =  new Cat();
        cat.foo((Integer) null);
    }
// ...
function log(x, y) {
  y = y || 'World';
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China

ES6 出来之后,原生支持函数的默认值:

function log(x, y = 'World') {
  y = y || 'World';
  console.log(x, y);
}

console.log('Hello') // Hello World
console.log('Hello', 'China') // Hello China

再回到 Java,目前是不能像 JavaScript 这样直接支持默认值的(或许也不需要这样),但可以通过重载依然曲线救国:

public class  Cat {
    public static void main(String[] args) {
        Cat cat =  new Cat();
        cat.meow(); // 默认参数是 "咪咪咪"
        cat.meow("喵喵喵");
    }

    public void meow() {
        meow("咪咪咪"); // 注意!这里传入的参数,就作为当前所在的没有参数的方法的默认参数
    }
    public void meow(String value) {
        System.out.println(value);
    }
}

6. 构造器的重载

构造器本质上也是一个方法,因此也能重载,并且也能曲线救国实现方法参数的默认值:

public class  Cat {
    int age;
    String name;
    
    public static void main(String[] args) {
        new Cat();
    }
    // 创建一只默认的猫,1岁,名叫小黑
    Cat() {
        this("小黑");
    }
    // 创建一只默认的猫,1岁,名叫name指定的名字
    Cat(String name2) {
        this(1, name2);
    }
    // 创建age和name指定的猫
    Cat(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

7. 对象的初始化

前面说了创建一个对象时:

具体初始化是有顺序的:

在以下代码中使用断点调试就可验证以上初始化流程:

public class Cat {
    static int count;  // 只在第一次new时初始化一次
    
    static {  // 只在第一次new时初始化一次
        for (int i = 0; i < 3; i++) {
            count += i;
        }
    }
    
    int age;  // 每次new一个对象实例时都会初始化
    String name;  // 每次new一个对象实例时都会初始化
    
    {
        for (int i = 0; i < 3; i++) {
            age += i;
        }
    }
    
    public Cat(int age, String name) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        new Cat(2, "wangpeng");
        new Cat(5, "xiaoqian");
    }
}

8. 对象的生命周期

看一个例子,占用尽可能多的内存,令JVM抛出内存不足 OutOfMemoryError 的异常:

public class Main {
    public static void main(String[] args) {
        Object[] array = new Object[10000];
        for (int i = 0; i < 10000; i++) {
            array[i] =  new byte[1024 * 1024];
        }
    }
}

. 数组—特殊的对象

上一篇 下一篇

猜你喜欢

热点阅读