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. 重写和重载的区别?
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);
}
}