多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
多态的优点
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
多态存在的三个必要条件
继承
重写
父类引用指向子类对象
简单来说:父类对象引用子类实例
public static void main(String[] args) {
Father f=new Son();
f.method();
}
输出:
我是父类的成员方法
public static void main(String[] args) {
Father f=new Son();
f.method();
}
//这里是重写了父类的method();方法
public class Son extends Father {
public void method(){
System.out.println("我是子类的成员方法,我复写了父亲");
}
}
输出:
我是子类的成员方法,我复写了父亲
那么同时都是调用f.method();,为什么会有两种结果了。
教你一个口诀:调用向左看,执行向右看,第二种是因为你重写了父类的方法,盖掉了
那么如果子类有一个属于自己的方法,那么父类不拥有子类这独特的方法,也就是是说
子类的方法必须通过子类 。方法();去使用(为了方便看到打点我借用了中文),那么
此时我们就需要强转了
强转规则:
1, 具有继承(实现)关系,否则报编译错误。
2, 见图:向下转型需要强转 ,向上转型不需要强转
public class Son extends Father {
public void study(){
System.out.println("我是子类要好好学习");
}
}
public class Demo {
public static void main(String[] args) {
Father f=new Son();
((Son)f).study();
}
}
输出:
我是子类要好好学习
Instanceof
如果左边操作数类型跟右边的类型必须有父子关系,否则报编译错误
这个通过代码看吧
public class Demo01 {
public static void main(String[] args) {
Person p1 = new Student();
Person p2 = new Teacher();
Student s1 = (Student) p1;
System.out.println(p1 instanceof Student);
method(p1);
method(p2);
}
public static void method(Person p){
//通过instanceof判断是Student类还是Teacher类
if(p instanceof Student ){
Student s =(Student) p;
s.study();
}else if(p instanceof Teacher ){
Teacher t =(Teacher) p;
t.study();
}
}
}
public class Person extends Object{
//Object万类之祖
}
public class Student extends Person{
public void study(){
System.out.println("好好学习,天天向上....");
}
}
public class Teacher extends Person{
public void study(){
System.out.println("好好备课,好好工作....");
}
}
输出:
true
好好学习,天天向上....
好好备课,好好工作....
静态关键字
类加载的时候会执行一次静态关键字
非静态的可以调用静态的方法
静态方法中不能直接访问同一个类的非静态成员,只能直接调用同一个类中的静态成员。只能通过对象实例化后,对象.成员方法的方式访问非静态成员。
静态方法中不能使用this(this代表当前实例,static代表类共享,所以两者是冲突的。)
代码块:
执行顺序:(优先级从高到低。)静态代码块>mian方法>构造代码块>构造方法。
方法里的{}叫普通代码块(顺序执行,先出现,先执行)
类中的{}叫构造代码块(创建对象时调用,优先于构造方法执行,每次实例化对象的时候都调用)
在构造代码块前加static,叫静态代码块(类加载时调用,优先于构造代码块执行,不管实例化几次,只调用一次,访问非静态成员与静态方法类似)