day15
一、访问修饰符
含义:
修饰类、方法、属性,定义使用的范围
理解:给类、方法、属性定义访问权限的关键字
注意:
1.修饰类只能使用public和默认的访问权限
2.修饰方法和属性可以使用所有的访问权限
访问修饰符 | 本类 | 本包 | 其他包子类 | 其他包 |
---|---|---|---|---|
private | OK | |||
默认的 | OK | OK | ||
protected | OK | OK | OK | |
public | Ok | OK | OK | Ok |
做实验
两个包下分别父类和子类,测试类进行实验
经验:
1.属性一般使用private修饰,因为封装
2.属性或者方法如果需要被子类使用,一般使用protected修饰
3.方法如果不需要被外界使用,一般使用private修饰
4.方法一般使用public修饰
二、Object
概念:
所有类的基类或者超类
理解:如果一个类没有明确继承的类,默认继承Object,所以说Object是所有类的祖先类
方法
equals:
作用:比较两个对象内存地址是否相同
public boolean equals(Object obj){
return this == obj;
}
注意:equals和==
a.基本数据类型:==比较的是值是否相同
b.引用数据类型:==比较的是内存地址
查看equals底层
鼠标放在equals上按ctrl点击----->点击Attach Source------>选择外部路径External location----->ps:C:\Program Files\Java\jdk1.8.0_144\src.zip
equals内存图
扩展
1.Java方法的参数是值传递
2.如果方法中参数是基本类型直接将实参的值传入该方法 3.如果方法中的参数是引用类型将对象的内存地址作为值传入该广法
hashCode:
作用:获取对象的hash值
hash值不等于内存地址,hash值是对象的内存地址+散列算法,算出来的一个数值
System.out.println(obj1.hashCode());//366712642
getClass:
作用:获取类的字节码文件对象
注意:
使用到类,会把该类的class文件加载到方法区,并且在堆中创建该类的class对象
该类的class对象作为class文件的访问入口
class文件只加载1次,所以该类的class对象在内存中也只有一个
Object obj1 = new Object();//0x001
Object obj2 = new Object();//0x002
Class<? extends Object> class1 = obj1.getClass();//获取的是Object类的class对象
Class<? extends Object> class2 = obj2.getClass();//获取的是Object类的class对象
System.out.println(class1 == class2);//true
toString:
作用:获取对象的字符串表示(将对象转换为字符串)
toString底层:
public String toString(){
//java.lang.Object @ 15db9742
return getClass().getName() + “@” + Integer.toHexString(hashCode());//getClass().getName() - class对象的全路径(报名+类名) //Integer.toHexString(hashCode()) - 获取对象的十六进制hash值
}
Object obj1 = new Object();//0x001
Object obj2 = new Object();//0x002
System.out.println(obj1.toString());//java.lang.Object@15db9742
System.out.println(obj2.toString());//java.lang.Object@6d06d69c
方法的使用
Object方法标杆作用
Object方法标杆作用:Object作为所有类的父类,定义了几个方法,方便子类去重写
equals:比较两个对象是否相同,不同子类比较两个对象的规则不一样,所以子类重写即可
toString:每个子类都有不同的属性,重写toString直接打印该对象中所有的属性,方便观察数据
getClass():在反射的知识点中使用
hashCode():在集合的知识点中使用
equals和toString使用
需求:编写用户类,比较两个对象是否相同,并打印
封装User(默认继承Object),重写equals、toString
@Override
public boolean equals(Object obj) {
if(this == obj){//比较两个对象的内存地址是否一致
return true;
}
//两个对象的内存地址不一致
User use = (User) obj;//需要强转,java的参数是值传递
//当前对象的账号和传进来对象的账号,此处是String类型的equals()
if(this.username.equals(use.username)){
return true;
}
return false;
}
@Override
public String toString() {//打印所有属性
return this.username + " -- " + this.password + " -- " + this.nickName + " -- " + this.name;
}
//测试类
User user1 = new User("1445584980", "123123", "撕裂的忧伤", "彭于晏");//0x001
User user2 = new User("1445584980", "123123", "撕裂的忧伤", "彭于晏");//0x002
System.out.println(user1.equals(user2));
System.out.println(user1.toString());
System.out.println(user2.toString());
深入String的equals()
MyString
重写方法(@Override),String的equals底层原理
首先toCharArray()将字符串转换为字符数组
重写equals
a.比较内存地址是否相同
b.比较字符长度是否相同
c.比较字符的Unicode码是否相同
重写toString
valueOf()将字符数组转为字符串
注意:打印对象,默认调用toString()
public class MyString {
private char[] value;
public MyString(String original) {
//"abc"
//['a','b','c']
value = original.toCharArray();//将字符串转换为字符数组
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
MyString my = (MyString) obj;
char[] v1 = this.value;
char[] v2 = my.value;
//比较字符长度
if(v1.length != v2.length){
return false;
}
for (int i = 0; i < v1.length; i++) {
//比较字符的Unicode码是否相同
if(v1[i] != v2[i]){
return false;
}
}
return true;
}
@Override
public String toString() {
return String.valueOf(value);//将字符数组转为字符串
}
}
2.面试题:String是如何比较两个字符串是否相同的
1.比较两个字符串的地址是否相同
2.比较两个字符串的字符个数
3.循环比较字符的Unicode码
//String和MyString都可以实现,表明重写的MyString符合要求
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//true
System.out.println(str1);
System.out.println(str2);
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
//注意:打印对象,默认调用toString()
System.out.println(m1);
System.out.println(m2);
三、final
含义:
最终的
关键字
作用:
- 修饰类:该类不能被继承
- 修饰方法:该方法不能被重写
- 修饰变量:变成常量,不能重新赋值
注意:
1.常量在常量池中声明,项目结束时才会被销毁
2.常量的命名规范:全部单词大写,单词之间使用下划线隔开
3.常量的生命周期:存在常量池中,直到项目结束才会被销毁
经验:
如果不想让该类有子类(不想该类有扩展),就是用final修饰final和static一般一起修饰属性,该属性变成静态常量
做实验
//final修饰类,该类不能被继承
//public final class A {
public class A {
//final修饰方法,该方法不能被子类重写
//public final void method(){
public void method(){
System.out.println("父类的方法");
}
}
public class B extends A{
@Override
public void method() {
System.out.println("子类重写父类的方法");
//final修饰变量,变量变为常量,不能重新赋值
final int i = 100;
System.out.println(i);
}
}
总结
1.访问修饰符 – 一定要去做实验
2.Object的概念
equals
getClass
hashCode
toString3.Object的使用
子类重写equals和toString4.MyString – 重要!!!
5.final - 最终的
修饰类,类不能被继承
修饰方法,方法不能被重写
修饰变量,变为常量