Object类
含义:所有类的基类/超类,一个类没有明确继承的类,默认继承Object类
equals()方法
equals:比较两个对象的内存地址是否相同
Object类: public boolean equals(Object obj){
return this == obj;
}
getClass()方法
getClass():获取该类的字节码文件对象
hashCode()方法
hashCode():获取对象的hash值
hash值:系统利用对象的内存地址+散列算法 获取的一个值
注意:hash值不等于内存地址
toString()方法
toString():获取对象的字符串表示(将对象转换为字符串)
public String toString(){
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
代码示例
Object obj1 = new Object(); Object obj2 = new Object(); //获取Object类的字节码文件对象 Class<? extends Object> class1 = obj1.getClass(); System.out.println(obj1.equals(obj2));//false System.out.println(obj1.getClass() == obj2.getClass());//true System.out.println(obj1.hashCode());//2018699554 System.out.println(obj2.toString());//java.lang.Object@4e25154f
扩展:String部分底层源码
String的equals为什么可以判断字符串内容?
答:把String的内容转换为字符数组,依次比较ASCII码
public class MyString { private String value; public MyString(String value) { this.value = value; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } //对象的向下转型 MyString m = (MyString) obj; //['a','b','c'] char[] v1 = this.value.toCharArray();//把当前对象的str转换为字符数组 //['a','b','c'] char[] v2 = m.value.toCharArray();//把被比较对象的str转换为字符数组 if(v1.length != v2.length){ return false; } for (int i = 0; i < v2.length; i++) { if(v1[i] != v2[i]){ return false; } } return true; } @Override public String toString() { return value; } } public static void main(String[] args) { /** * 知识点:String底层源码 * * String的equals为什么可以判断字符串内容? * 底层把String的内容转换为字符数组,依次比较ASCII码 */ 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);//默认调用toString System.out.println(str2);//默认调用toString 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-比较两个字符串的内容 System.out.println(m1);//abc System.out.println(m2);//abc }
知识点:switch使用字符串细节
public static void main(String[] args) { /** * 知识点:switch使用字符串细节 * * 两个字符串hash值有可能相同 */ String str = "ab"; switch (str) {//switch (str.hashCode()) { case "ab"://case 3104: if(str.equals("ab")){ System.out.println("ab"); } break; case "aa"://case 3105: if(str.equals("aa")){ System.out.println("aa"); } break; case "bC"://case 3105: if(str.equals("bC")){ System.out.println("bb"); } break; } }
final关键字
知识点:final - 最终的
作用:
1.修饰变量, 使其变成常量 (存储在常量池中,直到项目结束才会被销毁)
2.修饰类,该类不能被继承
3.修饰方法,该方法不能被重写
抽象类和抽象方法
抽象类:包含抽象方法的类
抽象方法:没有代码块且使用abstract修饰的方法。抽象方法交由非抽象的子类去重写
应用场景:当一个方法必须在父类中出现,但这个方法又不好实现,就把该方法变成抽象方法,交给非抽象的子类去实现
深入抽象类及抽象方法
1.抽象类中只能有抽象方法?
抽象类里可以有构造方法、静态方法、成员方法
2.抽象类中不可以没有抽象方法?
可以没有抽象方法,但是这样毫无意义
3.如果父类是抽象类,则子类必须实现父类的抽象方法?
子类如果是抽象类,可以不实现父类中的抽象方法
4.抽象类不能有构造方法?
可以有构造方法的
5.可以使用new关键字来创建抽象类对象?
不可以的,创建出的是匿名内部类的对象//1.创建匿名类,继承Chinese,重写eat、hobby方法 //2.创建匿名类的对象 //3.赋值给父类的引用 Chinese c = new Chinese() { @Override public void eat() { } @Override public void hobby() { } };
接口
含义:
1.接口是特殊的抽象类
2.接口中只能有静态常量和抽象方法
3.JDK1.8的新特性允许接口中使用默认方法和静态方法作用:制定规范
public interface I1 { //默认添加public static final int i = 100; //默认添加abstract public void method01(); public void method02(); //默认方法 default void defaultMethod(){ System.out.println("接口中的默认方法"); } //静态方法 public static void staticMethod(){ System.out.println("接口中的静态方法"); } } public class A extends Object implements I1,I2{ //I1、I2中都有method01的抽象方法,在实现类中只实现一个 @Override public void method01() { } @Override public void method02() { //在实现类中调用I1接口中的默认方法 //I1.super.defaultMethod(); I2.super.defaultMethod(); } }
深入接口
类 与 接口的关系
- 类–类:单继承
- 类–接口:多实现
- 接口–接口:多继承
面试题:
1.一个类可以实现多个接口? 可以
2.一个接口可以实现多个接口? 不可以,接口与接口之间是多继承关系
3.接口里面的方法不一定都是抽象的? JDK1.8开始接口中允许默认方法和静态方法
4.接口解决了类的单继承问题? 是的
5.一个类是否可以继承一个类并同时实现多个接口? 可以
6.接口可以new对象? 不可以,创建的是匿名内部类的对象//1.创建匿名类,实现I5接口中的i5method01方法 //2.创建匿名类的对象 //3.赋值给接口的引用 I5 i5 = new I5() { @Override public void i5Method01() { } };