单态:这个对象只有惟一的一种状态java
Student s = new Student();数组
多态:这个对象存在多种状态。 是指同一行为,具备多个不一样表现形式。ide
1)要有继承或者实现的关系测试
2)方法的重写(若是没有方法重写,格式不会报错,这样的多态是没有任何意义)ui
3)父类的引用指向子类对象(父new子)或者父接口的引用指向实现类对象(父接口new实现类)this
父类类型 变量名 = new 子类对象(); 变量名.方法名(); eg: Animal dog = new Dog(); dog.eat();
对象被什么数据类型所修饰,这个变量就会调用谁的实例变量code
//父类:SuperClass public class SuperClass { int num = 10; }
//子类:SubClass public class SubClass extends SuperClass { int num = 20; }
//测试类:PolyDemo02 public class PolyDemo02 { public static void main(String[] args) { //父new父 SuperClass superC = new SuperClass(); System.out.println(superC.num);//10 //子new子 SubClass subC = new SubClass(); System.out.println(subC.num);//20 System.out.println("==================="); //利用多态建立对象 SuperClass sc = new SubClass(); System.out.println(sc);//com.atguigu.poly.demo02.SubClass@15db9742 子类地址值 System.out.println(sc.num);//10 } }
先看父类中是否有这个方法,若是有,执行子类重写后的方法;若是没有,编译报错对象
//父类:SuperClass public class SuperClass { public void method () { System.out.println("父类的实例方法"); } }
//子类:SubClass public class SubClass extends SuperClass { public void method () { System.out.println("子类重写后的实例方法"); } }
//测试类:PolyDemo04 public class PolyDemo04 { public static void main(String[] args) { //父new父 SuperClass superC = new SuperClass(); System.out.println(superC); //com.atguigu.poly.demo04.SuperClass@15db9742 superC.method();//父类的实例方法 System.out.println("=============="); //子new子 SubClass subC = new SubClass(); System.out.println(subC);//com.atguigu.poly.demo04.SubClass@6d06d69c subC.method();//父类的实例方法 System.out.println("=============="); //父new子 SuperClass sc = new SubClass(); System.out.println(sc);//com.atguigu.poly.demo04.SubClass@7852e922 sc.method();//父类的实例方法 } }
和原来同样继承
//父类:SuperClass public class SuperClass { public SuperClass () { System.out.println("父类的构造器"); } }
//子类:SubClass public class SubClass extends SuperClass { public SubClass(){ //super(); 此处隐藏了JVM提供的super() System.out.println("子类的构造器"); } }
//测试类PolyDemo03 public class PolyDemo03 { public static void main(String[] args) { //父new父 SuperClass superC = new SuperClass();//父类的构造器 System.out.println("================"); //子new子 SubClass subC = new SubClass();//父类的构造器 子类的构造器 System.out.println("================"); // 父new子 SuperClass sc = new SubClass();//父类的构造器 子类的构造器 System.out.println(sc); //com.atguigu.poly.demo03.SubClass@15db9742 } }
//Student类 public class Student { private String name; private int age; 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 Student(String name, int age) { super(); this.name = name; this.age = age; } //重写系统中自带的toString方法 @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
//测试类:PolyDemo05 public class PolyDemo05 { public static void main(String[] args) { Student s1 = new Student("张三",18); Student s2 = new Student("李四",23); Student s3 = new Student("钱五",43); Student s4 = new Student("孙六",23); //对象数组 Student[] arr = {s1,s2,s3,s4}; printArr(arr); } //object为顶级父类,将其放置形参 private static void printArr(Object[] arr) { for (int i = 0; i < arr.length; i++) { Object obj = arr[i]; System.out.println(obj); } } }
//运行结果 Student [name=张三, age=18] Student [name=李四, age=23] Student [name=钱五, age=43] Student [name=孙六, age=23]
在多态的状况下,对象没法调用本身的特有方法,只能调用子类改写父类的方法。接口
解决多态的弊端,引用数据类型的类型转换
类型转换名称 | 类型转换方向 |
---|---|
向上转型(默认转换方式) | 将子类的对象或者实现类的对象转换为父类的类型或者父接口类型(多态) |
向下转型(强制类型转换) | 将父类类型或者父接口类型转换为子类类型或者实现类类型 |
子类类型 对象名 = (子类类型)父类类型的对象; eg: Animal cat = new Cat(); //多态 Dog dog = (Dog)cat; //强转
引用数据类型强制类型转换时注意事项:
可能会发生ClassCastException:类型转换异常
强制转换时易发生类型转换异常,使用instanceof给引用变量作类型的校验
变量名 instanceof 数据类型 eg: c instanceof Cat
instanceof返回值
instanceof为关系运算符,若是变量属于该数据类型,返回true;若是变量不属于该数据类型,返回false。
1.定义动物类 属性:年龄,颜色 行为:eat(String something)方法(无具体行为,不一样动物吃的方式和东西不同, something表示吃的东西)生成空参有参构造,set和get方法 2.定义狗类继承动物类 行为:eat(String something)方法,看家lookHome方法(无参数) 3.定义猫类继承动物类 行为:eat(String something)方法,逮老鼠catchMouse方法(无参数) 4.定义Person类 属性:姓名,年龄 行为:keepPet(Dog dog,String something)方法 功能:喂养宠物狗,something表示喂养的东西 行为:keepPet(Cat cat,String something)方法 功能:喂养宠物猫,something表示喂养的东西 实现以上两种行为,思考如何只写一个方法? 生成空参有参构造,set和get方法 5.测试以上方法 使用多态、强转、instanceof等
//Animal类 public abstract class Animal { private int age; private String color; //设置set()、get()方法 public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } //设置无参构造器和满参构造器 public Animal(int age, String color) { super(); this.age = age; this.color = color; } public Animal() { super(); } //设置动物类的抽象方法 public abstract void eat(String something); }
//Cat类 继承 Animal类 public class Cat extends Animal{ //重写父类eat方法 public void eat(String something) { System.out.println(getAge() + "岁" + getColor() + "色的小猫正在吃" + something); } //逮老鼠方法 public void catchMouse () { System.out.println(getAge() + "岁" + getColor() + "色的小猫正在逮老鼠"); } //设置构造器 public Cat() { super(); } public Cat(int age, String color) { super(age, color); } }
//Dog类 继承 Animal类 public class Dog extends Animal{ //重写父类抽象方法 @Override public void eat(String something) { System.out.println(getAge() + "岁" + getColor() + "色的小狗正在吃" + something); } public void lookHome(){ System.out.println(getAge() + "岁" + getColor() + "色的小狗正在看家"); } //设置构造器 public Dog() { super(); } public Dog(int age, String color) { super(age, color); } }
//Person类 public class Person { //喂养狗和喂养猫的方法为方法的重载,能够直接使用多态的好处一:声明方法时,再也不将形参写具体的引用数据类型,直接写父类的类型或者父类接口的类型 /*// 喂养狗的方法 public void keepPet(Dog dog,String something) { dog.eat(something); } // 喂养猫的方法 public void keepPet(Cat cat,String something) { cat.eat(something); }*/ public void keepPet (Animal a,String something) { a.eat(something); } }
//测试类: public class PolyDemo06 { public static void main(String[] args) { //建立猫对象 Animal cat = new Cat(2,"白"); //建立狗的对象 Animal dog = new Dog(3,"黑"); //建立人对象 Person p = new Person(); // 调用饲养员的喂养猫的方法 p.keepPet(cat, "鱼"); // 将多态形式的对象进行向下转型 if (cat instanceof Cat) { Cat c = (Cat)cat; c.catchMouse(); } //cat对象不属于Dog,判断返回false if (cat instanceof Dog) { Dog d = (Dog)cat; d.lookHome(); } //Cat c = (Cat)dog; //c.catchMouse(); System.out.println("=================="); // 调用饲养员喂养狗的方法 p.keepPet(dog, "骨头"); } }