首页 > 编程语言 >Java中的多态

Java中的多态

时间:2022-10-03 23:24:04浏览次数:52  
标签:Java void 多态 Cat public Animal eat

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

相关文章

  • java基础 Arrays.sort()用法
    1.作用对数组按照一定顺序排列,默认为升序。排列过程中为快排,不需要额外的空间,也不需要重新定义一个数组来接收它。示例:publicclassTest{publicstaticvoidm......
  • 每天一个小java练习(牢子好可爱啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊)2022.10.1
    练习题:接收用户输入的3个整数,并将它们的最大值作为结果输出:下面是我的代码以及运行截图啦啦啦啦:  这个本身很基础,,但是涉及到了?:的用法,就记录一下......
  • 力扣205(java)-同构字符串(简单)
    题目:给定两个字符串 s 和 t ,判断它们是否是同构的。如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。每个出现的字符都应当映射到另一......
  • 程序、进程和线程 Java多线程的状态【杭州多测师】【杭州多测师_王sir】
    CPU是以时间片的方式为进程分配CUP处理时间的,如果当一个进程同时要完成几件事的时候,如当从网上下载文件的时候,需要一边下载一边显示进度而且还要一边保存,如果按照单线程的......
  • java网络编程--4 UDP
    java网络编程--4UDP1.7、UDP发短信:不用连接,但是需要知道对方的地址主要包含两个类:DatagramPacket和DatagramSocket发送消息发送端:packagecom.ssl.lesson03;im......
  • Java学习之:静态初始化块、包、参数传递机制
    关键字static和静态初始化块static普通变量和方法从属于对象,而static修饰的成员变量和方法从属于类。静态方法:被static修饰的方法叫做静态方法,又被称为类方法。非static的方......
  • Java对象序列化和反序列化
    Java类的序列化和反序列化序列化:指将对象转换为字节序列的过程,也就是将对象的信息转换成文件保存。反序列化:将字节序列转换成目标对象的过程,也就是读取文件,并转换为对象。几......
  • Java项目打成镜像
    前言官方只有java8的docker镜像,如果我们的项目使用java11开发的,那么用java8的镜像打包运行会报错那么我们部署java项目有两种方式如:1.将项目打成war包部署到tomcat容器,2.自......
  • Java中Map.Entry
    Map<String,String>map=newHashMap<String,String>();map.put("1","value1");map.put("2","value2");map.put("3","value3");遍历map方式1:Ma......
  • java BIO
    packageIO;//文件、数组、管道、基本数据类型、缓冲、打印、对象序列化/反序列化,以及转换等​importjava.io.*;​/***操作文件{*  1.文件字节流:FileInpu......