Java Obiect类--------11

一、Object类

1.1含义

所有类的基类/超类,一个类没有明确继承的父类,都默认继承Object

1.2 euqals()

判断两个对象内存地址是否相同
public boolean equals(Object obj){
        return (this == obj);

package com.qf.test01;

public class A {
	
	private String str;
	private char c;
	private int i;
	
	public A() {
	}

	public A(String str, char c, int i) {
		this.str = str;
		this.c = c;
		this.i = i;
	}

	public String getStr() {
		return str;
	}

	public void setStr(String str) {
		this.str = str;
	}

	public char getC() {
		return c;
	}

	public void setC(char c) {
		this.c = c;
	}

	public int getI() {
		return i;
	}

	public void setI(int i) {
		this.i = i;
	}
}
package com.qf.test01;

public class Test01 {

	public static void main(String[] args) {
		
		A a1 = new A();
		A a2 = new A();
		System.out.println(a1 == a2);//引用数据类型使用==是比较内存地址是否相等
		System.out.println(a1.equals(a2));
		
		int a = 100;
		int b = 200;
		System.out.println( a == b);//基本数据类型使用==是比较值是否相等
	}
}

1.3 getClass()

获取该类的class对象(class对象作为class文件的访问入口) 

package com.qf.test01;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test02 {

	public static void main(String[] args) {

		A a1 = new A();
		A a2 = new A();
		
		Class c1 = a1.getClass();//获取A类的class对象
		Class c2 = a2.getClass();//获取A类的class对象
		
		System.out.println(c1 == c2);//true
		
		System.out.println("----------");
		
		//获取该类所有的属性
		Field[] fields = c1.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(field);
		}
		
		System.out.println("----------");
		
		//获取该类所有的构造方法
		Constructor[] constructors = c1.getDeclaredConstructors();
		for (Constructor constructor : constructors) {
			System.out.println(constructor);
		}
		
		System.out.println("----------");
		
		//获取该类所有的方法
		Method[] methods = c1.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
	}
}

 1.4 hashCode()

获取到对象的hash值(hash值 - 内存地址+散列算法,hash值不等于内存地址) 

package com.qf.test01;

public class Test03 {

	public static void main(String[] args) {
		
		A a1 = new A();
		A a2 = new A();
		
		System.out.println(a1.hashCode());   //获取a1的哈希值
		System.out.println(a2.hashCode());   //获取a1的哈希值
	}
}

 1.5 toString()

获取对象的字符串形式(将对象转换为字符串) 

public String toString(){
        //getClass().getName() - 获取class对象的名字(类的全路径-报名+类名)
        //Integer.toHexString(hashCode()) - 获取对象的hash值的十六进制表示(hash值原本是十进制)
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

package com.qf.test01;

public class Test04 {

	public static void main(String[] args) {
		
		A a1 = new A();
		
		//com.qf.test01.A @ 15db9742
		System.out.println(a1);//打印对象,默认调用toString()
		System.out.println(a1.toString());
	}
}

 二、深入Object的标杆作用

2.1前言 

所有的类都直接或间接继承Object,所以所有的类都能使用Object里的方法 

2.2Object - equals():

含义:比较两个对象的内存地址是否相同
标杆作用:比较两个对象是否相同,但是不同的子类判断两个对象是否相同规则是不一样的,所以在子类中重写equals方法即可 

package com.qf.test02;

public class User {
	
	private String username;
	private String password;
	private double money;
	
	public User() {
	}

	public User(String username, String password, double money) {
		this.username = username;
		this.password = password;
		this.money = money;
	}

	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;
	}

	public double getMoney() {
		return money;
	}

	public void setMoney(double money) {
		this.money = money;
	}
	
	@Override
	public boolean equals(Object obj) {
		//先判断两个对象的地址是否相同,地址都相同,证明是同一个对象
		if(this == obj){
			return true;
		}
		
		//判断两个用户对象的账号是否相同
		User user = (User) obj;//父类转子类:向下转型
		if(this.username.equals(user.username)){//equals-是String类重写Object类的equals方法(表示比较两个字符串内容是否相同)
			return true;
		}
		
		return false;
	}
	
	@Override
	public String toString() {
		return this.username + " -- " + this.password + " -- " + this.money;
	}
}

 2.3Objec - toString():

