栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

多态

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多态

目录

1.多态的基本介绍

2.方法的多态

3.对象的多态(核心)

4.多态的注意事项和细节

        1.多态的向上转型

         2.多态的向下转型

        3.属性重写问题

5.java的动态绑定机制(重点)

6.多态的应用

        1.多态数组

        2.多态参数


1.多态的基本介绍

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

Java 多态 | 菜鸟教程 (runoob.com)https://www.runoob.com/java/java-polymorphism.html

2.方法的多态

代码演示:        

package com.shixin.java;


public class polymorphic {
    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){
        return n1 + n2;
    }

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

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

3.对象的多态(核心)

        重要的几句话:

                (1)一个对象的编译类型和运行类型可以不一致

                (2)编译类型在定义对象时,就确定了,不能改变

                (3)运行类型可以变化的

                (4)编译类型看定义时 =号的左边,运行时看 =号的右边

代码演示:

package com.shixin.java;


public class PloyObject {
    public static void main(String[] args) {
        //体验对象的多态
        //animal 编译类型就是 Animal,运行类型是Dog
        Animal animal = new Dog();
        //因为运行时,执行到该行时,animal运行类型是Dog,所以cry方法就是Dog的cry方法
        animal.cry();
    }
}

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

class Cat extends Animal{

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

class Dog extends Animal{
    @Override
    public void cry() {
        System.out.println("Dog cry() 小狗汪汪叫");
    }
}

4.多态的注意事项和细节

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

        1.多态的向上转型

                (1)本质:父类的引用指向了子类的对象

                (2)语法:父类类型     引用名 = new  子类类型(); 

                (3)特点:编译类型看左边,运行类型看右边

                        可以调用父类中的所有成员(需要遵守访问权限)

                        不能调用子类中特有成员

                        最终运行效果看子类的具体实现

代码演示:

package com.shixin.java;


public class Test {
    public static void main(String[] args) {
        //向上转型:父类引用指向子类对象
        //语法:父类类型  引用名 = new  子类类型(); 
        Animal animal = new Cat();

        //可以调用父类中的所有成员(需要遵守访问权限)
        //不能调用子类中特有成员
        //因为在编译阶段,能调用那些成员,是由编译类型来决定的
        //最终运行效果看子类的具体实现
        animal.eat();//调用的是子类的eat()方法
        animal.sleep();
    }
}

class Animal{
    public void eat(){
        System.out.println("吃");
    }
    public void sleep(){
        System.out.println("睡");
    }
}

class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse(){//cat特有的方法
        System.out.println("猫抓老鼠");
    }
}

       

         2.多态的向下转型

                (1)语法:子类类型   引用名 = (子类类型)  父类引用;

                (2)只能强转父类的引用,不能强转父类的对象

                (3)要求父类的引用必须指向的是当前目标类型的对象

                (4)向下转型后,可以调用子类类型中所有的成员

代码演示:

package com.shixin.java;


public class PolymorphicDetail {
    public static void main(String[] args) {
        //父类引用指向子类对象
        Animal animal01 = new Cat();
        //不能调用子类中特有成员
        //animal.catchMouse;  报错

        //多态的向下转型
        //调用子类特有的方法:catchMouse()
        //语法:子类类型 引用名 = (子类类型) 父类引用;
        //要求父类的引用必须指向的是当前目标类型的对象
        //向下转型中,父类引用只能转换为其当前指向的子类对象
        //animal01的运行类型Cat类型,所以只能转换为Cat类型
        Cat cat = (Cat) animal01;
        cat.catchMouse();


    }
}

class Animal{
    public void eat(){
        System.out.println("吃");
    }
    public void sleep(){
        System.out.println("睡");
    }
}

class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse(){//cat特有的方法
        System.out.println("猫抓老鼠");
    }
}

        3.属性重写问题

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

代码演示:

package com.shixin.java;


public class PolymorphicDetail {
    public static void main(String[] args) {
        //属性没有重写之说!属性的值看编译类型
        Base base = new Sub();
        //看编译类型
        System.out.println(base.count);//10
    }
}

class Base{
   public int count = 10;
}

