多态:可以理解为事物存在的多种表现形态。
人:男人,女人。
动物:猫,狗。
猫x = new 猫();
动物 x = new 猫();
1.多态的体现
父类的引用指向了自己的子类对象。 动物 x = new 猫();
父类的引用也可以接收自己的子类对象。
2.多态的前提
必须是类与类之间有关系,要么继承,要么实现。
通常还有一个前提:存在覆盖。
3.多态的好处
多态的出现大大提高了程序的扩展性。
4.多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员
5.多态的应用
6.多态注意事项
需求:动物-》猫,狗。
abstract class Animal { public abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void catchMouse() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void kanJia() { System.out.println("看家"); } } class Pig extends Animal { public void eat() { System.out.println("吃饲料"); } public void gongDi() { System.out.println("拱地"); } } class day08 { public static void main(String[] args) { /* Cat c = new Cat(); function(c); function(new Dog()); function(new Pig()); */ //Animal c = new Cat(); //c.eat(); function(new Cat()); function(new Dog()); function(new Pig()); } /* public static void function(Cat c) { c.eat(); } public static void function(Dog d) { d.eat(); } public static void function(Pig p) { p.eat(); } */ public static void function(Animal a) { a.eat(); } }
改进:
abstract class Animal { public abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void catchMouse() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void kanJia() { System.out.println("看家"); } } class Pig extends Animal { public void eat() { System.out.println("吃饲料"); } public void gongDi() { System.out.println("拱地"); } } class day08 { public static void main(String[] args) { Animal a = new Cat();//类型提升,向上转型 a.eat(); //如果想要调用猫的特有方法时,如何操作? //强制将父类的引用,转成子类类型 Cat c = (Cat)a; c.catchMouse(); /*不允许,不能将父类对象转化成子类类型 我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升, 也可以被强制转换,多态自始至终都是子类对象在做着变化。 Animal a = new Animal(); Cat c = (Cat)a; a.catchMouse(); */ function(new Dog()); function(new Cat()); } public static void function(Animal a) { a.eat(); /*不能这样写. if(a instanceof Animal) { System.out.println("haha"); } */ if(a instanceof Cat)//判断传入的类型 { Cat c = (Cat)a; c.catchMouse(); } else if(a instanceof Dog) { Dog c = (Dog)a; c.kanJia(); } } }
需求:基础班学生:学习,睡觉。高级班学生:学习,睡觉。可以将这两类事物进行抽取。
abstractclass Student { publicabstract void study(); publicvoid sleep() { System.out.println("躺着睡"); } } class BaseStudent extends Student { publicvoid study() { System.out.println("basestudy"); } publicvoid sleep() { System.out.println("坐着睡"); } } class AdvStudent extends Student { publicvoid study() { System.out.println("advstudy"); } } class DoStudent { publicvoid doSome(Student stu) { stu.study(); stu.sleep(); } } class day08 { publicstatic void main(String[] args) { DoStudentds = new DoStudent(); ds.doSome(newBaseStudent()); ds.doSome(newAdvStudent()); } }
需求:电脑运行实例。电脑运行基于主板
interface PCI { public void open(); public void close(); } class MainBoard { public void run() { System.out.println("mainboard run"); } public void usePCI(PCI p) //PCI p = new NetCard()//接口型引用指向自己的子类对象 { if(p != null) { p.open(); p.close(); } } } class NetCard implements PCI { public void open() { System.out.println("netcard open"); } public void close() { System.out.println("netcard close"); } } class SoundCard implements PCI { public void open() { System.out.println("soundcard open"); } public void close() { System.out.println("soundcard close"); } } class day08 { public static void main(String[] args) { MainBoard mb = new MainBoard(); mb.run(); mb.usePCI(new NetCard()); mb.usePCI(new SoundCard()); } }
Object:是所有对象的直接或者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能。
equals()方法,两个对象进行比较,其实比较的是 地址值。
Object类中已经提供了对对象是否相同的比较方法。
如果自定义类中也有比较相同的功能,没有必要重新定义,只要沿袭父类中的功能,建立自己特有比价内容即可,这就是覆盖。
class Demo { private int num; Demo(int num) { this.num = num; } public boolean equals(Object obj) { //错误写法 :obj里没有num 变量return this.num == obj.num; if(!(obj instanceof Demo)) return false; Demo d = (Demo)obj; return this.num == d.num; } } class Person { } class day08 { public static void main(String[] args) { Demo d1 = new Demo(4); Person p = new Person(); System.out.println(d1.equals(p)); } }
Demo d1 = new Demo(4);
System.out.println(Integer.toHexString(d1.hashCode()));
System.out.println(d1.toString());
输出:
2a139a55
Demo@2a139a55