多态
多态
多态是封装,继承之后面向对象的三大特征之一,
多态的定义格式:就是父类的引用变量指向子类对象
父类类型 变量名 = new 子类类型();
变量名.方法名();
一个父类的方法可以被多个子类重写,在测试类调用的时候可以方便调用某一个子类重写的方法
多态成员的特点:
class Fu { int num = 4; } class Zi extends Fu { int num = 5; } class Demo { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num);//4 Zi z = new Zi(); System.out.println(z.num);//5 } }
成员变量在编译运行的时候看的都是等号左边,由于f是fu实例化的对象,所以会读取fu方法中的num=4,而,z是zi方法实例化的对象所以值是5
我们再来看一下成员方法
class Fu { int num = 4; void show() { System.out.println("Fu show num"); } } class Zi extends Fu { int num = 5; void show() { System.out.println("Zi show num"); } } class Demo { public static void main(String[] args) { Fu f = new Zi(); f.show(); } }
成员方法是编译看左边,运行看右边
转型
前面我介绍过变量的转型,今天我来介绍一下多态的转型,其方式有两种
1向上转型:当有子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程。
使用格式:
父类类型 变量名 = new 子类类型();
如:Person p = new Student();
2 向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。如果是直接创建父类对象,是无法向下转型的!
使用格式:
子类类型 变量名 = (子类类型) 父类类型的变量;
如:Student stu = (Student) p; //变量p 实际上指向Student对象
当用多态实例化一个对象之后,只能调用子类中重写的方法,若是想调用子类中特有的方法,就需要向下转型,
而多态本身就是向上转型的过程,所以向上转型不多说,
举例
/* 描述毕老师和毕姥爷, 毕老师拥有讲课和看电影功能 毕姥爷拥有讲课和钓鱼功能 */ class 毕姥爷 { void 讲课() { System.out.println("政治"); } void 钓鱼() { System.out.println("钓鱼"); } } // 毕老师继承了毕姥爷,就有拥有了毕姥爷的讲课和钓鱼的功能, // 但毕老师和毕姥爷的讲课内容不一样,因此毕老师要覆盖毕姥爷的讲课功能 class 毕老师 extends 毕姥爷 { void 讲课() { System.out.println("Java"); } void 看电影() { System.out.println("看电影"); } } public class Test { public static void main(String[] args) { // 多态形式 毕姥爷 a = new 毕老师(); // 向上转型 a.讲课(); // 这里表象是毕姥爷,其实真正讲课的仍然是毕老师,因此调用的也是毕老师的讲课功能 a.钓鱼(); // 这里表象是毕姥爷,但对象其实是毕老师,而毕老师继承了毕姥爷,即毕老师也具有钓鱼功能 // 当要调用毕老师特有的看电影功能时,就必须进行类型转换 毕老师 b = (毕老师) a; // 向下转型 b.看电影(); } }
学习到这里,面向对象的三大特征学习完了。
总结下封装、继承、多态的作用:
1 封装:把对象的属性与方法的实现细节隐藏,仅对外提供一些公共的访问方式
2 继承:子类会自动拥有父类所有可继承的属性和方法。
3多态:配合继承与方法重写提高了代码的复用性与扩展性;如果没有方法重写,则多态同样没有意义。
好了,面向对象的三大基本特征到此结束了,具体的使用后面会陆续介绍,明天我会跟新构造方法有关的东西