首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第一章:OOP:继承
第二章:关键字 super
第三章:关键字 static
第四章:成员变量初始化
第五章:OOP:多态
第六章:关键字 native
第七章:关键字 final
第八章:Object 类的使用
第九章:抽象类
第十章:接口
第十一章:经典接口介绍
第十二章:包装类
第十三章:内部类
当前位置:
首页>>
技术小册>>
Java语言基础6-面向对象高级
小册名称:Java语言基础6-面向对象高级
8.1 概述 - 在 Java 中,Object 类是所有类的根父类。 - 在 Java 中,如果在类的声明处没有显示的用 extends 关键字指明其父类,则默认父类为 java.lang.Object 类。 8.2 toString()方法 - 方法: ```bash public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } ``` 解释: ① 默认情况下,toString() 方法的返回值是 对象时类型 @ 对象的hashCode值的十六进制 。 ② 通常建议子类重写 toString() 方法。 ③ 如果我们直接使用 System.out.println(对象); 输出语句,默认会自动调用该对象的 toString() 方法。 Java 的引用数据类型的变量中实际存储的是对象的内存地址,但是 Java 对程序员隐藏了内存的地址信息,所以不能直接将内存地址显示出来,所以当我们打印对象的时候,JVM 会帮助我们调用对象的 toString() 方法。 示例: ```bash package com.github.objectdemo.demo1; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Person { /** * 姓名 */ private String name; /** * 年龄 */ private int age; /** * 身高 */ private double height; public Person() {} public Person(String name, int age, double height) { this.name = name; this.age = age; this.height = height; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } public double getHeight() { return this.height; } public void setHeight(double height) { this.height = height; } @Override public String toString() { return "Person{" + "name='" + this.name + '\'' + ", age=" + this.age + ", height=" + this.height + '}'; } } ``` ```bash package com.github.objectdemo.demo1; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Test { public static void main(String[] args) { Person person = new Person("李白", 18, 1.8); System.out.println(person); String info = person.toString(); System.out.println(info); } } ``` ```bash 运行结果: Person{name='李白', age=18, height=1.8} Person{name='李白', age=18, height=1.8} ``` 8.3 getClass() 方法 - 方法: ```bash public final native Class<?> getClass(); ``` - 解释: - ① 该方法返回对象的运行时类型。 - ② 因为 Java 有多态特性,所以一个引用类型的变量的编译时类型和运行时类型可能不一样,所以如果需要查看一个引用类型变量实际指向对象的类型,就需要此方法了。 - 示例: ```bash package com.github.objectdemo.demo2; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Animal { public void eat() { System.out.println("吃饭"); } } ``` ```bash package com.github.objectdemo.demo2; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } } ``` ```bash package com.github.objectdemo.demo2; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Dog extends Animal { @Override public void eat() { System.out.println("狗吃肉"); } } ``` ```bash package com.github.objectdemo.demo2; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Test { public static void main(String[] args) { Animal animal = new Dog(); System.out.println("animal.getClass() = " + animal.getClass()); // class com.github.objectdemo.demo2.Dog } } ``` 8.4 finalize() 方法 - 方法: ```bash protected void finalize() throws Throwable { } ``` - 解释: - ① 当对象被 GC 确定为要被回收的垃圾,在回收之前由 GC 帮你调用这个方法,不是由程序员手动调用。 - ② 这个方法与 C 语言的析构函数不同,C 语言的析构函数被调用,那么对象一定被销毁,内存被回收,而 finalize 方法的调用不一定会销毁当前对象,因为可能在 finalize() 中出现了让当前对象“复活”的代码。 - ③ 每一个对象的 finalize 方法只会被调用一次。 - ④ 子类可以选择重写,一般用于彻底释放一些资源对象,而且这些资源对象往往时通过 C/C++ 等代码申请的资源内存。 - 示例: ```bash package com.github.objectdemo.demo3; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Animal { private String name; @Override protected void finalize() throws Throwable { System.out.println("要挂了,要挂了"); } public String getName() { return this.name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Animal{" + "name='" + this.name + '\'' + '}'; } } ``` 8.5 hashCode() 方法 - 方法: ```bash public native int hashCode(); ``` - 解释: - ① 返回当前对象的 hash 值。 - ② hashCode 的常规规定: - 如果两个对象的 hash 值是不同的,那么这两个对象一定不相等; - 如果两个对象的 hash 值是相同的,那么这两个对象不一定相等。 - ③ 实际开发中,经常重写 hashCod()方法 ,尽量让不同的对象产生的 hashCode 是不同的。 - 示例: ```bash package com.github.objectdemo.demo4; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Animal { private String name; public String getName() { return this.name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Animal{" + "name='" + this.name + '\'' + '}'; } } ``` ```bash package com.github.objectdemo.demo4; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Test { public static void main(String[] args) { Animal a1 = new Animal(); int hashCode = a1.hashCode(); System.out.println(hashCode); // 356573597 System.out.println("Aa".hashCode()); // 2112 System.out.println("BB".hashCode()); // 2112 } } ``` 8.6 equals()方法 方法: ```bash public boolean equals(Object obj) { return (this == obj); } ``` - 解释: - ① 用于判断当前对象 this 和指定对象 obj 是否 相等 。 - ② 默认情况下,equals() 方法和 == 一样,比较的是对象的地址值。 - ③ 实际开发中,我们需要进行重写,要求如下: - 如果重写 equals() ,那么一定要重写 hashCode() 方法,因为规定: - 如果两个对象调用 equals 返回 true ,那么要求这两个对象的 hashCode 值一定是相等的。 - 如果两个对象的 hashCode 值不同的,那么要求这个两个对象调用 equals 方法一定是 false 。 - 如果两个对象的 hashCode 值相同的,那么这个两个对象调用 equals 可能是 true ,也可能是 false 。 - 如果重写 equals() ,那么一定要遵循如下几个原则: - 自反性:x.equals(x) 返回 true 。 - 传递性:x.equals(y) 为 true ,y.equals(z) 为 true ,然后 x.equals(z) 也应该为 true 。 - 一致性:只要参与 equals 比较的属性值没有修改,那么无论何时调用结果应该一致。 - 对称性:x.equals(y) 与 y.equals(x) 结果应该一样。 - 非空对象与null 的 equals 一定是 false 。 - 示例: ```bash package com.github.objectdemo.demo5; import java.util.Objects; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Person { private String name; private int age; private char gender; public Person() {} public Person(String name, int age, char gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } public char getGender() { return this.gender; } public void setGender(char gender) { this.gender = gender; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || this.getClass() != o.getClass()) { return false; } Person person = (Person)o; return this.age == person.age && this.gender == person.gender && Objects.equals(this.name, person.name); } @Override public int hashCode() { return Objects.hash(this.name, this.age, this.gender); } @Override public String toString() { return "Person{" + "name='" + this.name + '\'' + ", age=" + this.age + ", gender=" + this.gender + '}'; } } ``` ```bash package com.github.objectdemo.demo5; /** * @author maxiaoke.com * @version 1.0 * @return */ public class Test { public static void main(String[] args) { Person p1 = new Person("张三", 25, '男'); Person p2 = new Person("张三", 25, '男'); System.out.println("p1.equals(p2) = " + p1.equals(p2)); // true } } ```
上一篇:
第七章:关键字 final
下一篇:
第九章:抽象类
该分类下的相关小册推荐:
Java语言基础9-常用API和常见算法
Java面试指南
Java并发编程实战
Java语言基础7-Java中的异常
手把手带你学习SpringBoot-零基础到实战
Mybatis合辑3-Mybatis动态SQL
Java并发编程
Mybatis合辑5-注解、扩展、SQL构建
Java语言基础12-网络编程
Java语言基础15-单元测试和日志技术
Java语言基础5-面向对象初级
Java高并发秒杀入门与实战