==与equals()
- == 的作用是判断两个对象的地址是不是相等的,即判断两个对象是不是同一个对象(基本数据类型==比较的是值,引用数据类型==比较的是内存地址)
- equals()的作用判断对象是否相等。两种情况:① 类没有覆盖equals()方法,通过equals()比较两个对象时,等价于通过"=="比较这两个对象。② 类覆盖了equals()方法,来比较两个对象的内容是否相等,若内容相等,则返回返回true。
hashCode()
获取哈希码,即获取该对象在哈希表中的索引位置。哈希表存储的是键值对,特点:能根据“键”快速的检索出对应的“值”。HashSet在加入对象的时候,先计算对象的hashCode值来判断对象加入的位置,同时也会也会与该位置其他已经加入的hashCode值做比较,如果没有相符的hashCode,HashSet解假设对象没有重复出现。但是如果发现相同hashCode值的对象,这时会调用equals()方法来检查hashCode()相等的对象是否真的相同,如果两者相同,HashSet就不会让其加入操作成功,如果不同的话,机会重新散列到其他位置。
面向对象三大特性
- 封装:把对象属性私有化,向外界提供一些访问该属性的方法
- 继承:子类继承父类的所有方法和属性,包括私有的[ 但只能拥有,不能访问 ],
- 多态:多种形态,具体的表现特征是编译时的类型和运行时的类型不一致[ 编译看左边,运行看右边 ]。 变量的引用形式有两种:本态引用:左边的变量与右边的对象是同一种类型。 多态引用:左边的变量是父类类型,右边的对象是子类的对象。多用可用于方法的动态绑定。
多态数组 [数组声明是父类的类型,实际存储的是子类的对象 ], 多态参数[ 形参是父类的类型,实参是子类的对象 ]
接口和抽象类
为什么要有接口,为什么要有抽象类??从设计层面来看,接口是对方法的抽象,是一种行为规范。抽象类是对类的抽象,是一种设计模板
什么情况下用到接口:定义行为标准,
接口的特点:
① 接口是标准,就是用来被遵守的,即就是用来被实现的,那么要求实现类在实现接口时,必须实现/重写所有的抽象方法,否则这个实现类就得是一个抽象类。
② 接口也是不能直接创建对象的
③ 接口类型的变量与实现类的对象构成多态引用
④ 一个类继承父类时,我们说Java只支持单继承,但是一个类在实现接口时,可以同时实现多个接口
⑤ 一个类如果同时继承父类,又实现接口时,要求继承在前,实现在后
冲突问题
(1)当一个类同时实现了两个甚至更多个接口时,这些个接口中出现了方法签名相同的默认方法时,
那么我们必须在这个实现类中,做出选择。选择一:保留其中一个,放弃另一个,选择二:两者都不用,完全重写一个。
(2)当一个类同时继承了父类,又实现了接口,那么当父类中出现了和接口中方法签名一样的方法时,怎么办?
那么我们怎么选择?
选择一:默认选择,编译器默认选择父类
选择二:改选保留接口的
选择三:完全自己重写
什么情况下用到抽象类: 当我们在声明一个父类时,某个/些方法的实现不清楚,或者说无法给出具体的实现,要等到具体的子类中才能给出具体的实现,那么这样的方法,就可以声明为抽象方法。
抽象类特点:
① 抽象类不能实例化。 ② 如果子类继承了抽象类,必须重写父类的所有抽象方法,否则子类也得是一个抽象类。③抽象类也有构造器,这个构造器不是为了创建抽象类自己的对象使用的,而是为了子类创建对象服务的。④ 抽象父类与子类的对象之间可以构成多态引用。
区别:
- 接口中除了static,final变量,不能有其他变量。而抽象类不一定。
- 接口的方法不能有实现。默认修饰符为public,JDK1.8开始接口方法可以有默认实现。 抽象类中可以有非抽象方法。
- 一个类可以实现多个接口,但是只能有一个抽象类。接口自己本身可以通过extends关键字拓展多个接口。
abstract修饰符
1、可以修饰什么?
① 类 ② 方法
2、修饰类的话,和那些修饰符不能一起使用?
类:public和缺省, final
abstract和final不能一起修饰类。
3、修饰方法,和那些修饰符不能一起使用?
方法:4种权限修饰符 static,final,abstract,native
(1)final,abstract不行 因为final不能被重写
(2)static,abstract不行 因为static不能被重写
(3)native,abstract不行 因为都没有方法体,不知道是什么情况,会有歧义
(4)private,abstract不行 因为private不能被重写
成员变量与局部变量
- 语法形式:成员变量属于类|对象,局部变量是在方法中定义的变量或方法的参数;成员变量可以别public,private,static等修饰符修饰,而局部变量不能被访问控制符及static所修饰,但是,成员变量与局部变量都可以被final修饰。
- 内存中的存储方式:如果成员变量被static修饰,这个变量是属于类的,如果没有被static修饰,这个成员是属于实例的。对象存于堆内存,如果局部变量的类型为基本数据类型,则存储在栈中,如果是引用类型,则存放的是指向堆内存对象的引用,或者常量池中的地址。
- 生存时间:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随方法的调用而自动消失。
- 初始值:成员变量如果没有被赋初始值,则会自动以类型的默认值赋值,而局部变量则不会自动赋值。