含义:获取对象的字符串表示 -- getClass().getName() + "@" + Integer.toHexString(hashCode());


标杆作用:获取对象的字符串表示,但是不同的子类有不同的属性(数据),所以在子类中重写toString方法即可
目的:打印对象,输出对象中所有的属性,方便查看数据 

2.4需求 

需求1:模拟银行用户 

package com.qf.test02;

public class Test01 {

	public static void main(String[] args) {
		
		User user1 = new User("1445584980", "123123", 1000);
		User user2 = new User("1445584980", "123123", 1000);
		
		System.out.println(user1.equals(user2));//true
		
		System.out.println(user1);//默认调用toString
		System.out.println(user2);//默认调用toString
}

需求2:默认学生用户

package com.qf.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 "Student [name=" + name + ", sex=" + sex + ", age=" + age + ", classId=" + classId + ", id=" + id + "]";
	}
	
}
package com.qf.test02;

public class Test01 {

	public static void main(String[] args) {
	
		Student stu1 = new Student("李伟杰", '男', 18, "2204", "001");
		Student stu2 = new Student("李伟杰", '男', 18, "2204", "001");
	
		System.out.println(stu1.equals(stu2));//true
		
		System.out.println(stu1);//默认调用toString
		System.out.println(stu2);//默认调用toString
	}
}

三、深入String的底层原理

3.1知识点 

注意:String-字符串,底层使用字符数组存储数据 

3.2String 的equals判断思路(比较的是字符串内容): 

1.先判断内存地址
1.1 内存地址相同 -- 返回 true
1.2 内存地址不相同     
2.获取对象的字符数组,判断长度是否一致
2.1 长度不一致 -- 返回false
2.2 长度一致
3.循环遍历字符数组,比较ASCII码
3.1 ASCII不相同 -- 返回false
3.2 遍历后,所有的ASCII都相同 -- 返回true

package com.qf.test03;

public class MyString {

	private char[] value;//字符串底层容器
	
	public MyString(String original){
		value = original.toCharArray();//将字符串转换为字符数组,再赋值给value
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj){
			return true;
		}
		
		MyString m = (MyString) obj;//Test01类中的m2
		
		char[] v1 = this.value;//m1中的char[] -- ['a','b','c']
		char[] v2 = m.value;//m2中的char[] -- ['a','b','c']
		
		if(v1.length == v2.length){//两个字符数组长度一致
			for (int i = 0; i < v1.length; i++) {
				if(v1[i] != v2[i]){//判断的是字符的ASCII码
					return false;
				}
			}
			return true;
		}
		
		return false;
	}
	
	@Override
	public String toString() {
		return String.valueOf(value);//把字符数组转换为字符串
	}
}
package com.qf.test03;

public class Test01 {

	public static void main(String[] args) {

		String str1 = new String("abc");
		String str2 = new String("abc");
		
		System.out.println(str1 == str2);//false - 比较的是内存地址
		System.out.println(str1.equals(str2));//true - 调用String类重写的equals方法 - 比较的是字符串内容
		
		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));//true - 调用MyString类重写的equals方法 - 比较的是字符串内容
	
		System.out.println(m1);//默认调用toString
		System.out.println(m2);//默认调用toString
	
	}
}

Java Obiect类--------11_第1张图片

四、final修饰符

4.1作用及命名规范 

 作用:
        1.修饰类:该类不能被继承
        2.修饰方法:该方法不能被重写
        3.修饰变量:该变量变成常量,不能被重新赋值
        使用final修饰的变量(常量)存在常量池中
        直到项目结束(main方法结束),常量才会被回收
        所以常量被其他的变量生命周期更长
        常量的命名规范:所有字母都大写,单词与单词之间使用下划线隔开 

4.1.1父类 

package com.qf.test04;

//最终的类,不能被继承
//public final class Father {
public class Father {

	//最终的方法,不能被子类重写
	//public final void method(){}
	
	public void method(){}
}

 4.1.2子类

package com.qf.test04;

public class Son extends Father{

