精华内容
下载资源
问答
  • 求用多态解决问题

    2018-01-03 17:27:51
    SCN,SDN, SNC, STM 返回0 SSN 返回1 SGN 返回2 根据输入字符不同,返回相应的参数,用多态的方法来解决,求高人
  • 在 JAVA多态用在解决什么问题

    千次阅读 2015-07-29 09:49:11
    在 JAVA多态用在解决什么问题? 2011-11-24 07:39wangjianr 分类:JAVA相关 | 浏览 3083 次 分享到: 2011-11-24 07:51 提问者采纳 其实多态是一种面向对象的设计思想...

    在 JAVA多态用在解决什么问题?

    2011-11-24 07:39wangjianr  分类:JAVA相关 | 浏览 3083 次
    2011-11-24 07:51 提问者采纳
    其实多态是一种面向对象的设计思想,也就是只给接口,让你去实现(可以替换实现),就是设计和实现的分离,这个做法有利于软件的重用。
    
    举个例子,你创建了一个动物的抽象类或接口,里面有一些接口方法,你造了一个动物园,然后有各种动物的奔跑、叫唤、吃食等动作作为方法,但你并没有实现它,在没有任何动物之前你只用知道如何把这些动物都圈到笼子里,就有动物园了。
    
    然后,从别处给你运来了老虎、狮子、猴子、狗、猫这些动物,都是实现了你的奔跑、叫唤、吃食这些方法了,这些就是具体动物的实现部分,你把他们挂到你动物园上就行了。这就是多态。
    
    以下是一些理论的描述,请参考:
    
    多态给我们带来的好处,可以归纳为如下5点:
    1.         可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
    2.         可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
    3.         接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。例如,假设超类Shape规定了
        两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如CircleSphere为了实现多态,可以完善或者覆盖这两个接口方法。
    4.         灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
    5.         简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
           值得注意的是,多态并不能够解决提高执行速度的问题,因为它基于动态装载和地址引用,或称动态绑定。但在Java中,除了final类和一定条件下的final方法外,所有方法都由JVM在运行期间进行动态绑定。
    展开全文
  •   在学习《大话设计模式》的时候经常会遇到多态,但什么多态?为什么要使用多态什么时候用多塔?多态是如何实现的?使用多态什么好处?我们将根据以上五个问题展开激烈的讨论。 什么多态?   多态,...

      在学习《大话设计模式》的时候经常会遇到多态,但什么是多态?为什么要使用多态?什么时候用多态?多态是如何实现的?使用多态有什么好处?我们将根据以上五个问题展开激烈的讨论。

    什么是多态?

      多态,顾名思义指“多种形态”。多态表示不同的对象可以执行相同的动作,但要通过它们自己的实现代码来执行。

    例:猪、狗、猫都属于动物类,我们将动物类作为父类,猪“哼哼叫”,狗“汪汪叫”,猫“喵喵叫”,猪、狗、猫三者都能叫,但三者都要通过重写父类的方法才能实现。

    为什么要使用多态?使用多态有什么好处?

      我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。

    代码重用,也称代码复用, 就是说你把一个功能写成一个模块, 以便再次需要相同功能的时候,可以直接使用,而不用重新开发。
    举例: 假如你的网站需要验证码, 你就可以把验证码这个功能单独提取出来以便复用。
    通常代码复用是通过类与对象来实现的, 这也是面向对象编程与面向过程编程最主要的区别之一。

      作为面向对象的三大特性之一,多态也有代码重用的功能,还有解决项目中紧耦合的问题,提高程序的可扩展性·。

    举例:添加一个子类,继承父类,重写父类的方法。至此,该程序的扩展性得到了提升,而又不需要查看源代码是如何实现的就可以扩展新功能。

    什么时候用多态?

    • 方法中的参数
        class Program
        {
            static void Main(string[] args)
            {
                Person p=new Person();
                Audi audi=new Audi();
                p.setDriver(audi);
                p.drive();
                SBenz benz=new SBenz();
                p.setDriver(benz);
                p.drive();
            }
        }
    
        public abstract class Driver
        {
            public abstract void run();
        }
    
        class SBenz : Driver
        {
            public override void run()
            {
                Console.WriteLine("大奔");
            }
        }
    
        class Audi:Driver
        {
            public override void run()
            {
                Console.WriteLine("奥迪");
            }
        }
    
        class Person
        {
            private Driver driver;
            public Person() { }
    
            public Person(Driver driver)
            {
                this.driver = driver;
            }
    
            public void drive()
            {
                driver.run();
            }
    
            public void setDriver(Driver driver)
            {
                this.driver = driver;
            }
        }
    
    • 方法的返回类型
        public class CarFactory
        {
            public static Driver createCar(string carName)
            {
                
                if (carName.Equals("Audi"))
                {
                    return new Audi();
                }
                else if (carName.Equals("Benz"))
                {
                    return new SBenz();
                }
                else
                {
                    Console.WriteLine("出门左拐");
                    return null;
                }
            }
        }
    

    多态是如何实现的?

    • 父类是抽象类,方法是抽象方法(没有方法体,也不能实例化),子类重写父类的方法
    • 父类中是虚方法(有方法体,能实例化),子类重写父类的方法

    小结

    • 虚方法一定要有方法体(哪怕只是大括号),抽象方法一定没有方法体
    • 虚方法可以被子类重写,抽象方法必须被子类重写
    • 如果我们不需要使用父类创建对象,它的存在只是为供子类继承。可以将父类写成抽象(关键字abstract)类,将父类的方法写成抽象方法,子类中的方法仍用关键字override重写
    • 抽象类不能被实例化
    • 多态是指类可以有多种形态,通过修改可以形成多个的实现方法。当子类从父类继承时,它会获得父类的所有方法、字段、属性和事件。若要更改父类的数据和行为,通常有两种选择,第一种是在子类的访问修饰符后加new,就是隐藏了基类(父类)的方法,第二种是在子类中重写父类的方法,更换方法里的内容。

      耐心点,坚强点,总有一天,你承受过的疼痛会有助于你,生活从来不会刻意亏欠谁,它给了你一块阴影,必会在不远的地方撒下阳光。

    展开全文
  • abstract class Employee { public abstract double earnings(); } class YearWorker extends Employee { //重写earnings()方法 ...class MonthWorker extends Employee { ...上述代码中要重写earnings方法,和计算...
  • 什么多态? 概念:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态...而多态除了代码的复用性外,还可以解决项目中紧偶合的问题,提高程序的可扩展性.。耦合度讲的是模块模块之间,...

    什么是多态?

    概念:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单的说:就是用基类的引用指向子类的对象。

     

    为什么要用多态呢?

    原因:我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态除了代码的复用性外,还可以解决项目中紧偶合的问题,提高程序的可扩展性.。耦合度讲的是模块模块之间,代码代码之间的关联度,通过对系统的分析把他分解成一个一个子模块,子模块提供稳定的接口,达到降低系统耦合度的的目的,模块模块之间尽量使用模块接口访问,而不是随意引用其他模块的成员变量。

     

    多态有什么好处?

    有两个好处:

    1. 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。//继承 
    2. 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。 //多态的真正作用

     

    多态在什么地方用?

    可以用在方法的参数中和方法的返回类型中。

    在方法中的参数,请看下面的例子:

    复制代码

       public abstract class Driver
        {
            public void run();//让子类来运行
        }
    
    
    class SBenz : Driver
        {
            public void run()
            {
                Console.WriteLine("Benz在以200迈的速度在run");
            }
        }
    
    
    
    
     class JD : Driver
        {
            public void run()
            {
                Console.WriteLine("JD is running...");
            }
        }
    
    
     class Person
        {
            private Driver driver;
            public Person()
            {
    
            }
            public Person(Driver driver)
            {
                this.driver = driver;
            }
            public void drive()
            {
                driver.run();
            }
            public void setDriver(Driver driver)
            {//运用参数多态,以后不管买什么车都可以
                this.driver = driver;
            }
       }
    
    
    
    
    static void Main(string[] args)
            {
                Person p = new Person();
                JD jd = new JD();//刚开始没钱就买辆JD吧
                p.setDriver(jd);
                p.drive();
                SBenz benz = new SBenz();//有钱换车了
                p.setDriver(benz);
                p.drive();
            }

    复制代码

     

    在方法的返回类型中,请看下面的例子:

    上面的例子中,不管是JD还是Benz都是我们自己直接new出来的.我们可以设计一个工厂类,专门生成汽车

    /**
    *   我们将多态使用在方法的返回类型中
    *   Driver可以是抽象类,也可以是接口,JD和Benz分别继承该类或实现该借口

    */

    复制代码

     public class CarFactory
        {
            public Driver factory(String carName)
            {
                if (carName.Equals("JD"))
                {
                    return new JD();
                }
    
                else if (carName.Equals("Benz"))
                {
                    return new SBenz();
                }
    
                else
                {
                    Console.WriteLine("对比起,不伺候");
                    return null;
                }
            }
        }

    复制代码

    这实际上就是设计模式中的简单工厂模式!

    类型的参数.,传入参数的时候,可以传入任何一个类的对象,只要是对应的类的对象名称就可以了
    这就是多态的应用!

    展开全文
  • 多态问题

    2016-05-06 11:29:47
    这次面试,面试官问了我多态问题,由于当时多静态多态和动态多态不是很清楚,出了丑,所以在这里我总结了一下和大家分享一下多态问题。 6.多态 6.1 静态多态性机制  函数重载、运算符重载。 6.2 ...

    这次面试,面试官问了我多态的问题,由于当时多静态多态和动态多态不是很清楚,出了丑,所以在这里我总结了一下和大家分享一下多态问题。


    6.多态

    6.1 静态多态性机制

        函数重载、运算符重载。

    6.2 动态多态性机制:

        虚函数、抽象类。

    6.3动态多态性

    基类和派生类中可以定义相同原型的函数,但函数体不同,运行时函数处理不同类的函数时,能够绑定对象所属类定义的函数体。动态多态性需要通过动态绑定(晚绑定)来实现。

     

    6.4 多态实现

        需要通过绑定机制,绑定是将一个标识符名和一个存储地址联系在一起的过程。

    (1)编译时的多态通过静态绑定实现

            绑定工作在编译连接阶段完成:函数重载

    (2)运行时的多态通过动态绑定实现

            绑定工作在程序运行阶段完成:虚函数

    6.5 运算符重载

    (1)=, [ ], (), ->这四个运算符只能被重载为类的非静态成员函数,其他的可以被友元重载。

    (2).  ?:  sizeof  ::  .*  这五个运算符不能重载,其他运算符均可重载。

     

     6.5.1 重载为类成员的运算符函数

     

    1)定义形式:

    函数类型 operator 运算符(形参)

    {

           .......

    }

    (2)重载双目运算符为成员函数

         A.如果要重载双目运算符B为类成员函数,使之能够实现表达式oprd1 B oprd2, 其中oprd1必须为一个自定义类(假设为A类)的对象。

         B.如果oprd1不是自定义类的对象,则运算符B不能被重载为类的成员函数。

         C.如果oprd1是自定义类A的对象,则B应被重载为类的成员函数,形参类型应该是oprd2所属的类型。

     

    例:

    Complex Comlex::operate + (const Complex &c2) const{//这里传对象的引用&c2

    //对于传对象,开销比较小,效率比较高吧。为了保证实参的安全性,这里用的

    //是常引用,是只读的引用,只读取数据参与运算,不可以改变原来的操作数。

    //创建一个临时无名对象作为返回值

    return Complex(real+c2.real, imag+c2.img);

    }

    (3)单目运算符“++”重载为成员函数

    对于前置单目运算符,重载函数没有形参,对于后置单目运算符,重载函数有一个int型形参。

    例:

    Class Clock{

    Public:                                //外部接口

    Clock(int hour=0,int minute=0,int second=0);

    Void showTime() const;

    Clock & operator++();                //前置单目运算符重载

    Clock & operator++(int);                //后置单目运算符重载

    Private:

        Int hour,minute,second;

    }

    Clock & operator++(){                    //前置单目运算符重载函数

    second++;

    if(second>=60){

        minute-=60;

        minute++;

        if(minute>=60){

            minute-=60;

            hour=(hour+1)%24;

     

            }

        }

    return *this;

    }

     

    Clock Clock operator++(int){                //后置单目运算符重载函数

    //注意形参表中的整形参数

    Clock old=*this;

    ++(*this);                          //调用前置“++”运算符

    return old;

    }

     

    (4)存在问题,前置++和后置++定义有很大区别,不只是形参int问题,还有&Clock不同。为什么呢?

     

    6.5.2 运算符重载为非成员函数

     

    (1)函数的形参代表依自左至右次序排列的各操作数

    A. 参数个数 原操作数个数(后置++--除外)

    B. 至少应该有一个自定义类型的参数

    (2)后置单目运算符++--的重载函数,形参列表中要增加一个int,但不必写形参名。

    (3)如果在运算符的重载函数中需要操作某类对象的私有成员,可以将此函数声明为该类的友元。

    (4)双目运算符B重载为非成员函数后,

    表达式: oprd1 B oprd2

    等同于 operator B(oprd1, oprd2)

    (5)前置单目运算符B重载后,

    表达式 B oprd

    等同于 operator B(oprd)

    (6)后置单目运算符++--重载后,

    表达式 oprd B

    等同于 operator B(oprd, 0)

    例:以非成员函数形式重载Complex的加减法运算和”<<”运算符

    A. +-(双目)重载为非成员函数,并将其成名为复数类的友元,两个操作都是复数类的常引用。

    B. <<(双目)重载为非成员函数operator<<(ostream &out,const Complex &c),并将其声明为复数类的友元,以支持按下面形式输出复数类对象ab

           Cout<<a<<b;相当于:operator<<(operator<<(cout,a),b);

    C. 它的左操作数是std::ostream引用,右操作数为复数类的常引用

    D. 返回std::ostream引用。

    Class Complex{

    Public:

        complex(double r=0.0,double i=0.0):real(r),imag(i){}

        friend Complex operator + (const Complex &c1 , const Complex &c2);

        friend Complex operator - (const Complex &c1, const Complex &c2);

        friend ostream & operator<<(ostream &out, const Complex &c);

        //c++规定:流对象不允许复制,因此只能用引用&

    Private:

        Double real;

        Double imag; 

    }

    Complex operator +(const Complex &c1, const Complex &c2){

        Return Complex(c1.real+c2.real, c1.imag + c2.imag);

    }

    Complex operator - (const Complex &c1, const Complex &c2){

    Return Complex(c1.real - c2.real, c1.imag - c2.imag);

    }

    ostream & operator<<(ostream &out, const Complex &c){

        out<< “(”<<c.real<<”,”<<c.imag<<”)”;

    return out;

    }

     

    6.6一般虚函数成员

    6.6.1 为什么要有虚函数

     

    问题:如何能在运行时绑定函数调用表达式与函数代码?

    解决:用虚函数(用virtual关键字说明的函数)

    6.6.2 

    C++中在默认情况下,是采用静态绑定,也就是编译时的绑定。

    只有用virtual关键字特别说明的函数才进行动态绑定。

    虚函数必须是非静态的成员函数,虚函数经过派生后仍为虚函数。

    可以实现运行过程中的多态。

    6.6.3 虚函数的声明

    Virtual 函数类型 函数名(参数表);

    虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员函数实现的时候。

    在派生类中可以对基类中的成员函数进行覆盖:

        派生类继承基类的接口

        通过覆盖虚函数改造从基类继承而来的功能。

    虚函数一般不声明为内联函数,因为对虚函数的调用需要动态绑定,而对内联函数的处理是静态的。但将虚函数声明为内联函数也不会引起错误。        

     

    例:

    Class Base1{

    Public:

    Virtual void display() const;  //虚函数,其中的const表示display是常成员函

    //数,只能调用不修改成员变量的函数,和调用常成员变量,因为加上const

    //之后display不允许修改数据,一旦调用了可修改的编译,报错。

    };

    void Base1::disply() const{

    cout<< “Base1::display()”<<endll;

    }

     

    Class Base2::public Base1{

    Public:

        virtual void display() const;

    };

    void Base2::display() const{

    cout<<”Base2::display()”<<endl;

    }

     

    Class Derived::public Base2{

    Public:

    Virtual void display() const;

    };

    Void Derived::display() const{

        cout<<”Derived::display()”<<endl;

    }

    注意:  只要基类中定义了虚函数,派生类中在生命相同原型的函数,也将自动成为虚函数,可以不写virtual关键字。但是最好还是在虚函数前加virtual,使得程序具有更好的可读性。

     

    6.6.4 什么叫做动态绑定和静态绑定

    所谓静态绑定是指在程序编译过程中,把函数(方法或者过程)调用与响应调用所需的代码结合的过程称之为静态绑定。 动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法 除了限制访问,访问方式也决定哪个方法将被子类调用或哪个属性将被子类访问. 

     

    6.7 虚析构函数

    c++中,不能声明虚构造函数,但是可以声明虚析构函数。

     

    6.7.1 虚析构函数的声明语法:

    Virtual ~类名();

     

    6.7.2 为什么要用虚析构函数

     

    (1)如果一个类的析构函数是虚函数,那么由它派生而来的所有子类的析构函数也是虚函数。析构函数设置为虚函数之后,在使用指针引用时可以动态绑定,实现运行时的多态,保证使用基类类型的指针就能够调用适当的析构函数针对不同的对象进行清理工作。

    (2)简单的来说:如果有可能通过基类指针调用对象的析构函数,就需要让基类的析构函数成为虚函数,否则会产生不确定的后果。

    (3)自己理解:这里的虚析构函数是用来,通过基类指针删除派生类对象时调用派生类的析构函数的。如果不把基类的析构函数设置成虚析构函数,派生类的析构函数是不被执行的,会造成内存泄露!

     

    6.7.3 虚表

    (1)每个多态类有一个虚表(virtual table

    (2)虚表中由当前类的各个虚函数的入口地址

    (3)每个对象有一个指向当前类的虚表的指针(虚指针vptr

    6.7.4 动态绑定的实现:

    (1)构造函数中为对象的虚指针赋值

    (2)通过多态类型的指针或引用调用成员函数时,通过虚指针找到虚表,进而找到所调用的虚函数的入口地址。

    (3)通过该入口地址调用虚函数

     

    6.8抽象类

    6.8.1什么是抽象类

    (1)带有纯虚函数的类是抽象类,抽象类的主要作用是通过它为一个类族建立一个公共的接口,使它们能够更有效地发挥多态特性。

    (2)抽象类不能实例化,不能定义一个抽象类的对象,但是可以定义一个抽象类的指针和引用。通过指针或引用,就可以指向并访问派生类的对象,进而访问派生类的成员。

    (3)如果派生类没有给出全部纯虚函数的实现,这时的派生类仍然是一个抽象类。

     

    6.8.2纯虚函数

    (1)纯虚函数的声明格式:

          Virtual 函数类型 函数名 (参数表) = 0;

    实际上,纯虚函数和一般虚函数成员的原型在书写格式上的不同就在于后面加了“=0”。声明为纯虚函数之后,基类中就可以不再给出函数的实现部分。纯虚函数的函数体由派生类给出。

     

    6.8.3 多态类型和非多态类型

    C++的类类型分为两类——多态类型和非多态类型。多态类型是指有虚函数的类型,非多态类型是指所有的其他类型。

    对非多态类的公有继承,应当慎重,而且一般没有太大的必要。

     

    6.8.4 dynamic_cast执行基类向派生类的转换

    dynamic_cast是与static_castconst_castreinterpret_cast并列的4种类型转换操作符之一。它可以将基类的指针显示的转换为派生类的指针,或将基类的引用显示转换为派生类的引用。

    转换前类型必须是指向多态类型的指针,或多态类型的引用,而不能是指向非多态类型的指针或非多态类型的引用。

    例子:

    Void fun(Base *b){

    b->fun1();

    //尝试将b转换为Derived1指针

    Derived1 *d = dynamic_cast<Derived1*>(b); 

    if(d!=0)  d->fun2(); //判断转换是否成功

    }


    展开全文
  • jackson多态解析问题解决方案

    千次阅读 2020-11-18 09:32:11
    jackson实现多态解析 类结构: 接口类:Criteria public interface Criteria { //自己的接口 } 实现类1:AndCriteria @Data public class AndCriteria implements Criteria { //实现的接口 } 实现类2:OrCriteria ...
  • 多态的特点,该怎么使用。多态是用于解决什么问题的呢? 寻找答案,寻找答案,
  • @JsonTypeInfo 主要是用来解决反序列化时,多态问题。 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,include = JsonTypeInfo.As.PROPERTY,property = "@Clazz") //@JsonSubTypes({@JsonSubTypes.Type...
  • 多态

    2020-03-29 21:28:06
    2.Java语言中的多态什么呢? “同一个对象”的行为(方法),在不同的时刻或条件下,表现出不同的效果。 java语言中的多态: a. 编译时多态:方法重载(overload) b. 运行时多态: 才是今天所学习的多态 3.举例 ...
  • python中的多态什么 Python中的多态 (Polymorphism in Python) Polymorphism is a concept of Object Oriented Programming, which means multiple forms or more than one form. Polymorphism enables using a ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 119,313
精华内容 47,725
关键字:

多态解决了什么问题