方法重写

113 阅读8分钟

1. 方法重写

方法重写Override特点:
1.存在于父子类之间
2.方法名与父类相同
3.参数列表与父类相同
4.返回值与父类相同(或者是其子类)
5.访问权限不能严于父类(不能窄化父类的访问权限) 6.不能抛出比父类更多的异常
7.静态方法可以被继承,不能被重写

package com.qfedu.test1;
/**
 * 	宠物类   父类 
 * 	父类中保留子类共有的属性和方法
 * @author WHD
 *
 */
public class Pet {
	protected String name;
	protected int health;
	protected int love;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHealth() {
		return health;
	}
	public void setHealth(int health) {
		this.health = health;
	}
	public int getLove() {
		return love;
	}
	public void setLove(int love) {
		this.love = love;
	}
	
	void print() {
		System.out.println("宠物的名字是:" + name + ",健康值是:" + health + ",爱心值是:" + love);
	}	
}
package com.qfedu.test1;
/**
 * 	Dog类
 * 	品种
 * 
 * 	无参构造
 * 	打印信息方法
 * @author WHD
 *
 */
public class Dog extends Pet{
	private String strain;
	public String getStrain() {
		return strain;
	}
	public void setStrain(String strain) {
		this.strain = strain;
	}
	
	public Dog() {
	}
	
	
	public Dog(String name,int health,int love,String strain) {
		this.strain = strain;
		super.name = name;
		super.health = health;
		super.love = love;
	}
	/**
	 * 	(重载Overload)
	 * 	方法重写Override特点:
	 * 	1.存在于父子类之间
	 * 	2.方法名与父类相同
	 * 	3.参数列表与父类相同
	 * 	4.返回值与父类相同(或者是其子类)
	 * 	5.访问权限不能严于父类(不能窄化父类的访问权限)
	 * 
	 * 	6.不能抛出比父类更多的异常
	 * 	7.静态方法可以被继承,不能被重写
	 */
	@Override
	public void print(){
		super.print();
		System.out.println("Dog类的print方法");
	}
}
package com.qfedu.test1;
/**	
 * @author WHD
 *
 */
public class TestPet {
	public static void main(String[] args) {
		
		Dog dog1 = new Dog();
		dog1.print();
	}
}

2. @Override注解

此注解用于表示子类的方法属于重写父类的方法

只能用在子类的方法上

此注解不影响代码的执行结果,只用于规范方法重写

此注解可以提高代码的阅读性

3. 重写和重载的区别?

重写重载区别.png

4.Object类

4.1 重写toString

Object类中的toString方法默认返回值为:包名 +  类名 + @  + hash值

我们可以根据自己的需求进行重写,比如我们可以重写为返回值为:属性+属性值

直接打印对象名相当于访问此对象的toString方法

package com.qfedu.test3;
/**
 * 	所有类的默认父类都是Object
 * @author WHD
 *
 */
public class Student{
	private String  name;
	private int age;
	private String sex;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public String toString() {
		String str = super.toString();
		return "Student[name=" + name + ",age= "+ age +",sex = " + sex +"]" + str;
	}

	public static void main(String[] args) {
		Student stu = new Student();
		stu.setName("赵四");
		stu.setAge(20);
		stu.setSex("男");
		
		
		System.out.println(stu.toString());
		System.out.println(stu); // 直接打印对象 相当于此对象的toString方法

	}
}

4.2 面试题

==和equals的区别?

==比较基本数据类型 比较的是值

==比较引用数据类型 比较的是地址

equals本身也是比较地址,但是我们可以重写按照我们自己的要求来比较

String类就是对其进行了重写 重写为了比较字符串的内容

package com.qfedu.test4;

public class MyString {
	public static void main(String[] args) {
		System.out.println(myEquals("abc", "abcdefhj"));
	}
	
	
	public static boolean myEquals(String str1,String str2) {
		if(str1 == str2) {
			return true;
		}
		char [] ch1 = str1.toCharArray();
		char [] ch2 = str2.toCharArray();
		
		if(ch1.length != ch2.length) {
			return false;
		}
		
		for(int i= 0;i < ch1.length;i++) {
			if(ch1[i] != ch2[i]) {
				return false;
			}
		}
		return true;
	}
}

4.3 重写equals方法

需求:假设现在有"两个人",名字和身份证都一样,那么这"两个人"就是同一个人,,所以使用equals比较应当为true

