(1)什么是多态?
- 同类型的对象,表现出不同的形态。前者指父类,后者指不同的子类
说简单点,就是父类的同一种方法,可以在不同子类中表现出不同的状态,或者说在不同子类中可以实现不同的效果(重写)。
(2)多态的前提
- 有继承/实现关系------有了继承才有子父类之分
- 有父类引用指向子类对象------,如:Animal a = new Dog(); ——小到大,向上转型。这里父类引用指向子类对象,其实相当于把子类对象当父类对象来用,所以这是一种向上转型的引用。
- 有方法重写------在不同的子类中重写父类方法,实现自己不同的功能。当然也可以不重写,主要是重写这个功能使得每个子类都独具一格,不会全都相同,这是多态重要的一点。
(3)多类的好处
- 方法使用父类类型作为形参,就可以接收所以子类对象,体现多态的扩展性与便利
(4)多态的表现形式
- 父类类型 对象名称=new 子类类型();
Fu a=new Zi();
(5)调用的特点
- 成员变量:编译看左边,运行也看左边
- 成员方法:编译看左边,运行看右边(子类如果进行方法重写的话,父类里的方法就被覆盖)
(6) 多态弊端是什么?
- 不能调用子类特有功能,因为编译看左边,特有功能表示父类没有,代码直接报错
(7)引用数据类型的转换有几种方式?
- 自动类型转换
- 强制类型转换(可解决弊端)
//自动类型转换
Person p=new Student;//小(Student)--->大(Person)
//强制类型转换
Student s=(Student)p;//大(Person)--->小(Student)
(8)强制类型转换能解决什么问题?
- 可以把对象转换成真正的子类类型,从而调用子类的特有功能
- 转换类型与真实对象类型不一致会报错
- 转换的时候用instanceof关键字进行判断它属于哪个子类
(9)综合练习
- 根据需求完成代码
父类Animal
package duotai;
public class Animal {
private String color;
private int age;
public Animal() {
}
public Animal(String color, int age) {
this.color = color;
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(String something){
System.out.println("动物在吃"+something);
}
}
子类Dog
package duotai;
public class Dog extends Animal{
public Dog() {
}
public Dog(String color, int age) {
super(color, age);
}
@Override
public void eat(String something) {
System.out.println("此时此刻"+getAge()+"岁"+getColor()
+"颜色的狗抱着"+something+"猛吃");
}
public void lookHome(){
System.out.println("狗在看家");
}
}
子类Cat
package duotai;
public class Cat extends Animal{
public Cat() {
}
public Cat(String color, int age) {
super(color, age);
}
@Override
public void eat(String something) {
System.out.println("此时此刻"+getAge()+"岁"+getColor()
+"颜色的猫眯着眼吃"+something);
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
Person类
package duotai;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = 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 void keepDog(Dog dog,String someting){
System.out.println(this.age+"的"+this.name+"养了一条"
+dog.getColor()+"的"+dog.getAge()+"岁的狗");
dog.eat(someting);
}
public void keepCat(Cat cat,String someting){
System.out.println(this.age+"岁的"+this.name+"养了一条"
+cat.getColor()+"的"+cat.getAge()+"的小猫");
cat.eat(someting);
}
//一个一个构造饲养动物的方法,过于繁琐
*/
//构造一个方法,能够接收所有的动物
//方法的形参:可以写这些类的父类,就可以接收所以子类对象(多态)
public void keepPet(Animal a,String something){
//if条件语句判断它属于哪一个子类,进行强转,就可以使用子类特有的方法
if(a instanceof Dog ){
Dog d=(Dog)a; //Animal强转成Dog
System.out.println(this.age+"的"+this.name+"养了一条"
+a.getColor()+"的"+a.getAge()+"岁的狗");
a.eat(something);
d.lookHome();
} else if (a instanceof Cat ) {
Cat c=(Cat)a; //Animal强转成Cat
System.out.println(this.age+"的"+this.name+"养了一条"
+a.getColor()+"的"+a.getAge()+"岁的小猫咪");
a.eat(something);
c.catchMouse();
}else {
System.out.println("没有这种动物");
}
}
}
测试类
package duotai;
public class Test {
public static void main(String[] args) {
/*Person p1=new Person("西施",15);
Dog d=new Dog("粉红",2);
p1.keepDog(d,"美味的鸡叉骨");
//选中+shift+F6:批量修改
Person p2=new Person("花木兰",16);
Cat c=new Cat("淡黄",4);
p2.keepCat(c,"美味的小鱼干");*/
Person p1=new Person("西施",15);
Dog d=new Dog("粉红",2);
p1.keepPet(d,"美味的鸡叉骨");
Person p2=new Person("花木兰",16);
Cat c=new Cat("淡黄",3);
p2.keepPet(c,"美味的小鱼干");
}
}
结果
注意: