动态编译类型 - 同一方法能够根据发送对象的不一样而采用多种不一样的行为方式。java
一个对象的实际类型是肯定的,但能够指向对象的引用的类型有不少。ide
注意:多态是方法的多态,属性没有多态性oop
instanceof测试
一个对象的实际类型是肯定的code
new Student();对象
new Person();继承
可是,能够指向的引用类型就不肯定了编译器
子类重写了父类的方法,就执行子类的方法io
没法被重写的方法(修饰符):编译
static 静态方法 - 方法,属于类,而不属于实例
final 常量
private 私有方法也不能被重写
被这三个修饰符修饰的方法没法被重写,因此也没法实现多态
若是没有“重写Override”,不能重复方法/方法名
package oop.Demo06; public class Person { public void run(){ System.out.println("run"); } }
package oop.Demo06; public class Student extends Person { //重写在父类Person的run方法,今后父类子类都执行此处的方法 @Override public void run() { System.out.println("son"); } //父类Person没有这个方法-eat,所以在测试里,父类Person没法调用此方法 public void eat(){ System.out.println("eat"); } }
package oop; import oop.Demo05.A; import oop.Demo05.B; import oop.Demo06.Person; import oop.Demo06.Student; public class Application { public static void main(String[] args) { //一个对象的实际类型是肯定的 //new Student(); //new Person(); new Person/Student后就是new Person/Student //可是,能够指向的引用类型就不肯定了: 父亲的引用指向子类 // 也就是 y与x, 多个x能够获得相同的y值 //子类"Student"能执行的方法都是本身的或是继承父类的! Student s1 = new Student(); // 子类指向的引用 //父类Person能够指向子类"Student",可是不能够调用子类独有的方法 Person s2 = new Student(); // 父类指向的引用 Object s3 = new Student(); //由于Person是student的父类,Object是默认的父类因此,能够newStudent以这三种形式 //对象能执行那些方法,主要看对象左边的类型(父类、子类),和右边关系不大 s2.run(); // 父类Person //s2.eat(); 没法调用 s1.run(); //Student 类 s1.eat();//子类能够调用本身的方法eat //输出结果为 //son //son //都变成了son,经历过Override, 子类重写了父类的方法,就执行子类的方法 } }
instanceof (类型转换)
经过instanceof能够判断一个对象是什么类型
经过instanceof能够判断两个类之间是否存在父子关系
总结为公式:
System.out.println(x instanceof y); 编译器可否经过取决于x与y是否有父子类关系
怎么使用instanceof判断类与类之间的关系:
package oop; import oop.Demo05.A; import oop.Demo05.B; import oop.Demo06.Person; import oop.Demo06.Student; import oop.Demo06.Teacher; public class Application { public static void main(String[] args) { //Object > Person > Student//Teacher //Object > Person > Teacher //Object > String Object object = new Student(); //Object是Person的父类,Person是"Student"的父类 //使用new在object和 Student 创建了这种关系,那么使用instanceof验证一下 System.out.println(object instanceof Student); // True System.out.println(object instanceof Person); // True System.out.println(object instanceof Object); // True System.out.println(object instanceof Teacher); // False System.out.println(object instanceof String); // False System.out.println("========================"); Person person = new Student(); System.out.println(person instanceof Student); // True System.out.println(person instanceof Person); // True System.out.println(person instanceof Object); // True System.out.println(person instanceof Teacher); // False //System.out.println(person instanceof String); // False Person和String是平行关系,同级关系 !!编译器报错!! System.out.println("========================"); Student student = new Student(); System.out.println(student instanceof Student); // True System.out.println(student instanceof Person); // True System.out.println(student instanceof Object); // True //System.out.println(student instanceof Teacher); // False Student和Teacher是同级关系 !!编译器报错!! //System.out.println(student instanceof String); // False String和Student没有关系 !!编译器报错!! // 总结为公式: //System.out.println(x instanceof y); 编译器可否经过取决于x与y是否有父子类关系 } }
类型之间的转换
低转高是慢慢长大,高转低是返老还童,会失忆
//高 低 Person student = new Student(); //子类Student这个对象被new成父类Person, 低转高 OK //student.go(); //可是此时,student没法使用"Student"de方法go //student[父类Person]将这个对象转换为Student[子类Student],我么就可使用"Student"类型的方法了 Student student1 = (Student) student; //高转低, Person student -- Student student1 强制转换 ((Student) student).go(); //通过强制转换就可使用 更低一层-子类 的方法了 //子类转换为父类,可能会丢失一些本身的方法 /* 栗子: Object example = new Student(); //低转高 Student example2 = (Student) example; // ((Student) example).go(); */