常用类
一.Object
含义:
所有类的基类/超类,一个类没有明确继承的类,默认继承Object
1.equals
比较两个对象内存地址是否相同
源码实现:
public boolean equals(Object obj){
return this == obj;
}
代码实现:
public static void main(String[] args) {
Object obj1 = new Object();//0x001
Object obj2 = new Object();//0x002
boolean equals = obj1.equals(obj2);
System.out.println(equals);//false
boolean bool = obj1 == obj2;
System.out.println(bool);//false
}
2.getClass
获取该类的字节码文件对象
代码实现:
public static void main(String[] args) {
Object obj1 = new Object();//0x001
Object obj2 = new Object();//0x002
Class<? extends Object> c1 = obj1.getClass();
Class<? extends Object> c2 = obj2.getClass();
System.out.println(c1 == c2);//true
}
//应用于反射,实现获得类的字节码文件对象后获取类中的属性和方法.
public static void main(String[] args) {
A a = new A();
//获取A类的字节码文件对象
Class<? extends A> c = a.getClass();
//获取A类中所有属性
Field[] declaredFields = c.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field);
}
//获取A类中所有的方法
Method[] declaredMethods = c.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method);
}
}
3.hashCode
获取对象的hash值
hash值=系统利用对象的内存地址+散列算法获取的一个值
注意:hash值不等于内存地址
代码实现:
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
}
4.toString
获取对象的字符串表示(将对象转换为字符串)
源码实现:
public String toString(){
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
代码实现:
public static void main(String[] args) {
Object obj1 = new Object();
//java.lang.Object@15db9742
System.out.println(obj1.toString());
}
二.Object标杆作用
1.equals
判断两个对象是否相同,Object不同的子类判断两个的对象是否相同有不同的判断规则,子类重写equals即可
代码实现:
public static void main(String[] args) {
User user1 = new User("1445584980", "123123");
User user2 = new User("1445584980", "123123");
System.out.println(user1.equals(user2));//重写toStrong方法后输出true
System.out.println(user1);//默认调用toString
}
package com.dream.test02;
public class User {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
User user = (User) obj;
if(this.username.equals(user.username)){
return true;
}
return false;
}
@Override
public String toString() {
return username + " -- " + password;
}
}
2.toString
返回对象的字符串表示,Object不同的子类有不同的属性,重写toString,返回属性
需求:
public static void main(String[] args) {
//需求:
//两个学生班级号+学号一样视作同一学生
//打印学生对象:把该学生所有的属性都打印出来
Student stu1 = new Student("春日野结衣", '女', 18, "2107", "001");
Student stu2 = new Student("卢永刚", '男', 21, "2107", "001");
System.out.println(stu1.equals(stu2));//true
System.out.println(stu1);//春日野结衣--女--18--2107--001
}
public class Student {
private String name;
private char sex;
private int age;
private String classId;
private String id;
public Student() {
}
public Student(String name, char sex, int age, String classId, String id) {
this.name = name;
this.sex = sex;
this.age = age;
this.classId = classId;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
Student stu = (Student) obj;
if(this.classId.equals(stu.classId) && this.id.equals(stu.id)){
return true;
}
return false;
}
@Override
public String toString() {
return "name=" + name + ", sex=" + sex + ", age=" + age + ", classId=" + classId + ", id=" + id;
}
}
三.String底层源码
String的equals为什么可以判断字符串内容?
底层把String的内容转换为字符数组,依次比较ASCII码
代码实现:
package com.dream.test02;
public class Test03 {
public static void main(String[] args) {
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));
System.out.println(m1);
System.out.println(m2);
}
}
package com.dream.test02;
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;
}
}
四.switch使用字符串细节
两个字符串hash值有可能相同(利用反编译便于理解)
代码实现:
package com.dream.test02;
public class Test04 {
public static void main(String[] args) {
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的使用
作用:
作用:
1.修饰变量 - 常量
存储在常量池中,直到项目结束才会被销毁
2.修饰类,类不能被继承
3.修饰方法,方法不能被重写
代码实现:
package com.dream.test03;
//A类不能有子类
//public final class A {
public class A {
//该方法不能被子类重写
public final void method(){}
}
package com.dream.test03;
public class B extends A{
//当父类A被final修饰,B不能继承A
//父类中被final修饰的方法不能在子类中重写
}
六.抽象类
抽象方法:
抽象方法:没有代码块并使用abstract修饰的方法,交给非抽象的子类去重写
应用场景:当一个方法必须在父类中出现,但是这个方法又不好实现,就把该方法变成抽象方法,或交给非抽象的子类去实现
需求:
//需求:编写人类、中国人、日本人
package com.study.test02;
public abstract class Person {
private String name;
private int age;
private char sex;
public Person() {
super();
}
public Person(String name, int age, char sex) {
super();
this.name = name;
this.age = age;
this.sex = 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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
public abstract void eat();
}
package com.study.test02;
public class Japanese extends Person{
private String yearNums;
public Japanese() {
}
public String getYearNums() {
return yearNums;
}
public void setYearNums(String yearNums) {
this.yearNums = yearNums;
}
public Japanese(String name, int age, char sex, String yearNums) {
super(name, age, sex);
this.yearNums = yearNums;
}
@Override
public String toString() {
return "Japanese [yearNums=" + yearNums + ", toString()=" + super.toString() + "]";
}
@Override
public void eat() {
System.out.println(super.getName() + "吃生鱼片");
}
}
package com.study.test02;
public abstract class Chinese extends Person{
private String ID;
public Chinese() {
}
public Chinese(String name, int age, char sex, String iD) {
super(name, age, sex);
ID = iD;
}
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
@Override
public String toString() {
return "Chinese [ID=" + ID + ", toString()=" + super.toString() + "]";
}
public abstract void hobby();
}
package com.study.test02;
public class SiChuan extends Chinese{
public SiChuan() {
super();
}
public SiChuan(String name, int age, char sex, String iD) {
super(name, age, sex, iD);
}
@Override
public void hobby() {
System.out.println(super.getName() + "打麻将");
}
@Override
public void eat() {
System.out.println(super.getName() + "吃火锅");
}
@Override
public String toString() {
return "SiChuan [toString()=" + super.toString() + "]";
}
}
package com.study.test02;
public class GuangDong extends Chinese{
public GuangDong() {
super();
}
public GuangDong(String name, int age, char sex, String iD) {
super(name, age, sex, iD);
}
@Override
public void hobby() {
System.out.println(super.getName() + "做生意");
}
@Override
public void eat() {
System.out.println(super.getName() + "吃潮汕火锅");
}
@Override
public String toString() {
return "GuangDong [toString()=" + super.toString() + "]";
}
}
package com.study.test02;
public class Test01 {
public static void main(String[] args) {
Japanese j = new Japanese("小峰由衣", 28 , '女', "令和");
j.eat();
System.out.println(j);
SiChuan sc = new SiChuan("林成", 18 , '男', "123456789");
sc.eat();
System.out.println(sc);
GuangDong gd = new GuangDong("李嘉诚", 80 , '男', "987654321");
gd.eat();
System.out.println(gd);
}
}
/*输出结果:
小峰由衣吃生鱼片
Japanese [yearNums=令和, toString()=Person [name=小峰由衣, age=28, sex=女]]
林成吃火锅
SiChuan [toString()=Chinese [ID=123456789, toString()=Person [name=林成, age=18, sex=男]]]
李嘉诚吃潮汕火锅
GuangDong [toString()=Chinese [ID=987654321, toString()=Person [name=李嘉诚, age=80, sex=男]]]
*/
深入抽象类:
1.抽象类中只能有抽象方法?
抽象类里可以有构造方法、静态方法、成员方法
2.抽象类中不可以没有抽象方法?
可以没有抽象方法,但是这样毫无意义
3.如果父类是抽象类,则子类必须实现父类的抽象方法?
子类如果是抽象类,可以不实现父类对的抽象方法
4.抽象类不能有构造方法?
可以有构造方法的
5.可以使用new关键字来创建抽象类对象?
不可以的,创建出的是匿名内部类的对象
代码实现:
public static void main(String[] args) {
//1.创建匿名类,继承Chinese,重写eat、hobby方法
//2.创建匿名类的对象
//3.赋值给父类的引用
Chinese c = new Chinese() {
@Override
public void eat() {
}
@Override
public void hobby() {
}
};
}
七.接口
含义:
1.接口是特殊的抽象类
2.接口中只能有静态常量和抽象方法
3.JDK1.8的新特性允许接口中使用默认方法和静态方法
作用:
制定规范
代码实现:
package com.dream.test06;
public class Test01 {
public static void main(String[] args) {
A a = new A();
a.defaultMethod();
I1.staticMethod();
}
}
package com.dream.test06;
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("接口中的静态方法");
}
}
package com.dream.test06;
public class A implements I1{
@Override
public void method01() {
}
@Override
public void method02() {
}
}
八.深入接口
类——接口的关系:
类 - 类:单继承
类 - 接口:多实现
接口 - 接口:多继承
面试题:
1.一个类可以实现多个接口?可以
2.一个接口可以实现多个接口?不可以,接口与接口之间是多继承关系
3.接口里面的方法不一定都是抽象的?JDK1.8开始接口中允许默认方法和静态方法
4.接口解决了类的单继承问题?是的
5.一个类是否可以继承一个类并同时实现多个接口?可以
6.接口可以new对象?不可以,创建的是匿名内部类的对象
代码实现:
package com.dream.test07;
public interface I1 {
public void i1Method01();
public void method01();
default void method02(){}
}
package com.dream.test07;
public interface I2 {
public void i2Method01();
public void method01();
default void method02(){}
}
package com.dream.test07;
public interface I3 extends I4,I5{
public void i3Method01();
}
package com.dream.test07;
public interface I4 {
public void i4Method01();
}
package com.dream.test07;
public interface I5 {
public void i5Method01();
}
package com.dream.test07;
public class A extends Object implements I1,I2,I3{
@Override
public void i2Method01() {
}
@Override
public void i1Method01() {
}
@Override
public void i4Method01() {
}
@Override
public void i5Method01() {
}
@Override
public void i3Method01() {
}
//I1、I2中都有method01的抽象方法,在实现类中只实现一个
@Override
public void method01() {
}
@Override
public void method02() {
//在实现类中调用I1接口中的默认方法
//I1.super.method02();
I2.super.method02();
}
}
public class Test01 {
public static void main(String[] args) {
//1.创建匿名类,实现I5接口中的i5method01方法
//2.创建匿名类的对象
//3.赋值给接口的引用
I5 i5 = new I5() {
@Override
public void i5Method01() {
}
};
}
}