多态
动态编译,通过多态增加可拓展性。
注意事项:
-
多态是方法的多态,属性没有多态
-
父类与子类,有联系 类型转换异常
-
存在条件:继承关系;方法需要重写,如果没有重写,父子中的方法都不同,那就是各自执行各自的,也就不存在多态,重写后,两个类型里都有那个方法,那就执行子类的(子类能够从写父类),父类引用指向子类对象:Father s1 = new Son();太长不看系列:1.重写,2.父类引用指向子类对象
static 方法,属于类,不属于实例,不能重写
final 常量,不能重写
privat 私有的无法重写
1.多态即同一个方法可以根据发送对象的不同而采用多种不同的行为方式。
2.一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(他有很多个爹,父类引用可以指向子类对象)
package OOP02.Demon4;
public class Person {
public void run(){
System.out.println("run");
}
}
package OOP02.Demon4;
public class Student extends Person{
@Override
public void run() {
System.out.println("ru");
}
public void eat(){
System.out.println("eat");
}
}
package OOP02.Demon4;
public class Application {
public static void main(String[] args) {
// 一个对象的实际类型是确定的(右边)
//new Person();
//new Student();
//可以指向的引用类型就不确定了(左边)
//父类的引用指向子类
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
s2.run(); //ru
s1.run(); //ru 子类重写父类的方法
//=====================================================================
//对象能执行那些方法,主要看对象对边的类型。和右边关系不大
// s2.eat();会报错 s2里没有eat方法。
((Student) s2).eat(); //eat 将s2类型从Person强制转换为Student类型。
s1.eat(); //eat
//
/*
例如Student类型的对象s1能调用的方法为Student类型里的,和从父类(Person Object)继承来的
Person类型的对象s2能调用的方法为Person类型里的,和从父类(Object)继承来的
*/
}
}
instanceof
instanceof 用于判断两个是否有关系,在下方程序中会有演示
x instanceof Y;
能否编译通过,看大的(大的指引用类型,引用类型大于或等于实际类型,故称它为大的。父类引用类型可以指向子类对象)是否与Y有父子关系。
真或假再看实际类型(即小的)是否与Y有父子关系。
这么设计的逻辑为:如果我的爹(我的上一级,我i的更大范围)都与你(Y)没有父子关系,更无需判断我是否与你(Y)有父子关系,结果必然没有关系,而且可以称之为八竿子打不着。
以上逻辑可以再下方程序的
Student student = new Student();
//引用类型 变量名 = new 实际类型()
部分进行进一步理解。
package OOP02.Demon5;
public class Person {
public void run(){
System.out.println("run");
}
}
package OOP02.Demon5;
public class Student extends Person {
public void go(){
System.out.println("go");
}
package OOP02.Demon5;
public class Teacher extends Person{
}
package OOP02.Demon5;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
public class Application {
public static void main(String[] args) {
//Object > Person > Student
//Object > Person > Teacher
//Object > String
Object object = new Student();
//x instanceof Y;
//真或假取决于:x指向的实际类型是不是Y的子类型
//能不能编译通过:取决于x的引用类型和Y有没有父子关系
//即引用类型有父子联系的情况下(编译通过),才能通过instanceof判断是否有关系(真或假)。
System.out.println(object instanceof Object);//T
System.out.println(object instanceof Person);//T
System.out.println(object instanceof Student);//T
System.out.println(object instanceof Teacher);//F
System.out.println(object instanceof String);//F
System.out.println("=======================");
Person person = new Student();
System.out.println(person instanceof Object);//T
System.out.println(person instanceof Person);//T
System.out.println(person instanceof Student);//T
System.out.println(person instanceof Teacher);//F
//System.out.println(person instanceof String);//编译就报错
//有没有关系得注意他的实际类型啊!person的实际类型为Student,左边的为引用类型(Person)
System.out.println("=======================");
Student student = new Student();
System.out.println(student instanceof Object);//T
System.out.println(student instanceof Person);//T
System.out.println(student instanceof Student);//T
//System.out.println(student instanceof Teacher);//编译报错
//System.out.println(student instanceof String); //编译报错
}
}
类型转换
强制转换格式:(类型)变量
为了方便方法的调用,通过升降级可以减少重复的代码,使代码变得更简洁。
package OOP02.Demon5;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
public class Application {
public static void main(String[] args) {
//类型转换 在基本类型中 低转高可以自动转换,高转低需要强制转换(64转32)
//将高类型转为低类型
// 父转子为高转低,需要强制转换,子转父不需要强制转换,如:
//注意:子类转换为父类,可能会丢失自己一些方法
Person student = new Student();
//student.go(); 这里报错了,因为go方法为子类Student独有,父类Person没有;
//将高类型转为低类型:
//Person转为Student
Student OBJ= (Student) student;
OBJ.go(); //输出 go
//或
((Student) student).go();
//这里就可以运行go方法并成功输出"go“
//强制转换格式:(类型)变量
}
}