final修饰的类:
被修饰后别的类就不能再继承这个类了,也就是被fianl修饰的类没有子类
那么final可以修饰抽象类和接口吗?显然不行。因为抽象类需要子类继承,实现抽象方法,才能够被实例化。
final class FinalA{
}
//被final修饰后的类就不能再被继承,故以下代码报错
class B extends FinalA{
}
被final修饰的方法呢?什么?你说:我没听过,这个方法不陌生吧getClass()获取当前对象所属的类
被final修饰了的方法就是最终的方法,子类不能再重写这个方法了
class AA{
public final void show(){
}
}
//被final修饰的方法不能被子类重写,一下代码会报错
class BB extends AA{
public void show(){
}
}
final还可以修饰属性,
final修饰变量以后,感觉就像定义了一个常量一样,所以变量名都大写了。
而且你不能用set方法赋值(因为该变量是不可以改变的)
final修饰属性,可以考虑的赋值方式有三种:显示初始化,代码块中初始化,构造器中初始化。
public class FinalTest{
final int WIDTH=0; //显示初始化
final int LEFT;
final int RIGHT;
{
LEFT=1;//代码块中初始化
}
public FinalTest(){
RIGHT=2;//构造器中初始化
}
}
final修饰形参的话,就更要注意了。那么这个形参就只能被调用而不能被改变。
public void show(){
final int NUM=10;//常量
NUM+=20;//报错,因为常量不可变
}
真反人类的用法
public void show(final int num){
num=20;//编译不会通过
}
最后,老师笔记:
equals关键字,讲这个之前先普及一下"=="
- ==比较基本类型,就是比较值。
- ==比较引用类型,就是比较内存地址。
==比较基本类型
public static void main(String[] args) {
int i = 10;
int j = 10;
double d = 10.0;
System.out.println(i == j);//true
//“==”,在比较俩个基本类型的时候类型可以不相同,之所以结果是true,实际上是做了类型提升
System.out.println(i == d);//true
}
==比较引用类型
public static void main(String[] args) {
Cat cat1 = new Cat();
Cat cat2 = new Cat();
System.out.println(cat1==cat2);//false
System.out.println("==========================");
String str1= new String("abc");
String str2= new String("abc");
System.out.println(str1==str2);//false
}
使用equals比较引用类型
Object类中定义的equals()方法和==的作用是相同的,比较俩个对象的地址值是否相同。第二个结果之所以是true,因为String类重写了Object类中的equals()方法,重写之后比较的不再是引用地址是否相同,而是比较俩个对象的“实体内容”是否相同。
public static void main(String[] args) {
Cat cat1 = new Cat();
Cat cat2 = new Cat();
System.out.println(cat1.equals(cat2));//false
System.out.println("==========================");
String str1= new String("abc");
String str2= new String("abc");
//String类重写了Object类的equals方法。
System.out.println(str1.equals(str2));//true
}
自定义类重写equals方法
实际上我们想让我们自定义的类也比较一下俩个对象的内容是否一样。那我们就得在自定义的类中重写equals()方法了。
先来看看人家String类是怎么重写equals()方法的,学习学习
public boolean equals(Object anObject) {
if (this == anObject) {
//要是引用地址都一样,直接就相等了,不需要再折腾的去判断内容是否相等了
return true;
}
//俩个都是字符串才有可比性,传参都不是字符串,直接返回false
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
紧接着,我们就要在自己定义的类中去重写一个equals()
public class Cat extends Animal {
public Cat() {
super();
}
public Cat(String name) {
this.name = name;
}
public void CatchMouse() {
System.out.println("抓老鼠");
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
//要是引用地址都一样,直接就相等了,不需要再折腾的去判断内容是否相等了
return true;
}
if (obj instanceof Cat) {
Cat cat = (Cat) obj;
if (cat.name.equals(this.name)) {
return true;
} else {
return false;
}
}
// 简化写法
// if (obj instanceof Cat) {
// Cat cat = (Cat) obj;
// return cat.name.equals(this.name);
// }
return false;
}
}
测试程序:
public static void main(String[] args) {
Cat cat = new Cat();
cat.name="小西";
Cat cat1 = new Cat("小西");
Cat cat2 = new Cat("小西");
System.out.println(cat.equals(cat1));//true
System.out.println(cat1.equals(cat2));//true
System.out.println("==========================");
String str1= new String("abc");
String str2= new String("abc");
//String类重写了Object类的equals方法。
System.out.println(str1.equals(str2));//true
}
运行结果: