> 文档中心 > 关于在Java中对Object类的应用

关于在Java中对Object类的应用


关于对Object类的应用

一、对于Object类的概述及其作用

Object类是一个在Java之中内部所提供的一个系统类,在整个的程序设计与开发之中,Object类都有着非常重要的作用,他可以真正实现参数的统一

实际上在整个Java设计体系过程之中,几乎所有用户定义的类全部都是Object的子类(Object类是所有类的父类,包括系统类和用户自定义类),这样的概念就意味着以下的两种类定义的最终效果是完全相同的。

class Book{} class Book extends Object{}

既然所有的类都是Object类的子类,则意味着所有的类对象实例都可以通过Object利用自动上转型机制来进行接收。

范例:观察Object类与参数的统一

class Book {// Object子类public void read() {System.out.println("【Book】认真阅读图书。") ;}}public class Demo {public static void main(String args[]) {Object obj = new Book() ; // 向上转型if (obj instanceof Book) {// 如果要想调用子类的方法那么就必须向下转型Book book = (Book) obj ; // 向下转型book.read() ; // 子类扩充的方法}}}//程序执行结果:【Book】认真阅读图书。

本程序是采用了一个自定义的Book类和Object类之间产生了某些关联,但是String是一个系统内部提供的类,所以String类本身也是Object类的子类,那么就证明String类也可以自动向Object类自动向上转型。

范例:观察String类与Object类

public class Demo { public static void main(String args[]) {Object obj = "字符串abcde" ;// 字符串对象实例自动向上转型if (obj instanceof String) {// 判断obj是否为String的对象实例String message = (String) obj ; // 强制转型System.out.println(message.toUpperCase()) ; // String类定义的特殊方法}}}//程序执行结果:字符串ABCDE

在整个Java里面数据类型分为基本数据类型以及引用数据类型,那么所有的引用数据类型都可以通过Object类来接收,所以数组也可以使用Object类进行接收。

范例:观察数组与Object类

public class Demo {    public static void main(String args[]) {Object objA = new String[] {"字符串1", "字符串2", "字符串3"} ;print(objA) ; // 引用传递print(new int[] {10, 30, 50}) ; // 传递是整型数组 print("字符串类型");//不会输出}    public static void print(Object param) { //进行数组的输出,参数为Object类的数据,可以输入为任意引用数据类型, //方法体中可以根据不同的数据类型进行设计(instanceof), //这样设计的好处就是,参数中可以传入任意数据类型的数据, //即便是在方法体中没有设计的数据类型也不会出错。这样就实现了参数的统一。if (param instanceof String[]) {// 如果是字符串对象数组String [] array = (String []) param ; // 向下转型for (String temp : array) {System.out.print(temp + "、") ;}}if (param instanceof int[]) {// 判断是否为整型数组类型int [] array = (int []) param ; // 向下转型for (int temp : array) {System.out.print(temp + "、") ;}}System.out.println() ;}    }//程序运行结果://字符串1、字符串2、字符串3、//10、30、50、

在整个Java之中只要是引用数据类型,那么不管其是否有继承自Object父类,最终都可以自动向Object进行参数的向上转型,Object才是真正在实际开发过程之中最常见的公共的统一参数类型。

二、获取对象信息

任何类的实例化对象,如果直接进行输出的时候默认返回的信息实际上都是一个对象编码数据,之所以会返回这样的数据主要是由Object类中的toString()方法来决定的。

提示:关于Object类中的无参构造方法

如果按照类继承关系来讲,Object类中所有的方法都可以被子类所继承,就意味着只要是子类都可以使用Object类里面所提供的方法进行操作,在这些方法里面可以发现Object类会默认提供有一个无参构造,这个方法的主要目的是为了子类对象实例化的时候所保留的。

在这里插入图片描述

范例:观察一下toString()的使用

class Book { // 默认是Object子类}public class Demo {public static void main(String args[]) {System.out.println(new Book()) ; // 没有明确的调用toString()System.out.println(new Book().toString()) ; // 明确的调用了toString()}}/**程序执行结果:Book@2ffacdg0Book@9sdokja9**/

由于此时使用了两个关键字new,所以返回的对象编码信息一定是不同的,同时也可以清楚的发现不管是否调用了toString()方法,最终在执行的时候也都会自动的调用此方法将对象转为字符串后进行输出,可是默认情况下Object类中的toString()方法是不完善的,因为这个方法现在所给出的应该适用于所有的类对象,所有的类对象只有编码是公共的诉求,这样就可以得出结论:Object类中的toString()方法不怎么准确,如果子类有需要可以对此方法进行覆写。

范例:覆写toString()方法

class Book { // 默认是Object子类private String title ;private String author ;private double price ;public Book(String title, String author, double price) {this.title = title ;this.author = author ;this.price = price ;}public String toString() {return "【Book-" + super.toString() + "】图书名称:" + this.title + "、图书作者:" + this.author + "、图书价格:" + this.price ;}}public class Demo {public static void main(String args[]) {System.out.println(new Book("图书1", "李老师", 99.8)) ; // 没有明确的调用toString()}}/**程序执行结果:【Book-Book@6sjdki8】图书名称:图书1、图书作者:李老师、图书价格:99.8**/

其实现在所覆写的toString()方法就相当于代替了之前所明确定义的getInfo()方法,只不过getInfo()必须明确通过对象进行调用,而toString()可以自动调用。

在以后的使用Java的过程中,如果发现某一个对象输出的时候不会直接输出对象编码,那么此对象所对应的类中就一定成功进行了toString()方法的覆写。

三、对象比较

每一个的实例化对象并不像基本数据类型那样,可以直接利用内部提供的“==”运算符来实现相等比较,因为对象所保存的空间为堆内存,所以这样一来要想实现对象的比较最佳的做法就是将类之中的每一个属性进行依次判断。

范例:判断对象是否相同

class Book { // 默认是Object子类private String title ;private String author ;private double price ;public Book(String title, String author, double price) {this.title = title ;this.author = author ;this.price = price ;}public String toString() {return "【Book-" + super.toString() + "】图书名称:" + this.title + "、图书作者:" + this.author + "、图书价格:" + this.price ;}public String getTitle() {return this.title ;}public String getAuthor() {return this.author ;}public double getPrice() {return this.price ;}}public class Demo { public static void main(String args[]) {Book bookA = new Book("图书1", "李老师", 99.8) ;Book bookB = new Book("图书1", "李老师", 99.8) ;if (bookA.getTitle().equals(bookB.getTitle()) && bookA.getAuthor().equals(bookB.getAuthor()) &&bookA.getPrice() == bookB.getPrice()) {System.out.println("【√】当前两个对象的内容相等。") ;} else {System.out.println("【×】当前两个对象的内容不等。") ;}}}/**程序运行结果:【√】当前两个对象的内容相等。**/

虽然这个时候实现了两个对象的比较处理,可是却存在有一个非常严重的问题,所有比较的细节全部暴露在外部了,而在类设计的过程之中正确的比较的比较处理操作应该是一个类本身所具备的功能,所以应该将这个功能直接在类中定义(细节的比较处理应该在类中封装),这样Object类里面考虑到这种对象比较操作的常用性,所以它提供了一个对象比较的标准方法:

public boolean equals(Object obj)

equals()方法的名称我们实际上并不陌生,因为在String类对象的时候已经重点阐述过此方法了,下面为了更好的理解这个equals()方法的实现,我们来通过String类和Object类中的equals()方法定义和实现来进行区分。
在这里插入图片描述

在Object类之中由于需要保证equals()方法定义的完整,所以默认的比较形式采用的是地址数值“==”比较,但是发现在String类中它的比较相对来讲就繁琐了,但是这样的繁琐是有意义的,所以下面模拟String中的实现方式来在程序中定义属于自己的equals()对象的比较方法。

范例:实现对象比较

class Book { // 默认是Object子类private String title ;private String author ;private double price ;public Book(String title, String author, double price) {this.title = title ;this.author = author ;this.price = price ;}public String toString() {return "【Book-" + super.toString() + "】图书名称:" + this.title + "、图书作者:" + this.author + "、图书价格:" + this.price ;}    public boolean equals(Object obj) {// 方法覆写 if (this == obj) {// 两个对象的地址数值相同,也就是说两个对象为同一个对象时return true ; // 不再需要后续比较}  //如果没有此步骤,传入的对象如果是不是Book类,是其他引用类型的话,编译时不会出现错误,但执行时会报出ClassCastException的异常。if (!(obj instanceof Book)) {// 不是对象实例return false ; // 不再进行后续比较}Book book = (Book) obj ; // 传入的是一个Object类,使用子类属性和方法就必须向下转型return this.title.equals(book.title) && this.author.equals(book.author) && this.price == book.price ;}}public class Demo {public static void main(String args[]) {Book bookA = new Book("Java从入门到项目实战", "李兴华", 99.8) ;Book bookB = new Book("Java从入门到项目实战", "李兴华", 99.8) ;if (bookA.equals(bookB)) {System.out.println("【√】当前两个对象的内容相等。") ;} else {System.out.println("【×】当前两个对象的内容不等。") ;}  if (bookA.equals("字符串")) {System.out.println("【√】当前两个对象的内容相等。") ;} else {System.out.println("【×】当前两个对象的内容不等。") ;}  /** 此时,如果传入的是Null的话(什么也不传入),因为instanceof会直接判断null不属于任何对象的实例,所以会直接返回false。 **/ if (bookA.equals(null)) {System.out.println("【√】当前两个对象的内容相等。") ;} else {System.out.println("【×】当前两个对象的内容不等。") ;}}}/**程序执行结果:【√】当前两个对象的内容相等。【×】当前两个对象的内容不等。【×】当前两个对象的内容不等。**/

此时的程序实际上就相当于为大家解释了之前的String字符串的时候所说的概念:equals()方法可以自动的进行null判断。