class Sub extends Base{
    public int count = 20;
}

             

                  instanceOf 比较运算符,用于判断对象的运行类型是否为XX类型或XX类型的子类型

代码演示:

package com.shixin.java;


public class PolymorphicDetail02 {
    public static void main(String[] args) {
        BB b = new BB();
        System.out.println(b instanceof BB);//true
        System.out.println(b instanceof AA);//true

        //a 编译类型是AA  运行类型是BB
        AA a = new AA();
        System.out.println(a instanceof AA);//true
        System.out.println(a instanceof BB);//true

        Object obj = new Object();
        System.out.println(obj instanceof AA);//false

        String str = "hello";
        System.out.println(str instanceof Object);//true
        
    }
}
class AA{}//父类
class BB extends AA{}//子类

5.java的动态绑定机制(重点)

        1.当调用对象方法的时候,该方法会和对象的内存地址/运行类型绑定

        2.当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用

代码演示:

package com.shixin.java.test;


public class PolymorphicBinding {
    public static void main(String[] args) {
        //a的编译类型 A,运行类型 B
        A a = new B();
        System.out.println(a.sum());//30
        System.out.println(a.sum2());//20
    }
}


class A{//父类
    public int i =10;
    public int sum(){
        return getI() + 10;
    }
    public int sum2(){
        return i + 10;
    }
    public int getI(){
        return i;
    }
}

class B extends A{//子类
    public int i = 20;

    public int getI() {
        return i;
    }
}

6.多态的应用

        1.多态数组

                数组的定义为父类型,里边保存的实际元素为子类类型

        代码演示:

            

package com.shixin.java;


public class PolymorphicArray {
    public static void main(String[] args) {
        //应用实例:要求创建1个Person数组
        //1个Person对象,1个Student对象和1个Teacher对象,同一放到数组中,并调用每个对象的say方法
        Person[] people = new Person[3];
        people[0] = new Person("jack",20);
        //向上转型
        people[1] = new Student("tom",18,88);
        people[2] = new Teacher("smith",28,4000);

        for (int i = 0; i < people.length; i++) {
            //person[i] 编译类型是Person,运行类型是根据实际情况由JVM来判断
            System.out.println(people[i].say());//动态绑定

            //调用子类特有的方法
            if (people[i] instanceof Student){
                //向下转型
                ((Student)people[i]).study();
            }else if (people[i] instanceof Teacher){
                ((Teacher)people[i]).teach();
            }
        }
    }
}

class Person{
    private String name;
    private int age;

    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 String say(){//返回名字和年龄
        return name +"t"+ age;
    }
}

class Student extends Person{

    private double score;

    public Student(String name, int age, double score) {
        super(name, age);
        this.score = score;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    //重写父类say方法

    @Override
    public String say() {
        return super.say() + "tscore = " + score;
    }

    //特有方法
    public void study(){
        System.out.println("学生 " + getName() + "正在学习");
    }
}

class Teacher extends Person{
    private double salary;

    public Teacher(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String say() {
        return super.say() + "tsalary = "+ salary;
    }

    //特有方法
    public void teach(){
        System.out.println("老师 " + getName() + "正在讲课");
    }
}

    

        2.多态参数

                方法定义的形参类型为父类类型,实参类型允许为子类型

        代码演示:

package com.shixin;


public class PolymorphicParameter {
    public static void main(String[] args) {
        Master master = new Master();
        Cat cat = new Cat("jack");
        Dog dog = new Dog("tom");

        
        master.feed(cat);
        master.feed(dog);
    }
}

class Master{//主人类
    //给动物喂食的方法
    public void feed(Animal animal){
        animal.eat();
    }

}

class Animal{//动物类

    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public void eat(){
        System.out.println("动物需要进食");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
class Cat extends  Animal{//小猫类

    public Cat(String name) {
        super(name);
    }

    @Override
    public void eat() {
        System.out.println("小猫 " + getName() +" 吃鱼");
    }
}

class Dog extends Animal{//小狗类

    public Dog(String name) {
        super(name);
    }

    @Override
    public void eat() {
        System.out.println("小狗 " + getName() + "吃骨头");
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/983706.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号