第四章、Java面向对象(六)
本人也是刚入门Java语言,可能会有一些地方出现错误,描述的不对。如果发现不对的地方请及时指出,好对其进行修改。这样不仅可以让我学到东西,也可以让其他刚入门的朋友学习更正确的内容。
所有内容仅供参考。不具有完全的准确性!
注:关于Java的所有内容都会参考到尚硅谷在网上公开的学习视频及其提供的PPT
一、instanceof 操作符
在多态的时候提到了向上转型,向上转型是将父类类型的引用指向子类对象,这种也可以称为自动转换,是没问题的。但在我们编写代码的时候,免不了会出现将子类类型的引用指向父类对象,这种情况就是向下转型,也称为强制转换。
在基本数据类型的时候提到过类型转换,我们说强制类型转换会出现数据溢出,精确度不够等问题。此处类似,也会出现一些无法避免的问题。
为了避免这种情况的出现,我们可以通过instanceof操作符来处理。
- instanceof语法格式
x instanceof A
检验 x 是否属于类A的对象,返回值为布尔型。
要求:
- x所属的类与类A必须是子类和父类的关系,否则编译错误
- 如果x属于类A的子类B(间接父类也可以),x instanceof A值也为true。
如:
//前提:Student继承了Person类
Person p = new Student();
if(p instanceof Person){
System.out.println("属于Person类");
}
更详细的可以参考:https://www.cnblogs.com/lifexy/p/10812841.html
二、Object类的使用
- Object类是所有类的根父类(所有类都可以使用Object类中提供的方法和属性)
- 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
例:
public class Person{
}
等价于
public class Person extends Object{
}
- 当Object作为形参或者变量类型时,可以接受任何类型的数据。
三、== 操作符 和 equals方法
(一) == 操作符
可以使用在基本数据类型变量和引用数据类型变量中
- 基本数据类型比较值:判断两个变量保存的数据是否相等,相同返回true。
- 引用数据类型比较引用:比较两个变量的地址值是否相等,相同返回true。
注意:
用“==”进行比较时,符号两边的数据类型必须兼容(可自动转换的基本数据类型除外),否则编译出错
int a = 6;
int b = 6;
System.out.println(a == b);//true
double d = 6.0;
System.out.println(a == d);
String s = "r";
// System.out.println(a == s);//编译报错
String t = "r";
System.out.println(s == t);
String r = new String("r");
System.out.println(s == r);
输出结果:
true
true
true
false
最后一个返回false的原因:因为变量 r 是通过new创建的对象,通过new创建的对象在内存结构中是存放在堆空间中,而变量 s 是存放在常量池中的,地址值必然是不同的。所以返回false
(二)equals方法
是一个方法,而非运算符
- 只是用于引用数据类型。
- equals()方法声明在Object类中,又因所有类都继承自Object类,所以所有类都可以调用equals()方法。还可以对该方法进行重写。
- Object类中定义的equals()方法
public boolean equals(Object obj) {
return (this == obj);
}
- 说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
- 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
- 通常情况下,当我们自定义类需要用到equals()方法的时候,都需要对equals()方法进行重写。用来更好的比较两个对象的具体内容是否相同。
重写的原则:比较两个对象的实体内容是否相同.
例:
String类中重写的equals()方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (!COMPACT_STRINGS || this.coder == aString.coder) {
return StringLatin1.equals(value, aString.value);
}
}
return false;
}
(三) ==操作符 和equals()方法的区别
- == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址。
- equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是==。
- 具体要看自定义类里有没有重写Object的equals方法来判断。
- 通常情况下,重写equals方法,会比较类中的相应属性是否都相等。
四、toString()方法的使用
- 当我们输出一个对象的引用时,实际上就是调用当前对象的toString()。如果该对象的类中没有重写toString(),则默认调用Object类中的toString()
- Object类中的toSting()的定义
如果输出的引用调用的是Object类中的toString(),则最后输出的结果将是一个类名和其地址值
public String toString() {
//getClass().getName()获取调用对象的类名
//通过hashCode()计算出在堆空间中的存储位置并通过toHexString转为十六进制
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
-
像String、Date、File、包装类等都重写了Object类中的toString(),使得在调用对象的toString()时,返回的是具体内容("实体内容"信息)
-
在进行String与其它类型数据的连接操作时,自动调用toString()方法
Date now=new Date();
System.out.println(“now=”+now); 相当于
System.out.println(“now=”+now.toString()); -
可以根据需要在用户自定义类型中重写toString()方法如String 类重写了toString()方法,返回字符串的值。
String s1=“hello”;
System.out.println(s1);//相当于System.out.println(s1.toString()); -
基本类型数据转换为String类型时,调用了对应包装类的toString()方法
int a=10; System.out.println(“a=”+a);
五、包装类的使用
- 针对八个基本数据类型定义了一 一对应的引用类型——包装类(封装类)
- 使得基本数据类型有了类的特点,就可以调用类中的方法,Java才是真正的面向对象
- 基本数据类型包装成包装类的实例 —>装箱
int a = 10;
Integer i = new Integer(a);
也可以直接声明为包装类对象
Double d = new Double("12.5");
Boolean b = new Boolean("true");
- 包装类转换成基本数据类型 —>拆箱
调用包装类的xxxValue()
Integer in1 = new Integer(12);
int i = in1.intValue(); //此时in1就转成了基本数据类型,没有类的特征
在JDK5.0以后就出现了自动装箱和自动拆箱,我们不需要写装箱和拆箱的步骤(类型必须匹配)
public void method(Object obj){
System.out.println(obj);
}
public void test(){
int i = 10;
//在 5.0 之前,这样写是错误, 因为 i 是基本数据类型,而method的形参是Object类类型
//5.0之后,有了自动装箱就可以这样写了
method(i);// 完整代码:Integer in = new Integer(i); method(in);
//自动装箱:基本数据类型-->包装类
int j = 128;
Integer in2 = j; //正常来说,一个int型是不能直接赋给类类型的。有了自动装箱就可以了
Integer in3 = j;
System.out.println(in2); //128
System.out.println(in2 == in3); //false
//自动拆箱:包装类-->基本数据类型
int k = in2; //自动拆箱发完成 完整代码:int k = in2.intValue();
}
- 字符串转换成基本数据类型
//通过包装类的构造器实现:
String s = "12";
int i = new Integer(s);
//或
int i = new Integer("12");
//通过包装类的parseXxx(String s)静态方法:
Float f = Float.parseFloat("12.1");
- 基本数据类型转换成字符串
//调用字符串重载的valueOf()方法:
String fstr = String.valueOf(2.34f);
//更直接的方式:
String intStr = 5 + "";
//注意
int num1 = 10;
String str = num1; //此时是错的,不可以直接将int赋给String
注意:包装类不可以做运算,需要转换成基本数据类型