一、多态
1.1、多态概念
例:动物中猫,狗。
猫这个对象对应的类型是猫类型:猫 x = new 猫();
同时猫也是动物中的一种,也可以把猫称为动物:动物 y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向了子类对象。
父类或者接口的引用指向或者接收自己的子类对象。
作用:
多态的存在提高了程序的扩展性和后期可维护性。
前提:
1. 需要存在继承或者实现关系。
2. 需要有覆盖操作。
好处:
提高了代码的扩展性,前期定义的代码可以使用后期的内容。
1.2、2种类型
向上转型和向下转型
1.3、向上转型
声明时为父类的类型,如动物 小鸟=new 小鸟();
但运行时为子类的类行
任何子类存在的地方都可以用父类来替代
package com.day08.doutai.demo1; public abstract class Animal { private String name; private String gender; /** * 吃饭方法 */ public abstract void eat(); public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
package com.day08.doutai.demo1; /** * 小鸟吃虫子 * @author denny * */ public class Bird extends Animal { @Override public void eat() { System.out.println("小鸟吃虫子"); } public void fly(){ System.out.println("小鸟在天上飞"); } }
package com.day08.doutai.demo1; /** * 小狗吃骨头 * @author denny * */ public class Dog extends Animal { @Override public void eat() { System.out.println("小狗吃骨头"); } public void run(){ System.out.println("小狗在地上跑!"); } }
package com.day08.doutai.demo1; /** * 小猪类 * @author denny * */ public class Pig extends Animal { @Override public void eat() { System.out.println("小猪吃杂食!"); } public void sleep(){ System.out.println("小猪在睡觉!"); } }
测试类
package com.day08.doutai.demo1; /** * 多态向上转型 * 声明状态进为父类 * 运行时状态为子类 * @author denny */ public class AnimalTest1 { public static void main(String[] args) { //声明小狗 Animal dog=new Dog(); //声明小猪 Animal pig=new Pig(); //声明小鸟 Animal bird=new Bird(); getAnimal(dog); getAnimal(pig); getAnimal(bird); } public static void getAnimal(Animal a){ a.eat(); } }
结果:
小狗吃骨头 小猪吃杂食! 小鸟吃虫子
1.4、向下转型
判断是不是子类,是就强制类型转换
intanceof 关键字来判断
以上类不变
package com.day08.doutai.demo1; /** * 多态向上转型 * 声明状态进为父类 * 运行时状态为子类 * @author denny */ public class AnimalTest1 { public static void main(String[] args) { //声明小狗 Animal dog=new Dog(); //声明小猪 Animal pig=new Pig(); //声明小鸟 Animal bird=new Bird(); getAnimal(dog); getAnimal(pig); getAnimal(bird); } public static void getAnimal(Animal animal){ //判断是不是 小狗类 if(animal instanceof Dog){ Dog dog=(Dog)animal; dog.run(); //判断 是不是小鸟 }else if(animal instanceof Bird){ Bird bird=(Bird)animal; bird.fly(); }else if(animal instanceof Pig){ Pig pig=(Pig)animal; pig.sleep(); } } }
结果:
小狗在地上跑! 小猪在睡觉! 小鸟在天上飞
1.5、简单工厂
package com.day08.doutai.demo1; public class AnimalFactory { Animal an; public Animal getAmincal(String animal){ if(animal.equalsIgnoreCase("bird")){ an=new Bird(); }else if(animal.equalsIgnoreCase("pig")){ an=new Pig(); }else if(animal.equalsIgnoreCase("dog")){ an=new Dog(); }else{ System.out.println("没这个动物"); } return an; } }
测试类
package com.day08.doutai.demo1; public class Test1 { public static void main(String[] args) { //声明一个工厂类 AnimalFactory factory=new AnimalFactory(); Animal animal =factory.getAmincal("dog"); animal.eat(); } }
结果:
小狗吃骨头
1.6、多态中成员变量的特点
成员函数特点:
在编译时期:参阅引用类型变量所属类中是否有这个调用方法,如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用这个方法。
简单:成员函数在多态调用时,编译看左边,运行持右边
无论编译和运行,都参考左边(引用类型变量所属的类)。
静态成员,也是都参考左边
package com.day08.demo1; /** * 父类 * @author Denny * */ public class Fu { //成员变量 int num=5; } package com.day08.demo1; public class Zi extends Fu { int num=8; } package com.day08.demo1; public class Test1 { public static void main(String[] args) { Fu f=new Zi(); System.out.println(f.num); //5 Zi z=new Zi(); System.out.println(z.num); //8 } }
结果:
5
8
二、Object类
2.1、Object类
Object类是所有类的根类(间接父类),Java对象中最顶级的类。
这个类中定义了所有对象都具备的功能
2.2、equalse()方法
package com.day08.objec.demo1; /** * 人类 * @author Administrator * */ public class Person { /** * 姓名 * 年龄 * 性别 */ private String name; private int age; private String gender; /** * getter和setter方法 * @return */ public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
测试类
package com.day08.objec.demo1; public class Test1 { public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person(); Person p3 = p1; System.out.println(p1 == p2); System.out.println(p1.equals(p2)); System.out.println(p1 == p3); System.out.println(p1.equals(p3)); } }
结果:
false
false
true
true
重写equals方法
/** * 重写equalse方法 */ @Override public boolean equals(Object obj) { //判断是不是这个对象 if(this==obj){ return true; } //判断 如果是空值就返回false if(null==obj){ return false; } if(obj instanceof Person){ Person p=(Person)obj; return name.equals(p.getName())&&age==p.getAge()&&gender.equals(p.getGender()); }else{ return false; } }
测试
package com.day08.objec.demo1; public class Test1 { public static void main(String[] args) { Person p1 = new Person(); p1.setName("张三"); p1.setAge(20); p1.setGender("男"); Person p2 = new Person(); p2.setName("李四"); p2.setAge(21); p2.setGender("女"); Person p3 = p1; p3.setName("张三"); p3.setAge(20); p3.setGender("男"); System.out.println(p1.equals(p2)); System.out.println(p1.equals(p3)); System.out.println(p1.hashCode()); System.out.println(p2.hashCode()); System.out.println(p3.hashCode()); } }
结果:
false
true
705927765
366712642
705927765
2.3、toString()类
toString=getClass().getName+@+Integer.toHexString(hasCode())
还是上面的Person类
package com.day08.objec.demo1; public class Test2 { public static void main(String[] args) { Person p1 = new Person(); System.out.println(p1.toString()); //默认为十六进制 System.out.println(p1.hashCode());//默认为10进制 System.out.println(Integer.toHexString(p1.hashCode())); //转换为十六进制 System.out.println(p1.getClass().getName()+"@"+Integer.toHexString(p1.hashCode())); } }
结果:
com.day08.objec.demo1.Person@2a139a55
705927765
2a139a55
com.day08.objec.demo1.Person@2a139a55