1.方法覆写
1.1 是什么
Override 方法覆写,子类覆写父类的方法,
方法名、参数列表、返回值 必须相同
不能比原方法有更低的访问权限,权限控制必须大于等于原方法
不能比原方法有更宽泛的异常,异常要小于等于原方法
覆写 前提条件 : 必须是有继承关系
Overload 方法重载 : 方法名相同参数列表不同,列表可以是个数不同或类型不同
当父类功能无法满足子类需求的时候,需要对父类功能进行重写
1.2. 怎么用
1.3.@Override
@Override : 注解,是源码注解,编译后就没了,就被删除了
可以写,可以不写,只是一种提醒机制,防止我们写错代码,导致该方法并没有产生覆写
加上该注解后,如果不符合覆写条件,则会提醒报错
2.Final
2.1 是什么
final 是修饰符,表示最终的,不可修改的
2.2 能做什么
Final 是修饰符, 表示最终的,不可修改的
类 : Final修饰的类不能被继承
变量 : Final修饰的变量是常量,没有默认值,不能二次赋值(值在生命周期内不可修改)
方法 : Final修饰的方法,不能被覆写
2.3. 怎么用
2.4. 修饰引用类型
final修饰的引用类型变量, 变量值不能修改,但是变量指向的对象中的值,如果没有fianl修饰,是可以修改的
3.多态
3.1. 是什么
多态 polymorphic : 多种形态,相同功能,不同的对象有不同的状态
多态 : 父类引用指向子类对象
父类 : 长辈,直接父类,或者间接父类(爷爷、爷爷的爷爷....Object)
引用 : 指的引用数据类型
指向 : 就是可以找到谁
子类对象 : 创建了一个子类的实例化对象 new
使用父类类型创建的引用类型变量,可以找到子类对象
父类 变量名 = new 子类();
多态又叫向上转型 , 由子类 到父类 是向上 类似于自动类型转换
向下转型 , 由父类 到子类,类似于强制类型转换,但是 必须先发生向上转型之后,才能发生向下转型
3.2 相关知识
里氏替换原则 : 能使用父类的地方,就一定可以使用子类
3.3.应用场景
只要是一种情况对应多种不同实现的时候,一定要使用多态
3.4. 优点
降低耦合度,扩展性、替换性、维护性、灵活性增强
3.5.缺点
丢失子类特有的属性
使用多态进行属性调用 :
1 子类特有的,调用不了,因为多态的缺点就是丢失子类特有的属性
2 成员方法 : 如果子类覆写了父类的成员方法,则调用子类的成员方法
3 非成员方法 : 调用父类的
3.6 使用语法
3.7. Instanceof
java.lang.ClassCastException: _07_Poly.Sup cannot be cast to _07_Poly.Sub
类型转换异常
* Instanceof : 判断 某个对象是否由每个类实例化而来
*
* 防止向下转型出现错误
public static void main(String[] args) {
Sup sup = new Sub();
// Sup sup = new Sup();
Sub sub = null;
System.out.println(sup instanceof Sub);
if (sup instanceof Sub) {
sub = (Sub) sup;
}
System.out.println(sub);
}
3.8. 多态的几种形式
3.9.隐式多态
通过子类对象,调用继承父类的成员方法时,此时上下文环境为多态环境
public class Poly_05 {
public static void main(String[] args) {
// Sup1 sup = new Sub1();
// // 2 父类
// System.out.println(sup.age);
// // 父类 因为子类没有
// sup.m1();
// // 子类 因为覆写
// sup.m2();
// // 报错,因为父类没有,多态会丢失子类特有属性
// // sup.m3();
// // 向下转型
// Sub1 sub = (Sub1) sup;
// // 1 子类
// System.out.println(sub.age);
// // 父类 继承
// sub.m1();
// // 子类 因为子类有
// sub.m2();
// // 子类,又没有使用多态
// sub.m3();
Sub1 sub = new Sub1();
sub.m1();
}
}
class Sup1 {
int age = 2;
int sakjdkashdhqwrjnfaksf = 2;
public void m1() {
/**
* this : 是对象中第一个成员变量,保存当前对象的内存地址
*
* this既然保存当前对象内存地址,那么this的类型 可以是当前类类型,可以是父类类型
*
* this写在哪个类中,哪个类就是当前类 所以 当前类 是Sup1 父类 是 Object
*
* 因为this能调用当前类中所有的属性,并没有丢失,所以this是Sup1 当前类类型
*
* Sup1 this;
*
* this : 哪个对象调用这个成员方法,this就指向谁
*
* 最终是Sub1调用的m1方法,所以this 指向 Sub1
*
* Sup1 this = Sub1;
*/
// System.out.println("父类m1");
System.out.println(this);
// 2 父类
System.out.println(this.age);
System.out.println(this.sakjdkashdhqwrjnfaksf);
System.out.println(age);
// 子类
m2();
// 报错
// m3();
}
public void m2() {
System.out.println("父类m2");
}
}
class Sub1 extends Sup1 {
int age = 1;
public void m2() {
System.out.println("子类m2");
}
public void m3() {
System.out.println("子类m3");
}
}