java.lang.Object()、toString()、equals()、hashCode()、重写以及多态
提示:以下是本篇文章正文内容,下面案例可供参考
在 Java 中, Object
类是所有类的父类,也就是说 Java 的所有类都继承了 Object
,子类可以使用 Object
的所有方法。
Object 类是在 java.lang
包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object
,成为 Object
的子类。
Object
类可以 显式继承 ,也可以 隐式继承 :
显式继承
隐式继承:
toString()
方法toString()
一个 public
(公共的)修饰的一个方法,在 java.lang.Object
类中。
用来获得指定实例(对象)的描述信息(即用一个字符串描述一个实例)。
Returns a string representation of the object.
API Note:
In general, the method returns a string that “textually represents” this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The string output is not necessarily stable over time or across JVM invocations.
toString
Implementation Requirements:
The method for class returns a string consisting of the name of the class of which the object is an instance, the at-sign character `', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
toStringObject@
getClass().getName() + '@' + Integer.toHexString(hashCode())
其返回类型为 String类型 ,是由其实例的名称 + @ + 对象的哈希码(无符号)的十六进制组成。
运行结果:
打印的结果为: 包名 + 类名 @ 对象的哈希码
toString()
方法对 toString()
未进行重写时,调用其方法时,打印出来的结果是一个由 包名 + 类名 @ 对象的哈希码 ,于是我们对 toString()
方法进行重写:
@Override
public String toString() {
return "Food{" + kind +"}";
}
不可修改重写方法的名称,参数类型,参数顺序,以及返回类型。所以依旧为返回一个字符串,只是修改为:"Food{" + kind +"}"
。所以打印结果为:
代码:
System.out.println( 实例名称 )
在 toString()
方法没有重写时,打印为 包名 + 类名 @ 对象的哈希码 。但当 toString()
方法重写后,打印的就为 toString()
重写后返回的内容了。所以直接打印实例名称和 toString()
方法显示的内容一样。
equals()
一个 public
(公共的)修饰的一个方法,在 java.lang.Object
类中。
用来判断两个实例是否 “相等”,在没有重写之前,该方法是比较两个实例的地址。
public boolean equals(Object obj)
Indicates whether some other object is “equal to” this one.
The
equals
method implements an equivalence relation on non-null object references:
- It is reflexive: for any non-null reference value
x
,x.equals(x)
should returntrue
.- It is symmetric: for any non-null reference values
x
andy
,x.equals(y)
should returntrue
if and only ify.equals(x)
returnstrue
.- It is transitive: for any non-null reference values
x
,y
, andz
, ifx.equals(y)
returnstrue
andy.equals(z)
returnstrue
, thenx.equals(z)
should returntrue
.- It is consistent: for any non-null reference values
x
andy
, multiple invocations ofx.equals(y)
consistently returntrue
or consistently returnfalse
, provided no information used inequals
comparisons on the objects is modified.- For any non-null reference value
x
,x.equals(null)
should returnfalse
.An equivalence relation partitions the elements it operates on into equivalence classes; all the members of an equivalence class are equal to each other. Members of an equivalence class are substitutable for each other, at least for some purposes.
API Note:
It is generally necessary to override the
hashCode
method whenever this method is overridden, so as to maintain the general contract for thehashCode
method, which states that equal objects must have equal hash codes.Implementation Requirements:
The
equals
method for classObject
implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference valuesx
andy
, this method returnstrue
if and only ifx
andy
refer to the same object (x == y
has the valuetrue
). In other words, under the reference equality equivalence relation, each equivalence class only has a single element.Parameters:
obj
- the reference object with which to compare.Returns:
true
if this object is the same as the obj argument;false
otherwise.See Also:
hashCode()
[HashMap
](
public boolean equals(Object obj) {
return (this == obj);
}
x.equals(x)
应该返回 true。y.equals(x)
返回 true 时,x.equals(y)
才应该返回 true。x.equals(y)
返回 true 并且 y.equals(z)
返回 true,则 x.equals(z)
应该返回 true。x.equals(y)
的多次调用始终返回 true 或始终返回 false。(前提是没有修改对象上 equals 比较中使用的信息。)equals()
方法因为没有对equals()
方法进行重写前,该方法是比较两个实例的地址。
比较下列两个整数数组:
int[] list_1 = {1 , 2 , 3 , 4 , 5 , 6};
int[] list_2 = {1 , 2 , 3 , 4 , 5 , 6};
Array a = new Array();
a.setArray(list_1);
System.out.println(a.equals(list_2));
我们发现打印结果竟然为false:
我们打印这两个数组的地址发现,虽然这两个数组的内容,类型都一致,但他们的地址不同,所以通过 equals()
方法进行比较时,就会输出false的结果。
我们将equals()
方法重写,将其变成比较变量中值是否 ”相等“ ,而不再是比较地址。
@Override
public boolean equals(Object o) {
if (this == o){ //判断传入参数(o)是否是要比较的实例(this)
return true;
}
if (o == null || getClass() != o.getClass()){ //判断传入参数(o)是否为空
return false;
}
Array array = (Array) o;
return num == array.num;
}
则运行结果为:
hashCode()
方法hashCode()
一个 public
(公共的)修饰的一个方法,在 java.lang.Object
类中。
用于获得指定实例(对象)的哈希值。
public int hashCode()
Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by
HashMap
.The general contract of
hashCode
is:
Whenever it is invoked on the same object more than once during an execution of a Java application, the
hashCode
method must consistently return the same integer, provided no information used inequals
comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.If two objects are equal according to the
equals
method, then calling thehashCode
method on each of the two objects must produce the same integer result.It is not required that if two objects are unequal according to the
equals
method, then calling thehashCode
method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.Implementation Requirements:
As far as is reasonably practical, the
hashCode
method defined by classObject
returns distinct integers for distinct objects.
hashCode()
方法当重写equals()
方法后,要将hashCode()
方法重写,否则hashCode()
方法返回的值依旧为原来的值,所以重写后:
@Override
public int hashCode() {
return Objects.hash(num);
}
hashCode()
方法时为何乘以31因为31是一个奇素数,这样既可以避免乘法溢出,有做到最大限制避免 ”Hash冲突“。可以将 31 * i 转化为 (i << 5)- i,就能更好观察到。
为子类 重写 父类中的方法。
当子类重新定义从父类中继承的 同名,同参,同返回(返回修饰符范围不可以比父类小) 的方法是,则称子类中的方法 覆盖(重写) 的同名方法。
@Override
在 Java 中 ,@Override 注解是用来指定方法重写的,只能修饰方法并且只能用于方法重写,不能修饰其它的元素。用来避免重写时出错。
当书写错误后,@Override 的作用是告诉编译器检查这个方法,保证父类要包含一个被该方法重写的方法,否则就会编译出错。这样可以帮助程序员避免一些低级错误。
instanceof
(比较是否为某引用类型)if( another instanceof People){
People x = (People) another;
}
第二行对实例 another 进行强行转换是因为在栈中开辟了一个People类型的x,将another的值赋给x。
但还有一种说法,是instanceof
会在比较的时候将People类型的的父类也判定为 ”同一种类型“ ,所以在之后强转,实际上是是将类型向下赋值。
即为多种形态。
*** 编译时多态***:在编译阶段,同一个类中多个 同名不同参的方法,就是多态。(方法重载就是编译时多态)。
声明变量所指定的类型决定了可通过该变量访问那些字段和方法。
定义引用变量时为引用变量指定的类型被称为 编译时类型