	@Override
	public void method() {
		
		//最终的变量 -- 常量,不允许重新赋值
		//final int I = 100;
		//System.out.println(I);
		
		final int I;
		I = 100;
		System.out.println(I);
	}
}

 4.1.3测试类

package com.qf.test04;

public class Test01 {

	public static void main(String[] args) {

		Son son = new Son();
		son.method();
	}
}

 五、抽象类及抽象方法的使用

5.1需求 

编写人类、中国人、日本人类,操作对象 

分析:
        人类:
                属性:姓名、性别、年龄
                方法:吃饭饭、睡觉觉

        中国人类 继承 人类:
                属性:身份证
                方法:打太极

        日本人类 继承 人类:
                属性:年号
                方法:拍电影

需求的场景:三个类都是一个人写的 

 5.1.1父类Person

package com.qf.test05;

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 + "睡觉觉");
	}
	
}

 5.1.2抽象子类

package com.qf.test05;

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();
}

 5.1.3非抽象子类

package com.qf.test05;

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() + "吃火锅、烧烤、串串香");
	}

}
package com.qf.test05;

public class GuangDong extends Chinese{

	public GuangDong() {
	}
	
	public GuangDong(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() + "吃肠粉、潮汕牛肉火锅");
	}

}
package com.qf.test05;

public class Japanese extends Person{

	private String yearNum;
	
	public Japanese() {
	}
	
	public Japanese(String name, char sex, int age, String yearNum) {
		super(name, sex, age);
		this.yearNum = yearNum;
	}

	public String getYearNum() {
		return yearNum;
	}

	public void setYearNum(String yearNum) {
		this.yearNum = yearNum;
	}

	@Override
	public void eat() {
		System.out.println(super.getName() + "吃马赛克...");
	}
}

5.1.4测试类 

package com.qf.test05;

public class Test01 {

	public static void main(String[] args) {
		
		Japanese j = new Japanese("波多野结衣", '女', 16, "昭和");
		j.eat();
		
		System.out.println("-------");
		
		SiChuan sc = new SiChuan("李伟杰", '男', 18, "1234567890");
		sc.eat();
		sc.hobby();
		
		System.out.println("-------");
		
		GuangDong gd = new GuangDong("李嘉诚", '男', 85, "0987654321");
		gd.eat();
		gd.hobby();
	}
}

Java Obiect类--------11_第2张图片

 5.2面试题

1.抽象类不能有构造方法? 

        抽象类可以有构造方法

2.抽象类中只能有抽象方法?
        抽象类中可以有非抽象方法(构造方法、成员方法和静态方法) 

3.抽象类中不可以没有抽象方法?
        抽象类中可以没有抽象方法,但是毫无意义 

4.如果父类是抽象类,则子类必须实现父类的抽象方法?
        不一定,子类如果是抽象类,可以不实现父类的抽象方法 

5.可以使用new关键字来创建抽象类对象?
        不可以,抽象类是不能有对象的,创建的是匿名内部类的对象 
1.底层创建了匿名类,继承Person类,重写eat()
2.创建匿名类的对象
3.将匿名类的对象的内存地址赋值给父类的引用-p

package com.qf.test05;

public class Test02 {

	public static void main(String[] args) {

		Person p = new Person() {
			@Override
			public void eat() {
				System.out.println(super.getName() + "xxx");
			}
		};
		p.eat();
	}
}

 六、接口的使用

6.1含义 

接口是特殊的抽象类,接口中只能有静态常量和抽象方法 

        JDK1.8的新特性:接口中可以有静态方法和默认方法
        应用场景:接口是一个标准,规定实现类应该要完成的方法

 6.2注意

1.接口中的抽象方法默认使用public abstract修饰
2.接口中的属性默认使用public static final修饰

 6.3需求

编写学生管理系统 

分析:
        该系统管理学生 -- 增删改查

6.3.1学生类 

package com.qf.test06;

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 "Student [name=" + name + ", sex=" + sex + ", age=" + age + ", classId=" + classId + ", id=" + id + "]";
	}
	
}

 6.3.2学生类接口

package com.qf.test06;

//学生管理系统的接口
public interface StudentManagerSystem {
	
	int NAME = 1;
	int SEX = 2;
	int AGE = 3;
	int CLASS_ID = 4;
	int ID = 5;

