多态概述
多态:同一个对象,在不同时刻表现出来的不同形态。
- 举例:猫
- 我们可以说猫是猫,猫 cat=new 猫();
- 我们也可以说猫是动物,动物 animal=new 猫();
- 这里猫在不同的时刻表现出来了不同的形态,这就是多态。
多态的前提和体现:
- 有继承或者实现关系
- 有方法重写
- 有父类引用指向子类对象
多态中成员访问特点
- 成员变量:编译看左边,执行看左边
- 成员方法:编译看左边,执行看右边
为什么成员变量和成员方法的访问不一样呢?
因为成员方法有重写,而成员变量没有。
public class Animal{
public int age=40;
public void eat() {
System.out.println("动物吃东西");
}
}
public class Cat extends Animal{
public int age=20;
public int weight=10;
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫打游戏");
}
}
public class Demo{
public static void main(String args[]) {
//有父类引用指向子类对象
Animal a=new Cat();
System.out.println(a.age);
// System.out.println(a.weight); //父类中没有weight成员变量,所以报错
a.eat();
// a.playGame(); //父类没有playGame()方法,所以报错
}
}
多态的好处和弊端
多态的好处:提供了程序的扩展性
具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作。
多态的弊端:不能使用子类的特有功能
public class Animal{
public void eat() {
System.out.println("动物吃东西");
}
}
public class Pig extends Animal{
public void eat() {
System.out.println("猪吃白菜");
}
}
public class Dog extends Animal{
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫打游戏");
}
}
public class AnimalOperator {
// public void userAnimal(Cat c) {//Cat c = new Cat(); c.eat();
// c.eat();
// }
// public void userAnimal(Dog d) {//Dog d=new Dog(); d.eat();
// d.eat();
// }
public void userAnimal(Animal a) {
//Animal a=new Cat();
//Animal a=new Dog();
a.eat();
// a.playGame();//不能访问具体子类特有的功能
}
}
public class Demo{
public static void main(String args[]) {
AnimalOperator ao=new AnimalOperator();
Cat c=new Cat();
ao.userAnimal(c);
Dog d=new Dog();
ao.userAnimal(d);
Pig p=new Pig();
ao.userAnimal(p);
}
}
多态中的转型
向上转型
向上转型:从子到父,父类引用指向子类对象
向下转型
向下转型:从父到子,父类引用转为子类对象
public class Animal{
public void eat() {
System.out.println("动物吃东西");
}
}
public class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫打游戏");
}
}
public class Demo{
public static void main(String args[]) {
//多态
Animal a=new Cat();//向上转型
a.eat();
// a.playGame();
//创建Cat类的对象
/*
Cat c=new Cat();
c.eat();
c.playGame();
*/
//向下转型
Cat c=(Cat)a;//父类引用强转为子类对象
c.eat();
c.playGame();
}
}
多态转型内存图解(来源:黑马程序员)
Dog类无法转换为Cat类,所以报错。
案例:猫和狗
1.定义动物类
2.定义猫类
3.定义狗类
4.定义测试类
public class Animal{
private String name;
private int age;
public Animal() {
}
public Animal(String name,int age) {
this.name=name;
this.age=age;
}
public void setName(String name) {
this.name=name;
}
public void setAge(int age) {
this.age=age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void eat() {
System.out.println("动物吃东西");
}
}
public class Cat extends Animal{
public Cat() {
}
public Cat(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫打游戏");
}
}
public class Dog extends Animal{
public Dog() {
}
public Dog(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Demo{
public static void main(String args[]) {
//创建对象,进行测试
Animal a=new Cat();
a.setName("加菲猫");
a.setAge(5);
System.out.println(a.getAge()+','+a.getName());
a.eat();
a=new Cat("加菲猫",5);//因为它继承了Animal,所以也可以赋值给a,但是地址改变了。
System.out.println(a.getAge()+','+a.getName());
a.eat();
Animal a1=new Dog();
a1.setName("藏獒");
a1.setAge(10);
System.out.println(a1.getName()+','+a1.getAge());
a1.eat();
a1=new Dog("藏獒",11);
System.out.println(a1.getName()+','+a1.getAge());
a1.eat();
}
}