Java中的多态
一、多态的概述
1、同一个对象,在不同时刻表现出来的不同形态
2、多态的前提和体现
有继承/实现关系
有方法重写
有父类引用指向子类对象
3、代码示例:
package com.itheima_01;
/*
动物类
*/
public class Animal {
public void eat(){
System.out.println("动物吃东西");
}
}
package com.itheima_01;
/*
猫类
*/
public class Cat extends Animal{ //此处完成继承关系
@Override
public void eat(){ //此处实现方法重写
System.out.println("猫吃老鼠");
}
}
package com.itheima_01;
/*
测试类, 用于测试多态前提
*/
public class AnimalDemo {
public static void main(String[] args){
//父类引用指向子类对象
Animal animal = new Cat();
//可以看到此时 调用eat方法实现的是猫吃老鼠
animal.eat();
}
}
二、多态中成员访问特点
成员变量:编译看左边,执行看左边
成员函数:编译看左边,执行看右边
为什么成员变量与成员方法的访问不一样呢?
因为成员方法有重写,而成员变量没有
参考代码:
package com.itheima_02;
/*
动物类
*/
public class Animal {
public int age = 40;
public void eat(){
System.out.println("动物吃东西");
}
}
package com.itheima_02;
/*
猫类
*/
public class Cat extends Animal{
public int age = 20;
public int weight = 10;
@Override
public void eat(){
System.out.println("猫吃老鼠");
}
public void playGame(){
System.out.println("猫捉迷藏");
}
}
package com.itheima_02;
/*
测试类
*/
public class AnimalDemo {
public static void main(String[] args){
//有父类引用指向子类对象
Animal a = new Cat();
//在多态中 针对于属性而言 编译与运行都是以 左边(此处是父类引用)为准
System.out.println(a.age);
// System.out.println(a.weigth);
//在多态中 针对于方法而言 编译以左边为准 运行则是看右边
a.eat();
// a.playGame();
}
}
三、多态的好处和弊端
1、多态的好处:
提高了程序的拓展性,具体体现:定义方法的时候,使用父类作为参数,将来使用的时候,传入具体的子类类型参与操作
2、多态的弊端:
不能使用子类的特有功能(理解:多态是通过父类引用进行方法的调用,但是子类中的特有方法无法通过父类引用进行调用)
3、参考代码:
package com.itheima_03;
/*
动物操作类
*/
public class AnimalOperator {
/*public void useAnimal(Cat c){ //Cat c = new Cat();
c.eat();
}
public void useAnimal(Dog d){ //Dog d = new Dog();
d.eat();
}*/
//利用多态思想 传入我所需要的对应的子类对象
public void useAnimal(Animal a){
a.eat();
// a.lookDoor(); 不能利用父类引用访问子类特有的功能
}
}
package com.itheima_03;
public class Cat extends Animal{
@Override
public void eat(){
System.out.println("猫吃老鼠");
}
}
package com.itheima_03;
public class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗吃骨头");
}
public void lookDoor(){
System.out.println("狗看门");
}
}
package com.itheima_03;
public class Pig extends Animal{
@Override
public void eat(){
System.out.println("猪吃饲料");
}
}
package com.itheima_03;
/*
动物操作类
*/
public class AnimalOperator {
/*public void useAnimal(Cat c){ //Cat c = new Cat();
c.eat();
}
public void useAnimal(Dog d){ //Dog d = new Dog();
d.eat();
}*/
//利用多态思想 传入我所需要的对应的子类对象
public void useAnimal(Animal a){
a.eat();
// a.lookDoor(); 不能利用父类引用访问子类特有的功能
}
}
package com.itheima_03;
public class AnimalDemo {
public static void main(String[] args) {
//创建动物操作类的对象,调用方法
AnimalOperator ao = new AnimalOperator();
/*Cat c = new Cat();
ao.useAnimal(c);
Dog d = new Dog();
ao.useAnimal(d);*/
//可以看到:每添加一个类,就要到动物操作类中去添加新的方法(也可以使用上面注释的方法传参)
Animal a = new Cat();
ao.useAnimal(a);
a = new Dog();
ao.useAnimal(a);
a = new Pig();
ao.useAnimal(a);
}
}
四、多态中的转型
1、向上转型:
从子到父,父类引用指向子类对象(就是多态条件操作)
2、向下转型:
从父到子,父类引用转换为子类对象
例如:Animal a = new Cat(); Cat c = (Cat)a; 注意a,c中存放的引用类型相同才可进行 这里都是Cat类在堆区的地址值
3、代码示例:
package com.itheima_04;
public class Animal {
public void eat(){
System.out.println("动物吃东西");
}
}
package com.itheima_04;
public class Cat extends Animal{
@Override
public void eat(){
System.out.println("猫吃老鼠");
}
public void playGame(){
System.out.println("猫捉迷藏");
}
}
package com.itheima_04;
/*
向上转型
从子到父
父类引用指向子类对象
向下转型
从父到子
父类引用转为子类对象
*/
public class AnimalDemo {
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; //强制转换 a中存的也是Cat的堆区地址值才行,如果此时不是就会报错
c.playGame();
}
}
五、多态案例
1、案例一猫和狗:
package com.itheima_05;
/*
动物类
*/
public class Animal {
//成员属性
private String name;
private int age;
//构造方法
public Animal(){
}
public Animal(String name, int age){
this.name = name;
this.age = age;
}
//set/get/show方法
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void show(){
System.out.println(getName() + "," + getAge());
}
//定义一个吃东西的方法
public void eat(){
System.out.println("动物在吃东西");
}
}
package com.itheima_05;
/*
猫类
*/
public class Cat extends Animal{
//构造方法
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("猫吃老鼠");
}
}
package com.itheima_05;
/*
狗类
*/
public class Dog extends Animal{
//构造方法
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("狗吃骨头");
}
}
package com.itheima_05;
/*
测试类
*/
public class AnimalDemo {
public static void main(String[] args){
//实现猫类的调用
Animal a = new Cat();
/*
此处如果我们创建子类对象也只会到父类中去找属性和方法,我们并没有在子类中写
所以直接利用父类引用来调用方法、来实现初始化
当我们是使用子类引用来调用时,就需要参考继承中的调用规则中
*/
//Cat c = (Cat)a; 一般又用于调用子类中特有的方法此处没有
a.setName("加菲猫");
a.setAge(8);
a.show();
a.eat();
Animal a2 = new Cat("Tom", 6);
a2.show();
a2.eat();
//实现狗类的调用
Animal a3 = new Dog();
a3.setName("旺财");
a3.setAge(7);
a3.show();
a3.eat();
Animal a4 = new Dog("来福", 5);
a4.show();
a4.eat();
}
}
标签:Java,void,多态,Cat,public,Animal,eat
From: https://www.cnblogs.com/fragmentary/p/16751553.html