package com.qfedu.test5;
/**
 * 	名字
 * 	身份证号
 * 	
 * 	需求:假设现在有"两个人",名字和身份证都一样,那么这"两个人"就是同一个人
 * @author WHD
 */
public class Person {
	private String name;
	private String idCard;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getIdCard() {
		return idCard;
	}
	public void setIdCard(String idCard) {
		this.idCard = idCard;
	}
	public Person() {
	}
	public Person(String name, String idCard) {
		this.name = name;
		this.idCard = idCard;
	}
	
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		
		// 如果代码能执行到这里 表示地址不同
		// 那么接下来我们要比较两个对象的名字 和 身份证号 
		Person p1 = (Person)obj;
		
		if(this.getName().equals(p1.getName()) && this.getIdCard().equals(p1.getIdCard())) {
			return true;
		}
		
		return false;
	}
	public static void main(String[] args) {
		Person p1 = new Person("赵四", "2134723166879123454");
		Person p2 = new Person("赵四", "2134723166879123454");
	
		System.out.println(p1.equals(p2));
		System.out.println(p1 == p2);
	}
}

4.4 重写hashCode()

hashCode属于一种杂凑算法:是指将一些杂乱的条件拼凑在一起计算出来一个值

Java中hash值是根据地址加上其他的一些条件所计算出来的一个十进制的数值

为什么要重写hashCode?

因为在一些散列数据结构中,是根据两个对象的equals比较为true,并且hashCode相同,

则认为是重复的对象,这种规则来存储元素的。所以我们在实际开发中,通常重写了equals方法,也会重写hashCode

package com.qfedu.test1;
/**
 * 	hashCode hash值  
 * 	hashCode属于一种杂凑算法:是指将一些杂乱的条件拼凑在一起计算出来一个值
 * 	Java中hash值是根据地址加上其他的一些条件所计算出来的一个十进制的数值
 * 
 * 	为什么要重写hashCode?
 * 		因为在一些散列数据结构中,是根据两个对象的equals比较为true,并且hashCode相同,
 * 		则认为是重复的对象,这种规则来存储元素的。所以我们在实际开发中,通常重写了equals方法,也会重写hashCode
 * 	
 * @author WHD
 *
 */
public class Person {
	private String name;
	private String idCard;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getIdCard() {
		return idCard;
	}
	public void setIdCard(String idCard) {
		this.idCard = idCard;
	}
	
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		Person p1 = (Person) obj;
		if(this.getName().equals(p1.getName()) && this.getIdCard().equals(p1.getIdCard())) {
			return true;
		}
		return false;
	}
	
	/**
	 * 	我们要重写为 当equals比较为true
	 * 	hashCode必须相同
	 * 
	 * 	分析:因为我们现在要求 当equals比较为true  则hashCode相同
	 * 	并且equals方法是根据名字和身份证号来计算的
	 * 	所以我们可以将hashCode方法也重写为根据名字和身份证号来计算
	 * 
	 * 	问题
	 * 	1.result在计算过程中进行了重新赋值 不存在两个result
	 * 	2.我们改变完hashCode以后 地址是没有改变 也是不可能改变的
	 */
	public int hashCode() {
		int prime = 31; // 权重 
		int result = 1;
		result = prime * result + (this.getName() == null ? 0 : this.getName().hashCode());
		result = prime * result + (this.getIdCard() == null ? 0 : this.getIdCard().hashCode());
		return result;
//		return 99 * 99 + this.getName().hashCode() + this.getIdCard().hashCode();
	}
	
	public Person(String name, String idCard) {
		this.name = name;
		this.idCard = idCard;
	}
	public Person() {
	}
	public static void main(String[] args) {
		Person p3 = new Person("赵四", "4512487812142453");
		Person p4 = new Person("赵四", "4512487812142453");
		System.out.println(p3.equals(p4));
		System.out.println(p3.hashCode());
		System.out.println(p4.hashCode());
		
		System.out.println(p3 == p4);
	}
}

4.5 hashCode权重(了解)

为什么在计算hashCode的时候使用31作为权重?

31是一个特殊的质数

任何数乘以31  等于 这个数 左移5位 减去这个数本身

左移几位表示乘以2的几次方

右移几位表示除以2的几次方

为什么在计算hashCode的时候要使用31作为权重

  • 因为31是一个特殊的质数,任何数乘以31等于这个数左移5位 减去这                 数本身
  • 左移几位表示乘以2的几次方
  • 右移几位表示除以2的几次方
  • 综上所述,因为使用31计算hashCode时使用位运算符参与运算,效率比较高
  • x*31=(x<<5)-x

