大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。
当前系列: J&C 修改讲义

演示:

  • 一个“空”对象Student,能够调出一些他“没有”的方法,比如:equals()
  • 转到定义,发现Object


Object

Object是Java/C#中所有类型的父类,可以说它是万物之祖(万物皆对象)

因此,任何类默认自动的继承自Object,不需要显式声明。所有类都可以通过继承获得Object的方法属性等。

@想一想@:这样写法OK么?为什么?

Object lang = new Student();

这一章节我们学习以下几个方法:


hash值

hashCode()/GetHashCode():获取对象的哈希(复习)值:

  • 两个完全相同的对象GetHashCode()的Hash值必然相同。
  • 但是,相同的Hash值并不意味着生成他们的对象相同!

所以,我们可以用GetHashCode()确定两个对象不相同,但不能用于确定他们相同。

@想一想@:当我们说“相同”的时候,我们在说什么“相同”?

  • 两个变量指向的对象完全相同:(按文档:hash值是通过对象地址进行运算的
    Student lang = new Student();
    Student atai = lang;
  • 两个对象类成员的值完全相同:
    Student lang = new Student();
    lang.Name = "浪神";
    Student atai = new Student();
    atai.Name = "浪神";

@想一想@:为什么需要对象的hashCode呢?

PS:native标记的方法,不是由Java语言实现的。


比较:equals()

object还提供了equals()/Equals()方法,用于比较作为参数传入的两个对象是否相等,即两个变量是否指向同一个对象。

演示:转到定义

    public boolean equals(Object obj) {
        return (this == obj);
    }
和==的区别,就是当出现null值时:
Student lang = null;
Student atai = null;

System.out.println(lang == atai);    //true
System.out.println(lang.equals(atai));    //报异常,@想一想@:为什么?


override

你可能会觉得:有==不是就够用了么?干嘛要用equals()方法?

因为方法才可以override呀!有时候我们可能需要建立自己的规则来比较两个对象:比如两个Student,姓名(+生日+班级,或者身份证号)相同,就是同一个人。

public boolean equals(Object obj) {
	return Name == ((Student)obj).Name;
}

但是注意:equals和hashCode()要同时override,确保两者的值一样。(为什么后面详述)

F3演示:Integer类override了equals()和hashCode()

System.out.println(new Integer(100).equals(new Integer(100)));
System.out.println(new Integer(100).hashCode() == (new Integer(100)).hashCode());


ToString()

将对象转换成字符串:Java:toString() / C#:ToString()

@猜一猜@:

System.out.println(new Student());

结果是什么?演示:转到定义

为什么需要toString()?原因和hashCode()/equals()一样:

  • Java包自己内部需要,如上所示
  • 给我们一个override的机会,比如Float中就重写了toString()
        System.out.println(3.14F);
        System.out.println(new Float(3.14).toString());


装箱和拆箱

我们来看这样几行代码:

Object wx = new Student();    //把new Student()的堆地址存到wx变量中
int i = 888;                  //把值888直接存放到变量i中
Object o = 986;               //把986存到哪里?

注意最后一行代码,986能不能直接放到变量o里面?

这是不行的,因为o是Object引用类型的,o里面只能存放一个堆地址。但是Object o =986;又是符合语法的,这种把值类型数据直接赋值给Object变量的行为,被称之为装箱(box)。具体来说,这一行代码做了两件事:

  • 自动生成一个Object对象(相当于new object())
  • 将整数值986存入这个Object对象(这个过程就是装箱的核心过程)
  • 将Object对象的堆地址赋值给o变量

写成伪代码就是:

Object o = new Object();
o.inbox = 986;         //inbox是我随手写的,代指“箱子内部”

C#中可以用&运算符查看

既然能够装箱,当然也能够拆箱(unbox)

int i = (int)o;


#常见面试题#

装箱拆箱和

  • 隐式/显式类型转换
    int i = 10;
    float f = i;		
    int fi = (int)f;
  • 父类变量装子类对象
    Person plang = new Student();
    Student slang = (Student)plang;
有啥区别?

正面回答:

  • 装箱和拆箱仅适用于值类型和Object之间;
  • 装箱和拆箱多了一个创建Object实例的过程;

另外两种转换都没有这种过程的。


作业

  1. 通过阅读源代码,说一说Java/C#是如何比较两个String类型对象的。
  2. 声明一个Article类(如果还没有的话),包含两个属性:Title和Body,重写equals()方法:只要两个对象Title和Body都相等,返回true;否则,false。
  3. 调整Article的代码,使得当控制台输出一个Article对象的时候,输出的是它的标题和内容。
  4. 构造一个能装任何数据的数组,并完成数据的读写
  5. 使用object改造数据结构栈(MimicStack),并在出栈时获得出栈元素
学习笔记
源栈学历
今天学习不努力,明天努力找工作

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 J&C 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码