面向对象三大特性: 多态

什么是多态:

父类的一些成员,子类继承周去重写从而实现不同的功能。

多态的风雷

多态分为两种,一种是编译时的多态,一种是运行时的多态。

编译时多态:编译时的多态性是通过重载来实现的。

编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。

运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中运行时的多态性是通过覆写虚成员实现。 

多态的实现

重载(overload)

重载指的是同一个累中有两个或者多个名字但是参数不同的方法。

public void Calculate()
{
    // do the calculation here
}

public void Calculate(int num)
{
    // do the calculation here
}

运行时多态: 重写

重写有两种, 一种是override修饰符, 另一种使用new 修饰符

重新(override)是对父类中的虚函数(virtual method)或抽象函数的“覆盖”。

/// <summary>
    /// 动物类(父类)
    /// </summary>
    class Animal
    {
       /// <summary>
       /// 名字
       /// 说明:类和子类可访问
       /// </summary>
       protected string name;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name"></param>
        public Animal(string name)
        {
            this.name=name;
        }

        /// <summary>
        /// 名字(虚属性)
        /// </summary>
        public virtual string MyName
        {
            get { return this.name; }           

        }

        /// <summary>
        /// 吃(虚方法)
        /// </summary>
        public virtual void Eat()
        {
            Console.WriteLine("我会吃!");
        }

        /// <summary>
        /// 叫(虚方法)
        /// </summary>
        public virtual void Shout()
        {
            Console.WriteLine("我会叫!");
        }
    }

    /// <summary>
    /// 狗(子类)
    /// </summary>
    class Dog:Animal
    {
        string myName;
        public Dog(string name): base(name)
        {
            myName = name;
        }

        /// <summary>
        /// 名字(重写父类属性)
        /// </summary>
        public override string MyName
        {
            get { return "我是:狗狗,我叫:"+this.name; }

        }

        /// <summary>
        /// 吃(重写父类虚方法)
        /// </summary>
        public  override void Eat()
        {
            Console.WriteLine("我喜欢吃肉!");
        }

        /// <summary>
        /// 叫(重写父类方法)
        /// </summary>
        public override void Shout()
        {
            Console.WriteLine("汪!汪!汪!");
        }
    }
    /// <summary>
    /// 猫(子类)
    /// </summary>
    class Cat : Animal
    {
        string myName;
        public Cat(string name)
            : base(name)
        {
            myName = name;
        }
        /// <summary>
        /// 名字(重写父类属性)
        /// </summary>
        public override string MyName
        {
            get { return "我是:猫咪,我叫:" + this.name; }

        }

        /// <summary>
        /// 吃(重写父类虚方法)
        /// </summary>
        public override void Eat()
        {
            Console.WriteLine("我喜欢吃鱼!");
        }

        /// <summary>
        /// 叫(重写父类方法)
        /// </summary>
        public override void Shout()
        {
            Console.WriteLine("喵!喵!喵!");
        }
    }

    /// <summary>
    /// 羊(子类)
    /// </summary>
    class Sheep : Animal
    {
        string myName;
        public Sheep(string name)
            : base(name)
        {
            myName = name;
        }
        /// <summary>
        /// 名字(重写父类属性)
        /// </summary>
        public override string MyName
        {
            get { return "我是:羊羊,我叫:" + this.name; }

        }

        /// <summary>
        /// 吃(重写父类虚方法)
        /// </summary>
        public override void Eat()
        {
            Console.WriteLine("我喜欢吃草!");
        }

        /// <summary>
        /// 叫(重写父类方法)
        /// </summary>
        public override void Shout()
        {
            Console.WriteLine("咩!咩!咩!");
        }
    }

重写(new)

new:覆盖指的是不同类中有两个或以上的返回类型,方法名,参数都相同,但是方法体不同的方法。

/// <summary>
    /// 动物类(父类)
    /// </summary>
    class Animal
    {
       /// <summary>
       /// 名字
       /// 说明:类和子类可访问
       /// </summary>
       protected string name;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name"></param>
        public Animal(string name)
        {
            this.name=name;
        }

        /// <summary>
        /// 名字(虚属性)
        /// </summary>
        public virtual string MyName
        {
            get { return this.name; }           

        }

        /// <summary>
        /// 吃(虚方法)
        /// </summary>
        public virtual void Eat()
        {
            Console.WriteLine("我会吃!");
        }

        /// <summary>
        /// 叫(虚方法)
        /// </summary>
        public virtual void Shout()
        {
            Console.WriteLine("我会叫!");
        }
    }

    /// <summary>
    /// 狗(子类)
    /// </summary>
    class Dog:Animal
    {
        string myName;
        public Dog(string name): base(name)
        {
            myName = name;
        }
        /// <summary>
        /// 名字(重写父类属性)
        /// </summary>
        public override string MyName
        {
            get { return "我是:狗狗,我叫:"+this.name; }
        }

        /// <summary>
        /// 吃(重写父类虚方法)
        /// </summary>
        new  public   void Eat()
        {
            Console.WriteLine("我喜欢吃肉!");
        }

        /// <summary>
        /// 叫(重写父类方法)
        /// </summary>
        public new void Shout()
        {
            Console.WriteLine("汪!汪!汪!");
        }
    }

