文章目录
今天的内容不是很复杂,属于较为简单的一些知识总结,其中我尽量用比较通俗的文字来解释,若有需要交流的地方请留言哦我会第一时间回复
文章目录
前言
今天的主要内容是对1、Object对象中的 equals、getClass、hashCode、toString四个方法的使用,其中还会对 equals与 toString方法的标杆作用进行重写 2、对final关键字进行学习(对 修饰变量、方法、类做解释)3、抽象方法以及抽象类的使用和深入认识 4、接口的认识(有空我会单独进行详细解释)
提示:以下是本篇文章正文内容,下面案例可供参考
一、深入了解Object类
在刚开始学习Java的时候我们就说过Java是一门面向对象的语言所谓“万物皆对象”这句话就是它的标配,而在学习玩继承过后我们都知道子类需要继承父类时才会有继承关系,那么今天我们就来说说这个“Object”,它可以说是所有类的“父类”,也称超类,一直默默无闻地作为一个工具而存在的伟大父亲,以下的四个方法都是它特有的方法
(1)equals方法
equals 方法使我们之前所用过的,它是用于比较两个对象的内容是否一样,其返回类型为boolean类型
案例一、
package com.dream.test01;
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:Object
* 含义:所有类的基类/超类,一个类没有明确继承的类,默认继承Object
*
* equals:比较两个对象内存地址是否相同
* public boolean equals(Object obj){
* return this == obj;
* }
*/
Object obj1 = new Object();//0x001
Object obj2 = new Object();//0x002
boolean equals = obj1.equals(obj2);
System.out.println(equals);//false
//虽然 obj1与obj2都创建于同一个类 ,但是其分配的内存地址是不一样的所以是 false
}
}
(2)getClass方法
案例二、了解getClass方法 获取对象的字节码文件,每个源代码加载到JVM中后都会先导入.class文件
package com.dream.test01;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:Object
* 含义:所有类的基类/超类,一个类没有明确继承的类,默认继承Object
*
* equals:比较两个对象内存地址是否相同
* public boolean equals(Object obj){
* return this == obj;
* }
* getClass:获取该类的字节码文件对象
*/
Object obj1 = new Object();//0x001
Object obj2 = new Object();//0x002
Class<? extends Object> c1 = obj1.getClass();//获取obj1的字节码文件
Class<? extends Object> c2 = obj2.getClass();//获取obj2的字节码文件
//说明:由于 obj1与obj2都是创建于Object类,而在jvm加载的时候只会生成一个.class文件供
// 这两个对象使用,所以二者的.class文件内容是一样的
System.out.println(c1.equals(c2));//true
System.out.println(c1==c2);//true
}
}
//问题:为什么 “==” 与 equals 比较出来的结果都是 true?
//我们来看看equals底层代码
public boolean equals(Object obj) {
return (this == obj);
}
可以看到,在Object类型的equals方法是直接通过 == 来比较的,和 == 是没有任何区别的。
那么为什么又要说equlas和==的区别呢?是因为equals方法是可以由我们自己重写的。
(3)hashCode方法
package com.dream.test01;
public class Test04 {
public static void main(String[] args) {
/**
* 知识点:Object
* 含义:所有类的基类/超类,一个类没有明确继承的类,默认继承Object
*
* equals:比较两个对象内存地址是否相同
* public boolean equals(Object obj){
* return this == obj;
* }
* getClass:获取该类的字节码文件对象
* hashCode:获取对象的hash值
* hash值-系统利用对象的内存地址+散列算法获取的一个值
* 注意:hash值不等于内存地址
* toString:
*/
Object obj1 = new Object();
Object obj2 = new Object();
System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
}
}
(4)toString方法
含义:将所获取的内容转换成 “String”类型,之前在学习数组的时候有使用过一次,
案例如下:
package com.dream.test01;
public class Test05 {
public static void main(String[] args) {
/**
* 知识点:Object
* 含义:所有类的基类/超类,一个类没有明确继承的类,默认继承Object
*
* equals:比较两个对象内存地址是否相同
* public boolean equals(Object obj){
* return this == obj;
* }
* getClass:获取该类的字节码文件对象
*
* hashCode:获取对象的hash值
* hash值-系统利用对象的内存地址+散列算法获取的一个值
* 注意:hash值不等于内存地址
*
* toString:获取对象的字符串表示(将对象转换为字符串)
* public String toString(){
* return getClass().getName() + "@" + Integer.toHexString(hashCode());
* }
*/
Object obj1 = new Object();
System.out.println(obj1.toString());//java.lang.Object@15db9742
}
}
(5)"equals"与"toString"的标杆作用
通过案例来演示
package com.dream.test02;
public class MyString {
private String value;
public MyString(String value) {
this.value = value;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
MyString m = (MyString) obj;
//['a','b','c']
char[] v1 = this.value.toCharArray();//把当前对象的str转换为字符数组
//['a','b','c']
char[] v2 = m.value.toCharArray();//把当前对象的str转换为字符数组
if(v1.length != v2.length){
return false;
}
for (int i = 0; i < v2.length; i++) {
if(v1[i] != v2[i]){
return false;
}
}
return true;
}
@Override
public String toString() {
return value;
}
}
package com.dream.test02;
public class User {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
User user = (User) obj;
if(this.username.equals(user.username)){
return true;
}
return false;
}
@Override
public String toString() {
return username + " -- " + password;
}
}
package com.dream.test02;
public class Student {
private String name;
private char sex;
private int age;
private String classId;
private String id;
public Student() {
}
public Student(String name, char sex, int age, String classId, String id) {
this.name = name;
this.sex = sex;
this.age = age;
this.classId = classId;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
Student stu = (Student) obj;
if(this.classId.equals(stu.classId) && this.id.equals(stu.id)){
return true;
}
return false;
}
@Override
public String toString() {
return "name=" + name + ", sex=" + sex + ", age=" + age + ", classId=" + classId + ", id=" + id;
}
}
package com.dream.test02;
public class Test03 {
public static void main(String[] args) {
/**
* 知识点:String底层源码
*
* String的equals为什么可以判断字符串内容?
* 底层把String的内容转换为字符数组,依次比较ASCII码
*/
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//true - 比较两个字符串内容是否相同
System.out.println(str1);//默认调用toString
System.out.println(str2);//默认调用toString
System.out.println("--------------");
MyString m1 = new MyString("abc");
MyString m2 = new MyString("abc");
System.out.println(m1 == m2);//false
System.out.println(m1.equals(m2));
System.out.println(m1);
System.out.println(m2);
}
}
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:Object标杆作用
*
* equals:判断两个对象是否相同,Object不同的子类判断两个的对象是否相同有不同的判断规则,子类重写equals即可
* toString:返回对象的字符串表示,Object不同的子类有不同的属性,重写toString,返回属性
*/
User user1 = new User("1445584980", "123123");
User user2 = new User("1445584980", "123123");
System.out.println(user1.equals(user2));//true
System.out.println(user1);//默认调用toString
}
二、学习“final”关键字
认识final:“final” 代表着最终,被该关键字所修饰的变量为常量,修饰的方法无法被重写,修饰的类无法被继承
/**
* 知识点:final - 最终的
*
* 作用:
* 1.修饰变量 - 常量
* 存储在常量池中,直到项目结束才会被销毁
* 2.修饰类,类不能被继承
* 3.修饰方法,方法不能被重写
*/
案例展示
package com.dream.test03;
//A类不能有子类
//public final class A {
public class A {
//该方法不能被子类重写
public final void method(){}
}
三、抽象方法以及抽象类的使用和深入认识
何为抽象?
解释:在生活中我们常常都听说过“抽象”这一个词语,那么究竟什么叫作抽象呢?所谓抽象一句话就是“像又不像,似是而非,具有某一类的特征但是又不完全具备”,例如:我画了一个圆圈,我问你这像什么,它可以像盘子 也可以像太阳,但是却不完全像,之所以说它像盘子或太阳,那是因为它具有盘子或太阳的某一特征----即 都是圆形的。这就是抽象的解释
语法关键字:abstract---->抽象的
(1)抽象类
定义类的时候用“abstract”修饰的类
注意:
1、抽象类是无法被实例化的,只能由继承他的子类来完成相关操作
2、抽象类中的抽象方法没有方法体,由子类继承抽象类后强制性完成该抽象方法的方法体
3、有抽象方法的类一定是抽象类,而抽象类中的方法不一定全是抽象方法
(2)案例演示
package com.dream.test04;
//定义一个人类的抽象类
public abstract class Person {
private String name;
private char sex;
private int age;
public Person() {
}
public Person(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//抽象方法
public abstract void eat();
public void sleep(){
System.out.println(this.name + "睡觉觉");
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
package com.dream.test04;
//定义一个抽象的子类Chinese继承Person类,由于也是抽象类 可以不用完成person类中的抽象方法
public abstract class Chinese extends Person{
private String id;
public Chinese() {
}
public Chinese(String name, char sex, int age, String id) {
super(name, sex, age);
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
//抽象方法
public abstract void hobby();
@Override
public String toString() {
return "Chinese [id=" + id + ", toString()=" + super.toString() + "]";
}
}
package com.dream.test04;
//完成对父类Chinese的继承并完成其中的抽象方法eat();
public class SiChuan extends Chinese{
public SiChuan() {
}
public SiChuan(String name, char sex, int age, String id) {
super(name, sex, age, id);
}
@Override
public void hobby() {
System.out.println(super.getName() + "喜欢打麻将");
}
@Override
public void eat() {
System.out.println(super.getName() + "吃火锅");
}
@Override
public String toString() {
return "SiChuan [toString()=" + super.toString() + "]";
}
}