导语
俗话说得好:万物皆对象。既然这样,你为什么没有对象呢。
主要内容
- Object类的作用
- Object类的常用方法
- Object类接收引用数据类型
具体内容
现在有对象、数组、接口,那么这么多数据怎么能够进行统一呢?于是就有了Object类的设计。
Object类的基本定义
Object类是所有类的父类,也就是说任何一个类的定义的时候如果没有明确的继承一个父类的话,那么它就是Object的子类,也就是说以下两种类的定义的最终效果是完全相同的。
class Book {
}
class Book extends Object {
}
在整个Java里面类的继承关系一直存在(除了Object类之外)。
既然Object是所有类的父类,那么最大的一个好处就在于:利用Object类可以接收全部类的对象,因为向上自动转型。
范例:利用Object类来接收对象
class Book extends Object {}
public class TestDemo {
public static void main(String args[]){
Object objA = new Book(); // 向上转型
Object objB = "hello"; // 向上转型
Book b = (Book) objA;
String s = (String) objB;
}
}
既然这样,如果在不确定参数类型的时候,使用Object类型应该是最好的选择。
问题:为什么在Object类里要定义一个无参构造方法呢?
既然Object类是所有类的父类 ,那么所有类的对象实例化的时候,了类构造方法一定要默认调用父类的无参构造。
从严格意义上来讲(一般不遵守),任何一个简单Java类都应该覆写Object类中的如下三个方法:
- 取得对象信息:public String toString()。
- 对象比较:public boolean equals(Object obj)。
- 取得对象HASH码:public hashCode()。
取得对象信息:toString()
如果说现在是一个String类对象,直接输出这个对象可以取得字符串的,但是如果是一个自定义的对象,那么发现就会出现一个对象编码。
范例:观察代码
class Book extends Object {}
public class TestDemo{
public static void main(String args[]) {
Book b = new Book();
String s = "Hello";
System.out.println(b);
System.out.println(b.toString());
System.out.println(s);
}
}
输出结果:
Book@659e0bfd
Book@659e0bfd
Hello
发现现在如果直接输出对象与调用toString()方法后输出对象的功能是完全一样的。
在进行对象输出的时候,输出操作会自动调用对象中的toString()方法,将对象变为字符串后再输出,而默认情况下Object类中的toString()为了适应所有对象的输出,所以只输出了对象的编码。
如果现在有需要,也可以自己根据实际情况来覆写此方法。
范例:覆写toString()方法
class Book {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
public String toString() {
return "书名:" + this.title + "价格:" + this.price;
}
}
public class TestDemo {
public static void main(String args[]){
Book b = new Book("Java开发", 79.8);
System.out.println(b);
System.out.println(b.toString());
}
}
输出结果:
书名:Java开发价格:79.8
书名:Java开发价格:79.8
直接输出对象就调用了toString(),等于输出对象的时候代码又节约了。
对象比较:equals();
对象比较在很多的开发中都是一定要使用到的核心概念。
范例:覆写equals()方法
class Book {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Book)) { // 如果不是本类实例返回false
return false;
}
Book book = (Book) obj;
if (this.title.equals(book.title)
&& this.price == book.price) {
return true;
}
return false;
}
public String toString() {
return "书名:" + this.title + "价格:" + this.price;
}
}
public class TestDemo {
public static void main(String args[]){
Book b1 = new Book("Java开发", 79.8);
Book b2 = new Book("Java开发", 79.8);
System.out.println(b1.equals(b2));
System.out.println(b1.equals("Hello"));
}
}
输出结果:
true
false
对象的比较操作写出以上的代码应该就算是完整了。
Object类可以接收一切引用数据类型
Object类是所有类的父类,所以Object类的对象可以接收所有类的对象,可是除了类的对象之外,Object类连数组和接口对象也都可以接收。
范例:接收数组数据
public class TestDemo {
public static void main(String args[]) {
Object obj = new int [] {1, 2, 3}; // 向上转型
System.out.println(obj);
if (obj instanceof int[]) {
int data [] = (int[]) obj;
for (int i = 0; i < data.length; i++) {
System.out.println(data[i]);
}
}
}
}
输出结果:
[I@659e0bfd
1
2
3
除了数组外,接口也同样可以。
范例:接收接口对象
interface A {
public void fun();
}
class B implements A {
public void fun() {
System.out.println("Hello World !");
}
}
public class TestDemo {
public static void main(String args[]) {
A a = new B(); // 接口对象
Object obj = a; // 接收接口对象
A t = (A) obj;
t.fun();
}
}
输出结果:
Hello World !
整个程序的参数就统一在Object类型上。
总结
- Object类对象可以接收一切的数据类型(引用数据类型),包括数组和接口,解决数据统一问题。
- toString()在对象直接输出时调用,equals()在对象比较时调用。