重写Object类方法&抽象类&接口
1.重写Object类方法
1.1 hashCode方法
hashCode方法本身作用?
hashCode本身属于Object提供的一个用于获取对象hash值十进制的方法
hashCode,hash值是什么东西?
hash值是JVM根据杂凑算法 将对象的地址或者其他系信息作为条件计算出来的一个值 这个值一般情况下保证可以唯一性
hash算法举例:根据每人的姓氏的笔画除以某个数再加上某个数,决定你要在第几排第几列,正向是快速的但是不可以逆转的 例子:王 丰
hash值和地址的关系?
hash值仅仅只是地址的表现形式并不能代表地址 Java中生成hash的原码我们是看不到的 因为底层是使用C语言来写的
两个对象的hash值相同不一定是同一个对象,两个一致的对象hash值一定相同
为什么要重写hashCode方法?
在一些散列的数据结构中,有这样的要求 如果两个对象使用equals比较为true 那么这两个对象hash值必须一致,所以我们实际开发中,如果重写了equals方法,必须重写hashCode方法
package com.qfedu.test2;
/**
* 重写hashCode方法
* hashCode方法本身作用?
* hashCode本身属于Object提供的一个用于获取对象hash值十进制的方法
* hashCode,hash值是什么东西?
* hash值是JVM根据杂凑算法 将对象的地址或者其他信息等作为条件
* 计算出来的一个数值 这个数值一般情况保证下可以唯一性
* hash算法举例:根据每个人姓氏的笔画数决定你在第几排 根据你名字的笔画数除以某个数 再加上某个数 得到你应该在第几列
* 正向是快速的 但是不可逆的 王 丰
* hash值和地址的关系?
* hash值仅仅只是地址的表现形式 并不能代表地址 Java中的生成hash的原码我们是看不到的 因为底层是使用C语言来写的
* 两个对象hash值相同 不一定是同一个对象 两个一致的对象 hash值一定相同
* 为什么要重写hashCode方法?
* 在一些散列的数据结构中 有这样的要求 如果两个对象使用equals比较为true 那么这两个对象hash值必须一致
* 所以我们在实际开发中 如果重写了equals方法 必须重写hashCode方法
* @author WHD
*
*/
public class Person extends Object{
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(String name, String idCard) {
this.name = name;
this.idCard = idCard;
}
public Person() {
}
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
Person p = (Person) obj;
if(this.getName().equals(p.getName()) && this.getIdCard().equals(p.getIdCard())) {
return true;
}
return false;
}
public int hashCode() {
int prime = 31; // 权重 特殊的质数
int result = 1; // 结果先赋值为1 接下来计算 然后返回
result = prime * result + (this.getName() == null ? 0 : this.getName().hashCode());
result = prime * result + (this.getIdCard() == null ? 0 :this.getIdCard().hashCode());
return result;
}
public static void main(String[] args) {
Person p1 = new Person("赵四","1578721247856121");
Person p2 = new Person("赵四","157872124785612dsadsadasd1");
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println("返回当前所在类的Class对象" + p1.getClass().toString());
System.out.println("包名+类名" + p1.getClass().getName());
}
}
1.2getClass()方法
此方法返回的是一个Class类型的对象,继续调用getName()方法,返回当前对象的包名+类名(全限定名)
2. 抽象类
抽象 类 不是特别具体的一个类别
抽象:模糊不具体
1.抽象方法和抽象类都使用abstract关键字修饰
2.抽象方法没有方法体 必须存在于抽象类中
3.抽象类不能直接new对象 必须通过多态的方式来创建对象 new子类的方式
4.子类必须重写父类的抽象方法,除非子类也是抽象类
5.没有抽象的静态方法 没有抽象的构造方法
抽象类和普通类的区别?
1.抽象类可以写抽象方法,普通类不行
抽象类作为父类,实现多态的方式 依然是父类作为形参父类作为返回值
总结:抽象类使用感受
抽象类可以定义抽象方法 用于强制子类实现 这样可以统一我们程序的整体结构 更加规范
package com.qfedu.test3;
/**
* 门
* 属性:
* 品牌
* 价格
* 行为:
* 开
* 关
* 门:
* 普通门
* 防盗门
* @author WHD
*
*/
public abstract class Door {
private String brand;
private double price;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public abstract void open();
public abstract void close();
}
package com.qfedu.test3;
/**
* 普通门
* @author WHD
*
*/
public class CommonDoor extends Door{
@Override
public void open() {
System.out.println("普通门开门,钥匙一插,轻轻一转,门开了");
}
@Override
public void close() {
System.out.println("甩手一关门");
}
}
package com.qfedu.test3;
public class SecurityDoor extends Door{
@Override
public void open() {
System.out.println("指纹+人脸识别,门开了");
}
@Override
public void close() {
System.out.println("红外线感应,自动关门");
}
}
package com.qfedu.test3;
/**
* 人类
* 用于操作门
* 关门
* 开门
* @author WHD
*
*/
public class Person {
public void openCommonDoor(CommonDoor cd) {
cd.open();
}
public void openSecurityDoor(SecurityDoor sd) {
sd.open();
}
public void closeCommonDoor(CommonDoor cd) {
cd.close();
}
public void closeSecurityDoor(SecurityDoor sd) {
sd.close();
}
// 以上四个方法不合理 如果有的子类 必须重复编写新的方法
// 使用以下两个方法能够解决这个问题
public void openDoor(Door door) {
door.open();
}
public void closeDoor(Door door) {
door.close();
}
public CommonDoor buyCommomDoor() {
return new CommonDoor();
}
public SecurityDoor buySecurityDoor() {
return new SecurityDoor();
}
public Door buyDoor(String type) {
if(type.equals("普通")) {
return new CommonDoor();
}else if(type.equals("安全")) {
return new SecurityDoor();
}
return null;
}
}
package com.qfedu.test3;
public class Test {
public static void main(String[] args) {
Door door1 = new CommonDoor();
Person zhaosi = new Person();
zhaosi.openDoor(door1);
zhaosi.closeDoor(door1);
Door door2 = new SecurityDoor();
zhaosi.openDoor(door2);
zhaosi.closeDoor(door2);
Door door3 = zhaosi.buyDoor("普通");
zhaosi.openDoor(door3);
}
}
3.final关键字
final 单词:最终
可以
1.修饰属性
使用final修饰的属性称之为常量,如果在程序需要使用一个不能改变的值,那么可以使用final修饰
final修饰的常量名全部要大写,多个单词之间使用下划线分割
普通常量:
通常在定义的时候赋值也可以在构造方法中赋值,只能被赋值一次,使用类名直接访问
2.修饰方法:此方法不能被重写,可以被继承
3.修饰类:此类不能被继承
package com.qfedu.test4;
/**
* final 最终
* 修饰属性 常量
* 1.通常在声明的时候直接赋值
* 2.在构造方法中赋值也可以
* 修饰方法
* 1.被final修饰的方法可以被继承 ,不能被重写
* 修饰类
* 1.修饰类不能被继承
* @author WHD
*
*/
public class TestFinal {
final double PI = 3.14; //方式1 定义的时候赋值
private final int A ;
public TestFinal() {
A = 20; // 方式2 在构造方法中赋值
}
public static void main(String[] args) {
TestFinal tf = new TestFinal();
System.out.println(tf.A);
// tf.a = 20;
A a = new A();
a.m1();
}
}
class MySuper{
public final void m1() {
System.out.println("MySuper类中的m1方法");
}
}
class A extends MySuper{
// final修饰的方法 不能被重写
// @Override
// public void m1() {
//
// }
}
final class B{
}
//class C extends B{ 不能继承B类 因为 B类使用final修饰
//
//}
//class D extends String{
//
//}
package com.qfedu.test4;
/**
* 使用final修饰的属性我们称之为常量
* 常量的作用:
* 1.如果在程序执行过程中不想要一个值被改变 就可以使用final修饰 比如 PI 圆周率
* 2.使用final修饰的常量只能被赋值一次
* 3.通常在定义的时候赋值 也可以在 构造方法(没有加static修饰的)或者 静态代码块(加上static修饰的)中赋值
* 常量的写法要求 :全部大写 多个单词之间使用下划线分割
* 在日常开发中 通常将static和final结合一起来使用 因为如果一个内容不允许被改变 那么这个内容通常也没有必要存在多个
* @author WHD
*
*/
public class TestFinalField {
public static final double PI = 3.14; // 方式1 定义的时候赋值 使用的最多的方式
public static final String COUNTRY_NAME;
static {
COUNTRY_NAME = "中国"; // 方式2 在静态代码块中赋值
}
// 以上两种方式都是为了保证在使用在这个信息之前 这个静态常量就有值了
public static void main(String[] args) {
System.out.println(TestFinalField.PI);
System.out.println(TestFinalField.COUNTRY_NAME);
}
}