	/**
	 * 添加学生
	 * @param stu 目标学生
	 * @return 状态码
	 */
	public int add(Student stu);
	
	/**
	 * 学生容器的扩容
	 */
	public void expansion();
	
	/**
	 * 删除学生
	 * @param classId 班级号
	 * @param id 学号
	 * @return 状态码
	 */
	public int delete(String classId,String id);
	
	/**
	 * 修改学生信息
	 * @param classId 班级号
	 * @param id 学号
	 * @param type 修改的类型(1-姓名 2-性别 3-年龄 4-班级号 5-学号)
	 * @param val 要修改的值
	 * @return 修改是否成功
	 */
	public boolean update(String classId,String id,int type,Object val);
	
	/**
	 * 修改学生姓名
	 * @param classId 班级号
	 * @param id 学号
	 * @param name 要修改的值
	 * @return 修改是否成功
	 */
	public boolean updateName(String classId,String id,String name);
	
	/**
	 * 修改学生性别
	 * @param classId 班级号
	 * @param id 学号
	 * @param sex 要修改的值
	 * @return 修改是否成功
	 */
	public boolean updateSex(String classId,String id,char sex);
	
	/**
	 * 修改学生年龄
	 * @param classId 班级号
	 * @param id 学号
	 * @param age 要修改的值
	 * @return 修改是否成功
	 */
	public boolean updateAge(String classId,String id,int age);
	
	/**
	 * 修改学生班级号
	 * @param classId 班级号
	 * @param id 学号
	 * @param targetClassId 要修改的值
	 * @return 修改是否成功
	 */
	public boolean updateClassId(String classId,String id,String targetClassId);
	
	/**
	 * 修改学生学号
	 * @param classId 班级号
	 * @param id 学号
	 * @param targetId 要修改的值
	 * @return 修改是否成功
	 */
	public boolean updateId(String classId,String id,String targetId);
	
	/**
	 * 查询学生
	 * @param classId 班级号
	 * @param id 学号
	 * @return 在容器中的下标
	 */
	public int query(String classId,String id);
	
	/**
	 * 查询学生
	 * @param name 姓名
	 * @return 学生数组
	 */
	public Student[] queryByName(String name);
	
	/**
	 * 查询学生
	 * @param sex 性别
	 * @return 学生数组
	 */
	public Student[] queryBySex(char sex);
	
	/**
	 * 查询学生
	 * @param startAge 开始年龄(包含)
	 * @param endAge 结束年龄(不包含)
	 * @return 学生数组
	 */
	public Student[] queryByAge(int startAge,int endAge);
	
	/**
	 * 查询学生
	 * @param classId 班级号
	 * @return 学生数组
	 */
	public Student[] queryByClassId(String classId);
	
	/**
	 * 查询学生
	 * @param classId 班级号
	 * @param id 学生号
	 * @return 学生对象
	 */
	public Student queryByClassIdAndId(String classId, String id);
	
	/**
	 * 打印容器内的所有学生对象
	 */
	public void printStuInfo();
	
	/**
	 * 传入数组打印学生
	 * @param stus 学生数组
	 */
	default void printStuInfo(Student[] stus){
		for (Student stu : stus) {
			System.out.println(stu);
		}
	}
}

 6.3.3学生实现类

package com.qf.test06;

//学生管理系统的实现类
public class StudentManagerSystemImpl implements StudentManagerSystem{

	@Override
	public int add(Student stu) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void expansion() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public int delete(String classId, String id) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean update(String classId, String id, int type, Object val) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean updateName(String classId, String id, String name) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean updateSex(String classId, String id, char sex) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean updateAge(String classId, String id, int age) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean updateClassId(String classId, String id, String targetClassId) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean updateId(String classId, String id, String targetId) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int query(String classId, String id) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public Student[] queryByName(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Student[] queryBySex(char sex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Student[] queryByAge(int startAge, int endAge) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Student[] queryByClassId(String classId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Student queryByClassIdAndId(String classId, String id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void printStuInfo() {
		// TODO Auto-generated method stub
		
	}

}

 

你可能感兴趣的:(java,开发语言)