当前位置 : 主页 > 编程语言 > c语言 >

多态

来源:互联网 收集:自由互联 发布时间:2023-09-07
1. 多态 问题引入 使用传统的方法来解决(private 属性) 传统的方法带来的问题是什么? 如何解决? 问题是: 代码的复用性不高,而且不利于代码维护 解决方案: 引出我们要讲解的多态

1. 多态 问题引入

多态_子类

使用传统的方法来解决(private 属性)

传统的方法带来的问题是什么? 如何解决?

问题是: 代码的复用性不高,而且不利于代码维护

解决方案: 引出我们要讲解的多态

1.1 普通方法 305

代码在com.stulzl.poly_.包中

测试Poly01
package com.stulzl.poly_;

public class Poly01 {
    public static void main(String[] args) {
        Master tom = new Master("汤姆");
        Dog dog = new Dog("大黄");
        Bone bone = new Bone("大棒骨");
        tom.feed(dog,bone);
        System.out.println("=============");
        Cat cat = new Cat("小花猫");
        Fish fish = new Fish("黄花鱼");
        tom.feed(cat,fish);
    }
}
主人类Master
package com.stulzl.poly_;

public class Master {
    private  String name;

    //构造器
    public Master(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    //完成主人给小狗喂骨头
    public void feed(Dog dog,Bone bone){
        System.out.println("主人 "+name+" 给"+dog.getName()+" 吃"+bone.getName());
    }
    //完成主人给小猫喂鱼
    public void feed(Cat cat,Fish fish){
        System.out.println("主人 "+name+" 给"+cat.getName()+" 吃"+fish.getName());
    }
}
父类Food
package com.stulzl.poly_;

public class Food {
    private String name;

    //构造器
    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
子类Fish
package com.stulzl.poly_;

public class Fish extends Food {
    public Fish(String name) {
        super(name);
    }
}
子类Bone
package com.stulzl.poly_;

public class Bone extends Food {
    public Bone(String name) {
        super(name);
    }
}
父类Animal
package com.stulzl.poly_;

public class Animal {
    private  String name;

    //构造器
    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
子类 Cat
package com.stulzl.poly_;

public class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }
}
子类Dog
package com.stulzl.poly_;

public class Dog extends Animal{
    public Dog(String name) {
        super(name);
    }
}

2. 多态基本介绍 306

方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的

2.1 多态的具体体现

2.2.1 方法的多态 306

代码在com.stulzl.poly_method.包中

PolyMethod

package com.stulzl.poly_method;

public class PolyMethod {
    public static void main(String[] args) {
        //方法重载体现多态
        A a = new A();
        //这里我们传入不同的参数,就会调用不同 sum 方法,就体现多态
        System.out.println(a.sum(10, 20));
        System.out.println(a.sum(10, 20, 30));
        //方法重写体现多态
        B b = new B();
        a.say();
        b.say();
    }
}

class B { //父类
    public void say() {
        System.out.println("B say() 方法被调用...");
    }
}

class A extends B {//子类

    public int sum(int n1, int n2) {//和下面 sum 构成重载
        return n1 + n2;
    }

    public int sum(int n1, int n2, int n3) {
        return n1 + n2 + n3;
    }

    public void say() {
        System.out.println("A say() 方法被调用...");
    }
}

2.2 对象的多态(重点)307

多态_多态_02

多态_子类_03

代码在com.stulzl.poly_objpoly.包中

测试PolyObject

package com.stulzl.poly_objpoly;

//对象的多态
public class PolyObject {
    public static void main(String[] args) {
        //体验对象多态特点
        //编译类型就是 Animal , 运行类型 Dog
        Animal animal = new Dog();
        animal.cry();//小狗汪汪叫//因为运行时 , 执行到改行时,animal 运行类型是 Dog,
                               // 所以 cry 就是 Dog 的 cry

        //animal 编译类型 Animal,运行类型就是 Cat
        animal=new Cat();
        animal.cry();//小猫喵喵叫……

    }
}

父类Animal

package com.stulzl.poly_objpoly;

public class Animal {//父类
    public void cry(){
        System.out.println("Animal cry() 动物在叫……");
    }
}

子类Cat

package com.stulzl.poly_objpoly;

public class Cat extends Animal{//子类

    public void cry() {
        System.out.println("Cat cry() 小猫喵喵叫……");
    }
}

子类Dog

package com.stulzl.poly_objpoly;

public class Dog extends Animal{//子类
    public void cry(){
        System.out.println("Dog cry() 小狗汪汪叫……");
    }
}


3. 多态快速入门

3.1 使用多态的机制来解决主人喂食物的问题 308

多态_子类_04

代码在com.stulzl.poly_.包中

测试Poly01

package com.stulzl.poly_;

//使用多态的机制来解决主人喂食物的问题 308
public class Poly01 {
    public static void main(String[] args) {
        Master tom = new Master("汤姆");
        Dog dog = new Dog("大黄~");
        Bone bone = new Bone("大棒骨");
        tom.feed(dog,bone);

        System.out.println("=============");

        Cat cat = new Cat("小花猫~");
        Fish fish = new Fish("黄花鱼");
        tom.feed(cat,fish);

        System.out.println("=============");
        Pig pig = new Pig("小花猪");
        Food rice = new Food("米饭");
        tom.feed(pig,rice);
    }
}

主人类Master

package com.stulzl.poly_;

public class Master {
    private  String name;