综上所述,因为使用31计算hashCode 使用位运算符参与运算  效率比较高

5. getClass()

getClass方法可以获取当前对象信息 包名 + 类名

package com.qfedu.test2;
/**
 * 	getClass方法可以获取当前对象信息 包名 + 类名
 * @author WHD
 *
 */
public class Student {
	public static void main(String[] args) {
		Student stu = new Student();
		System.out.println(stu);
		System.out.println(stu.getClass());
		System.out.println(stu.getClass().toString());
		
		System.out.println(stu.getClass().getName());
		
	}
}

6. 类类型的属性

我们在实际开发中,通常需要使用自定义的数据类型来存储数据,这样更合适。

package com.qfedu.test3;
/**
 * 	姓名
 * 	年龄
 * 	身高
 * 	性别
 * 	地址
 * @author WHD
 *
 */
public class Person {
	private String name;
	private int age;
	private double height;
	private String sex;
	private Address address;
	private Hobby[] hobbies; // String [] strs
	public void setHobbies(Hobby [] hobbies) {
		this.hobbies = hobbies;
	}
	public Hobby[] getHobbies() {
		return hobbies;
	}
	
	public void setAddress(Address address) {
		this.address = address;
	}
	public Address getAddress() {
		return address;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getHeight() {
		return height;
	}
	public void setHeight(double height) {
		this.height = height;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String toString() {
		return "Person[name=" + name + ",age=" + age + ",sex=" + sex + ",height=" + height + ",address=" + address + "]";
	}
}
package com.qfedu.test3;

public class Address {
	private String province;
	private String city;
	private String area;
	private String street;
	private String zipCode;
	public String getProvince() {
		return province;
	}
	public void setProvince(String province) {
		this.province = province;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getArea() {
		return area;
	}
	public void setArea(String area) {
		this.area = area;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	public String getZipCode() {
		return zipCode;
	}
	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}
	@Override
	public String toString() {
		return "Address [province=" + province + ", city=" + city + ", area=" + area + ", street=" + street
				+ ", zipCode=" + zipCode + "]";
	}
}
package com.qfedu.test3;

public class Hobby {
	private String hobbyType;
	private String hobbyName;
	public String getHobbyType() {
		return hobbyType;
	}
	public void setHobbyType(String hobbyType) {
		this.hobbyType = hobbyType;
	}
	public String getHobbyName() {
		return hobbyName;
	}
	public void setHobbyName(String hobbyName) {
		this.hobbyName = hobbyName;
	}
	@Override
	public String toString() {
		return "Hobby [hobbyType=" + hobbyType + ", hobbyName=" + hobbyName + "]";
	}

}
package com.qfedu.test3;

import java.util.Arrays;

public class TestPerson {
	public static void main(String[] args) {
		Person p1 = new Person();
		p1.setName("赵四");
		p1.setAge(20);
		p1.setHeight(175);
		p1.setSex("男");
		
		Address address = new Address();
		address.setProvince("河南省");
		address.setCity("郑州市");
		address.setArea("二七区");
		address.setStreet("长江路街道");
		address.setZipCode("450003");
		
		p1.setAddress(address);
		
		Hobby [] hobbies = new Hobby[3];
		
		hobbies[0] = new Hobby();
		hobbies[0].setHobbyType("文艺类");
		hobbies[0].setHobbyName("唱歌");
		
		hobbies[1] = new Hobby();
		hobbies[1].setHobbyType("体育类");
		hobbies[1].setHobbyName("篮球");
		
		hobbies[2] = new Hobby();
		hobbies[2].setHobbyType("电子竞技类");
		hobbies[2].setHobbyName("贪吃蛇");
		p1.setHobbies(hobbies);
		
		Hobby [] hs  = p1.getHobbies();
		for (int i = 0; i < hs.length; i++) {
			System.out.println(hs[i].getHobbyType() + "----" + hs[i].getHobbyName());
		}
		System.out.println("-----------------------------------");
		System.out.println(Arrays.toString(p1.getHobbies()));
		
		System.out.println("-----------------------------------");
		System.out.println("名字:" + p1.getName());
		System.out.println("省份是:" + p1.getAddress().getProvince());
		System.out.println("城市是:" + p1.getAddress().getCity());
		
		System.out.println("地址信息是:" + p1.getAddress());
		System.out.println("-----------------------------------");
		System.out.println(p1);
	}
}