【15-1】面向对象-多态-好处&弊端&前提 //描述狗 class Dog extends Animal { public void eat() { System.out.println("吃饭"); } public void lookHome() { System.out.println("看家"); } } //描述猫 class Cat extends Animal { public void eat() { System.out.println("鱼"); } public void catchMice() { System.out.println("抓老鼠"); } } //进行抽取,将共性的功能抽取到父类Animal中。 abstract class Animal { public abstract void eat(); } class DogAndCatTest { public static void main(String[] agrs) { //Dog d = new Dog(); //method(d); Animal a = new Dog(); method(a); //Cat c = new Cat(); method(new Cat()); } /* 发现,每一个动物,都需要为这个动物单独定义一个功能。 让这个动物的对象去做事。 这个程序扩展性很差。 如何提高这个扩展性呢? 发现,既然是让动物去吃,无论是Dog还是Cat, eat是它们的共性,于是就可以将eat进行抽取,抽取到父类中。 Dog是Animal中的一种。 Dog d = new Dog(); Ainmal a = new Dog(); Cat c = new Cat(); Animal aa = new Cat(); */ //只要去建立Animal的引用,就可以接收所有的dog对象进来,让它们去eat //提高了程序的扩展性。 public static void method(Animal a) { a.eat(); } /* //接收Dog,让dog去做事 public static void method(Dog d) { d.eat(); } //接收Cat让Cat去做事 public static void method(Cat c) { c.eat(); } */ } ======================================================================================================== //15-2的完整例子如下: //抽象类 动物 abstract class Animal { public abstract void eat(); } //描述Dog class Dog extends Animal { public void eat() { System.out.println("吃饭"); } public void lookHome() { System.out.println("看家"); } } //描述猫 class Cat extends Animal { public void eat() { System.out.println("鱼"); } public void catchMice() { System.out.println("抓老鼠"); } } class DuoTaiTest { public static void main(String[] args) { //Dog d = new Dog(); //method(d); //Cat c = new Cat(); //method(c); Animal a = new Dog(); //method(a); a.eat(); //Animal a1 = new Dog(); //method(a1); if(a instanceof Dog) { Dog d = (Dog)a; d.lookHome(); } } //public static void method(Animal a) //{ // a.eat(); //} } =========================================================================================================== 【15-2】面向对象-多态-转型 //描述狗 class Dog extends Animal { public void eat() { System.out.println("吃饭"); } public void lookHome() { System.out.println("看家"); } } //描述猫 class Cat extends Animal { public void eat() { System.out.println("鱼"); } public void catchMice() { System.out.println("抓老鼠"); } } //进行抽取,将共性的功能抽取到父类Animal中。 abstract class Animal { public abstract void eat(); } /* 多态:体现 父类的引用或者接口指向了自己的子类对象。 Dog d = new Dog(); //Dog对象的类型是Dog类型。 Animal a = new Dog(); //Dog对象的类型右边是Dog类型,左边是Animal类型。 好处: 提高了程序的扩展性。 弊端: 通过父类引用操作子类对象时,只能使用父类中已有的方法,不能操作子类特有的方法。 前提: 1,必须有关系,继承或实现。 2,通常都有重写操作 子类的特有方法如何调用呢? Animal a = new Dog(); //Animal是父类型,new Dog()是子类对象。 但是父类型引用指向子类对象时,这就是让子类对象进行了类型的提升(向上转型), 如果想要使用子类的特有方法,只有子类型可以用。 可以向下转型,强制转换。 Animal a = new Dog(); a.eat(); Dog d = (Dog)a;//将a转型为Dog类型。向下转型 d.lookHome(); //此时就可以用这个子类的特有功能了。 向下转型什么时候用?当需要使用子类型的特有内容时。 注意:无论向上还是向下转型,最终都是子类对象做着类型的变化。 向下转型的注意事项: Animal a = new Dog(); //Cat c = (Cat)a; //向下转型因为不明确具体子类对象类型,所以容易引发ClassCastException异常。 所以为了避免这个问题,需要在向下转型前,做类型判断。 判断类型用的是关键字。instanceof if(a instanceof Cat) //a指向的对象类型是Cat类型。 { //将a转型为Cat类型。 Cat a = (Cat)a; c.catchMouse(); } else if(a instanceof Dog) { Dog d = (Dog)a; d.lookHome(); } 转型总结 1,什么时候向上转型呢? 提高程序的扩展性,不关心子类型(子类型被隐藏) 需要用子类的特有的方法吗?不需要,那就向上转型。 2,什么时候使用向下转型呢? 需要使用子类特有的方法时。 但是一定要使用instaceof 进行类型的判断,避免发生ClassCastException异常 */ class DogAndCatTest { public static void main(String[] agrs) { Dog d = new Dog(); method(d); Cat c = new Cat(); method(c); } public static void method(Animal a) { a.eat(); } } 【15-2】面向对象-多态-举例 //多态-举例 class 毕姥爷 { public void 讲课() { System.out.println("讲管理"); } public void 钓鱼() { System.out.println("钓鱼"); } } class 毕老师 extends 毕姥爷 { public void 讲课() { System.out.println("Java"); } public void 看电影() { System.out.println("看电影"); } } class DuoTaiTest { public static void main(String[] args) { 毕姥爷 x = new 毕老师(); x.讲课(); x.钓鱼(); //x.看电影();//不行 //想要使用毕老师的特有方法时,需要 if(x instanceof 毕老师) { 毕老师 y = (毕老师)x; y.看电影(); } } } ----------------------------------------- 【15-3】面向对象-多态-练习-笔记本电脑 ========================================================================================================= //描述笔记本,用到了鼠标的功能。 class noteBook { public void run() { System.out.println("notebook run"); } public void useMouse(Mouse m) { if(m!=null) { m.open(); m.close(); } } } //描述鼠标。 class Mouse { public void open() { System.out.println("mouse open"); } public void close() { System.out.println("mouse close"); } } class NoteTest { public static void main(String[] args) { noteBook b = new noteBook(); b.run(); b.useMouse(new Mouse()); } } ========================================================================================== /* 阶段一需要,笔记本电脑运行。 按照面向对象的思想,用代码体现。 名称提炼法。 笔记本电脑。 行为,运行。 class HoteBook { //运行功能 public void run() { System.out.println("notebook run"); } } 阶段二需求:想要在笔记本电脑上加上一个手提式鼠标。 多了个对象,鼠标。 行为:开启,关闭。 class Mouse { public void open() { System.out.pritnln("mouse open"); } public void close() { System.out.println("mouse close"); } } //笔记本怎么用这鼠标呢? 在笔记本中多一个使用鼠标的功能. 需要修改原来的笔记本类中的内容,添加一个功能。 class NoteBook { //运行功能 public void run() { System.out.println("notebook run"); } //使用鼠标的功能 public void useMouse(Mouse m) { if(m!=null) { m.open(); m.close(); } } } //如果想要加入键盘呢? */ class Mouse { public void open() { System.out.println("mouse open"); } public void close() { System.out.println("mouse close"); } } class NoteBook { //运行功能 public void run() { System.out.println("notebook run"); } //使用鼠标的功能 public void useMouse(Mouse m) { if(m!=null) { m.open(); m.close(); } } } class DuoTaiTest2 { public static void main(String[] args) { NoteBook book = new NoteBook(); book.run(); book.useMouse(new Mouse()); } } -------------------------------------------- 【15-4】面向对象-多态-成员变量&成员函数&静态函数的特点 =================================================================================================== /* 多态中,成员调用的特点。 1,成员变量。 当子父类中出现了同名的成员变量时, 多态调用该变量时。 编译时期,参考的是引用变量所属的类中是否有被调用的成员变量,没有,编译失败。 运行时期,也是调用引用变量所属的类中的成员变量。 简单记:编译和运行都参考等号左边 编译运行看左边 2,成员函数。 编译,参考左边,如果没有,编译失败。 运行,参考右边的对象所属的类。 编译看左边,运行看右边。如果子类没有和父类同名的那个函数,则运行的是父类的那个函数。 对于成员函数是动态绑定对到对象上。 3,静态函数。 对于静态成员函数,编译和运行都参考左边。 对于静态函数是静态的绑定到类上。 */ //结论: //对于成员变量和静态函数,编译和运行都看左边。 //对于成员函数,编译看左边,运行看右边。 class Fu { int num = 3; void show() { System.out.println("fu show run"); } static void method() { System.out.println("fu static method run"); } } class Zi extends Fu { int num = 5; void show() { System.out.println("zi show run"); } static void method() { System.out.println("zi static method run"); } } class DuoTaiDemo { public static void main(String[] args) { /* //测试成员变量的多态调用 Fu f = new Zi(); System.out.println(f.num); //3 Zi z = new Zi(); System.out.println(z.num); //5 */ /* //测试成员变量的多态调用 Fu f = new Zi(); f.show(); //结果:zi show run; */ //测试静态函数的多态调用。 Fu f = new Zi(); f.method(); //注意:真正开发静态方法是不会被多态调用的,因为静态方法不所属于对象,而是所属于类的。 Fu.method(); } }
原文:http://www.cnblogs.com/sun-/p/5208791.html