可以看出,当派生类Dog的Eat()方法使用new修饰时,Dog的对象转换为Animal对象后,调用的是Animal类中的Eat()方法。其实可以理解为,使用new关键字后,使得Dog中的Eat()方法和Animal中的Eat()方法成为毫不相关的两个方法,只是它们的名字碰巧相同而已。所以, Animal类中的Eat()方法不管用还是不用virtual修饰,也不管访问权限如何,或者是没有,都不会对Dog的Eat()方法产生什么影响(只是因为使用了new关键字,如果Dog类没用从Animal类继承Eat()方法,编译器会输出警告)。

我想这是设计者有意这么设计的,因为有时候我们就是要达到这种效果。严格的说,不能说通过使用new来实现多态,只能说在某些特定的时候碰巧实现了多态的效果。

原文地址:https://www.cnblogs.com/TheMiao/p/9271401.html

时间: 2024-10-31 10:29:51

面向对象三大特性: 多态的相关文章

面向对象三大特性-多态的思考

无论是python语言,还是java语言都有着面向对象的特性,而面向对象三大特性(封装,继承,多态)中封装和继承是比较容易理解的,多态的话自己一直处于一个似懂非懂的状态.比如一些概念性的东西: 多态的要点: 1. 多态是方法的多态,不是属性的多态(多态与属性无关). 2. 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象. 3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了. 对象类型的转换: 向上可以自动转换类型,由子类转换成父类! 向下(由父类转换

深入理解面向对象三大特性——多态

多态,字面意思,就是多种形态 比如:一种红酒,由不同的人来品尝,会有不同的感觉,这叫做多态: 一个人用不同的方式来喝酒,也会有不同的后果,这也叫做多态. 多态的原理:类都写好了,不要去修改它,只是在类外调用时更改参数,从而实现不同的结果(多态) //举例:创建一个电脑的接口 interface Computer { public function version(); public function work(); } //创建一个笔记本的子类实现接口 class Notecomputer im

python面向对象三大特性-多态

import abc #利用abc模块实现抽象类 class All_file(metaclass=abc.ABCMeta): all_type='file' @abc.abstractmethod #定义抽象方法,无需实现功能 def read(self): '子类必须定义读功能' with open('filaname') as f: pass @abc.abstractmethod #定义抽象方法,无需实现功能 def write(self): '子类必须定义写功能' pass class

JAVA基础——面向对象三大特性:封装、继承、多态

JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据.     隐藏类的实例细节,方便修改和实现. 3.封装的实现步骤 需要注意:对封装的属性不一定要通过get/set方法,其他方法也可以对封装的属性进行操作.当然最好使用get/set方法,比较标准. A.访问修饰符 从表格可以看出从上到下封装性越来越差. B.this关键字 1.this关键字代表当前

(1) 深入理解Java面向对象三大特性 封装 继承 多态

转眼已经工作快6年了,最开始做了2年J2EE:然后整了2年的数据仓库,主要是Cognos的报表开发:现在从事4G LTE核心网的开发,用的语言任然是Java,但写代码的机会不多,基本都是看代码找BUG,偶尔做点new feature也是在比较成熟的框架上复制.粘贴.修改,大部分时间还是在理解业务,钱多.事少.离家近,当时来这家公司图的是后面2点,2年过去了,英文水平有所提升,对敏捷开放也有一定的了解,但技术方面明显退步了或者说没有进步吧,本来以前也不怎么好,因为工作上用不到,自己也没怎么学习,所

面向对象编程(十四)——面向对象三大特性之多态②

面向对象最核心的机制——动态绑定,也叫多态. 通过下面的例子理解动态绑定,即多态 1 package javastudy.summary; 2 3 class Animal { 4 /** 5 * 声明一个私有的成员变量name. 6 */ 7 private String name; 8 9 /** 10 * 在Animal类自定义的构造方法 11 * @param name 12 */ 13 Animal(String name) { 14 this.name = name; 15 } 16

JavaScript基础--面向对象三大特性(八):继承封装多态

一.构造函数基本用法:function 类名(参数列表){属性=参数值} 1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 6 //创建Person对象的时候,可以直接给名字和年龄 7 var p1 = new Person('abc',80); 8 window.alert(p1.name); 9 var p2 = new Person('hello',9); 10 window.alert(p2.

面向对象三大特性(封装/继承/多态)

引入:在面向对象思想中,有三大特性,封装  继承  多态. 思考:我们在使用类和对象实现编程的时候,到底是遵循这什么样的逻辑呢?为什么要这样规范类呢? 引入:面向对象很重要的思想就是隐藏,即外部不知道类内部是如何实现业务逻辑的,只管调用和使用结果,这个就是面向对象三大特性之一:  封装 1.封装[掌握] 定义:封装,字面意思就是将内容装到某个容器中,并进行密封保存,在面向对象思想中,封装指数据和对数据的操作捆绑到一起,形成 对外界的隐藏,同时对外提供可以操作的接口. 1.数据:即要操作的数据,在

面向对象三大特性五大原则 + 低耦合高内聚

面向对象三大特性五大原则 + 低耦合高内聚 面向对象的三大特性是"封装."多态"."继承",五大原则是"单一职责原则"."开放封闭原则"."里氏替换原则"."依赖倒置原则"."接口分离原则". 什么是面向对象 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结