Java多态、final与抽象类:面向对象编程进阶指南
面向对象高级(多态final抽象类)今天我们继续学习面向对象的语法知识我们今天学习的主要内容是多态、final、抽象。学会这些语法知识可以让我们编写代码更灵活代码的复用性更高。一、多态接下来我们学习面向对象三大特征的的最后一个特征——多态。1.1 多态概述什么是多态多态是在继承/实现情况下的一种现象表现为对象多态、行为多态。比如Teacher和Student都是People的子类代码可以写成下面的样子public class People { String name 父类; public void run(){ System.out.println(人会跑); } }public class Teacher extends People{ String name 老师; Override public void run() { System.out.println(老师跑的比较慢~~~); } // 独有功能 public void teach(){ System.out.println(老师教授Java~~~); } }public class Student extends People{ String name 学生; Override public void run() { System.out.println(学生跑的飞快~~~); } // 独有功能 public void study(){ System.out.println(学生好好学习~~~); } }public class Test1 { public static void main(String[] args) { // 目标认识多态 People p1 new Teacher(); System.out.println(p1.name); // 识别技巧: 编译看左边, 运行看右边 p1.run(); // 识别技巧: 编译看左边, 运行看右边 People p2 new Student(); System.out.println(p2.name); // 识别技巧: 编译看左边, 运行看右边 p2.run(); // 识别技巧: 编译看左边, 运行看右边 } }注意: 多态的前提: 有继承/实现关系存在父类引用子类对象存在方法重写。 多态的一个注意事项: 多态是对象、行为的多态Java中的属性(成员变量)不谈多态。1.2 多态的好处各位同学刚才我们认识了什么是多态。那么多态的写法有什么好处呢在多态形式下右边的对象是解耦合的更便于扩展和维护。怎么理解这句话呢比如刚开始p1指向Student对象run方法执行的就是Student对象的业务假如p1指向Teacher对象 run方法执行的自然是Teacher对象的业务右边对象可以随时切换后续业务随机改变。定义方法时使用父类类型作为形参可以接收一切子类对象扩展性更强更便利。public class Test2 { public static void main(String[] args) { // 目标掌握使用多态的好处 // 好处1:可以实现解耦合右边对象可以随时切换后续业务随机改变 People p1 new Student(); p1.run(); System.out.println(); Teacher t new Teacher(); go(t); Student s new Student(); go(s); } // 好处2:可以使用父类类型的变量作为形参可以接收一切子类对象。 // 参数People p既可以接收Student对象也能接收Teacher对象。 public static void go(People p){ System.out.println(开始------------------------); p.run(); System.out.println(结束------------------------); } }1.3 类型转换虽然多态形式下有一些好处但是也有一些弊端。在多态形式下不能调用子类特有的方法比如在Teacher类中多了一个teach方法在Student类中多了一个study方法这两个方法在多态形式下是不能直接调用的。多态形式下不能直接调用子类特有方法但是转型后是可以调用的。这里所说的转型就是把父类变量转换为子类类型。public class Test2 { public static void main(String[] args) { // 目标掌握使用多态的好处 // 好处1:可以实现解耦合右边对象可以随时切换后续业务随机改变 People p1 new Student(); p1.run(); // p1.study(); // 多态形式下不能调用子类特有的方法 // 想要调用就需要强制类型转换 Student s1 (Student) p1; s1.study(); //强制类型转换可能存在的问题:编译阶段有继承或实现关系就可以强制, 但是运行时可能会出现类型转换异常 // Teacher t1 (Teacher) p1; // 运行时: ClassCastException 类型转换异常 System.out.println(); Teacher t2 new Teacher(); go(t2); Student s2 new Student(); go(s2); } //好处2:可以使用父类类型的变量作为形参可以接收一切子类对象。 public static void go(People p){ System.out.println(开始------------------------); p.run(); System.out.println(结束------------------------); } }强转前Java建议使用instanceof关键字判断当前对象的真实类型再进行强转p instanceof Student 判断当前对象是否真实类型或者子类格式如下//如果p接收的是子类对象 if(父类变量 instanceof 子类){ //则可以将p转换为子类类型 子类 变量名 (子类)父类变量; }如果类型转换错了就会出现类型转换异常ClassCastException比如把Teacher类型转换成了Student类型.关于多态转型问题我们最终记住一句话原本是什么类型才能还原成什么类型