java基础4-equals方法、instanceof方法、接口和抽象类
equals()方法
比较两个对象的引用是否指向同一块地址
public class Main {
public static void main(String[] args) {
A a1=new A();
A a2=new A();
System.out.println(a1.equals(a2));
}
}
class A {
public void aMethod1() {
System.out.println("aMethod1");
}
}
输出结果
false
系统在构造a1对象和a2对象后 开辟了两个内存空间
如果需要判断两个对象的某个属性值是否相等需要重写equals()方法
利用Intellij Idea的Generate Code功能可以自动生成equals()方法
public class Main {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
System.out.println(a1.equals(a2));//a1.a是否等于a2.a
a2.a=20; //修改a2.a
System.out.println(a1.equals(a2));//返回false
}
}
class A {
int a = 10;
@Override//自动生成的代码
public boolean equals(Object o) {
if (this == o) return true;//两个对象的地址是否相同
if (o == null || getClass() != o.getClass()) return false;
//o == null :o是否空值?
/*getClass()得到一个类对象
判断两个对象是否是相同的类型
比如在main方法中 a1的类对象就是A
*/
A a1 = (A) o;
//转化 注意这里的a1其实是o
return a == a1.a; //如果o的a1和a相等返回true
}
}
显示结果:
true
false
equals()比较String类型
在比较String类型时java是不够聪明的
public class Test {
public static void main(String []args) {
String s1 = "ant";
String s2 = "an";
s2 += "t";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
}
}
输出结果:
false
true
显然s1和s2是相等的 但"=="并没有获得正确的结果
instance关键字避免类型转换的安全问题
用法:父类对象 instanceof 子类
返回布尔值
public class Main {
public static void main(String[] args) {
A a = new Ason();
//向上类型转换
a.a();
//输出Ason
Ason a1 = (Ason) a;
a1.a();//被覆盖输出Ason
if (a instanceof Ason2) {
Ason2 ason2 = (Ason2) a;
} else System.out.println("不合法类型转换");//类型转换不合法
}
}
class A {
public void a() {
System.out.print("A");
}
}
class Ason extends A {
public void a() {
System.out.println("Ason");
}
}
class Ason2 extends A {
public void a() {
System.out.println("Ason2");
}
}
输出结果:
Ason
Ason
不合法类型转换
对象的toString();方法
返回对象内存地址的Hash值
public class Main {
public static void main(String[] args) {
A a = new A();
System.out.print(a.toString());
}
}
class A {
public void a() {
System.out.print("A");
}
}
返回结果:
A@14ae5a5
接口
接口的内部全是常量和公共的抽象方法
接口是一种约束类的规范
接口制定了类的行为方式,而没有说明如何实现类 对于提供了具有这些签名的方法的类,可以称之为实现接口
public class Main {
public static void main(String[] args) {
A a = new A();//构造
a.printA(111);//A的printA()方法
a.printB();
D d = new D();//构造
d.printA();//d的printA方法 值是"c"
d.printB();//d的printV方法 值是30
}
}
interface printA { //声明接口可以省略abstract关键字
int a = 10;//a是一个公共常量 该语句有隐式的public static final
void printB();//接口内的方法都是抽象的
}
interface printB {
int b = 20;
void printB();
}
class A implements printA, printB {//一个类可以实现多个接口
public void printA() {
System.out.println(1);//必须实现接口内的所有方法
}
public void printB() {
System.out.println(b);//b=20 来自接口 printB
}
}
class C {
int c = 30;
}
class D extends C implements printB, printA {//一个类最多可以继承一个类 但可以实现多个接口
void printA() { //同样D也必须实现接口内的全部方法
System.out.println("c");
}
public void printB() {
System.out.println(c);//c=30来自类C
}
}
输出结果
111
20
c
30
抽象类
抽象类必须用abstract修饰
抽象类可以用来约束子类必须有的方法和成员变量
public class Main {
public static void main(String[] args) {
Ason ason = new Ason();
ason.printA();
ason.printA(2);
}
}
abstract class A {
int a;//这里a不必赋值 但是在接口中这里的a必须是一个常量
int b;
abstract void printA();//抽象方法不可以有方法体
}
class Ason extends A {
int a = 10;
void printA() { //抽象类的子类必须实现所有抽象方法 但是可以不实现抽象的成员变量
System.out.println(a);
}
void printA(int a) {//实现完规定的抽象方法后才可以重载 这里和接口不同
System.out.println(a);
}
}
输出结果:
0
2