    //构造器
    public Master(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }


    //使用多态机制,可以统一的管理主人喂食的问题
    //animal编译类型是Animal,可以指向(接收)Animal的子类对象
    //food编译类型是Food,可以指向(接收)Food的子类对象
    public void feed(Animal animal,Food food){
        System.out.println("主人 "+name+" 给"+animal.getName()+" 吃"+food.getName());
    }

//    //完成主人给小狗喂骨头
//    public void feed(Dog dog,Bone bone){
//        System.out.println("主人 "+name+" 给"+dog.getName()+" 吃"+bone.getName());
//    }
//    //完成主人给小猫喂鱼
//    public void feed(Cat cat,Fish fish){
//        System.out.println("主人 "+name+" 给"+cat.getName()+" 吃"+fish.getName());
//    }
}

父类Food

package com.stulzl.poly_;

public class Food {//父类
    private String name;

    //构造器
    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

子类Fish

package com.stulzl.poly_;

public class Fish extends Food {
    public Fish(String name) {
        super(name);
    }
}

子类Bone

package com.stulzl.poly_;

public class Bone extends Food {
    public Bone(String name) {
        super(name);
    }
}

子类Rice

package com.stulzl.poly_;

public class Rice extends Food{
    public Rice(String name) {
        super(name);
    }
}

父类Animal

package com.stulzl.poly_;

public class Animal {//父类
    private  String name;

    //构造器
    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

子类Cat

package com.stulzl.poly_;

public class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }
}

子类Dog

package com.stulzl.poly_;

public class Dog extends Animal{
    public Dog(String name) {
        super(name);
    }
}

子类Pig

package com.stulzl.poly_;

public class Pig extends Animal {
    public Pig(String name) {
        super(name);
    }
}

4. 多态的注意事项 309

4.1 细节1

多态的前提是:两个对象(类)存在继承关系

多态的向上转型

多态_System_05

多态的向下转型

多态_多态_06

代码在com.stulzl.poly_detail.包中

测试PolyDetail

package com.stulzl.poly_detail;

//多态细节309
public class PolyDetail {
    public static void main(String[] args) {
        //向上转型: 父类的引用指向了子类的对象  309
        //语法:父类类型引用名 = new 子类类型();
        Animal animal = new Cat();
        Object obj = new Cat();//可以吗? 可以 Object 也是 Cat 的父类
        //向上转型调用方法的规则如下:
        //(1)可以调用父类中的所有成员(需遵守访问权限)
        //(2)但是不能调用子类的特有的成员
        //因为在编译阶段,能调用哪些成员,是由编译类型来决定的
        //animal.catchMouse();错误
        //(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法
        //然后调用,规则我前面我们讲的方法调用规则一致
        animal.eat();//猫吃鱼..
        animal.run();//跑
        animal.show();//hello,你好
        animal.sleep();//睡

        //希望可以调用 Cat 的 catchMouse 方法  310
        //多态的向下转型
        //(1)语法:子类类型 引用名 =(子类类型)父类引用;
        //问一个问题? cat 的编译类型 Cat,  运行类型是 Cat
        Cat cat = (Cat) animal;
        cat.catchMouse();//猫抓老鼠
        //(2)要求父类的引用必须指向的是当前目标类型的对象  310
        //此句的意思是,之前animal指向了Cat,但是你要强转只能转向Cat类
    }
}

父类Animal

package com.stulzl.poly_detail;

public class Animal {//父类
    String name = "动物";
    int age = 10;
    public void sleep(){
        System.out.println("睡");
    }
    public void run(){
        System.out.println("跑");
    }
    public void eat(){
        System.out.println("吃");
    }
    public void show(){
        System.out.println("hello,你好");
    }
}

子类Cat

package com.stulzl.poly_detail;

public class Cat extends Animal{
    public void eat(){//方法重写
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){//Cat 特有方法
        System.out.println("猫抓老鼠");
    }
}

4.2 细节2 310

属性没有重写之说!属性的值看编译类型

代码在com.stulzl.poly_detail02.包中

测试PolyDetail02

package com.stulzl.poly_detail02;

import javax.security.auth.Subject;

//属性没有重写之说!属性的值看编译类型
public class PolyDetail02 {
    public static void main(String[] args) {
        //属性没有重写之说!属性的值看编译类型
        Base base = new Sub();//向上转型
        System.out.println(base.count);//?  10,看编译类型
        Sub sub = new Sub();
        System.out.println(sub.count);//20
    }
}
class Base{//父类
    int count=10;//属性
}
class Sub extends Base{//子类
    int count=20;//属性
}
【文章原创作者:响水网站开发 http://www.1234xp.com/xiangshui.html 复制请保留原URL】
上一篇:如何解决vs出现scanf报错的问题
下一篇:没有了
网友评论