基类显式继承接口,类继承基类时又继承同一接口,引发接口方法混乱(显式继承接口的弊端)

基类BaseOutput显式继承了一个接口IOutput,之后类TrackOutput继承BaseOutput,同一时候又继承了IOutput接口。假定IOutput有方法Output,这样在TrackOutput中就有两个Output方法,一个源于基类BaseOutput,于个源于接口IOutput。这样就引发了混乱。要怎么办?先看以下的一段代码

    interface IOutput
    {
        void output();
    }
  class BaseOutput : IOutput
    {
        void IOutput.output()
        {
            Console.WriteLine("IOutput...");
        }
    }

    class TrackOutput : BaseOutput, IOutput
    {
        public void Output()
        {
           Console.WriteLine("TrackOutput...");
           base.Output();
        }
    }

在编译时。base.Output会报错,提示BaseOutput中不包括output的定义。这怎么会这样?BaseOutput不是继承了IOutput的方法,并实现了IOutput中的output的方法了吗?

假设把BaseOutput中对IOutput中的output显式实现。改动为隐式实现。新代码例如以下:

  class BaseOutput : IOutput
    {
         public void output()
        {
            Console.WriteLine("IOutput...");
        }
    }

这样编译就能够通过。并且也可正常执行了,測试代码例如以下:

static void Main(string[] args)
        {
            TrackOutput t = new TrackOutput();
            t.Output();
            Console.ReadLine();
        }

输出正常。所以接口的显式实如今二次继承时,会出现故障。

那假设在BaseOutput中就是须要显式实现IOutput,而在TrackOutput中也须要实现Output,那怎么办?能够考虑两种方案。

方案一:

在TrackOutput中,显式转换成IOutput,然后输出。代码例如以下:

class BaseOutput : IOutput
    {
        void IOutput.output()
        {
            Console.WriteLine("IOutput...");
        }
    }

    class TrackOutput : BaseOutput, IOutput
    {
        public void output()
        {
            Console.WriteLine("TrackOutput...");
            IOutput i = this;
            i.output();
        }
    }

能够看到,结果如我们所期望的输出。只是。这里有一点须要注意,在经过IOutput i=this的转换后。再i调用output方法。会调用TrackOutput的output方法。而调用output方法后,又引发里面的IOutput i=this的转换,然后循环不断,引发无限递归。从而引发问题。

为了解决问题,我有了方案二。

方案二:在基类BaseOutput中添加一个output的虚方法。然后在TrackOutput中重载。

代码例如以下:

  class BaseOutput : IOutput
    {
        void IOutput.output()
        {
            Console.WriteLine("IOutput...");
        } 

        public virtual void output()
        {
            Console.WriteLine("MyOutput...");
        }
    }

    class TrackOutput : BaseOutput, IOutput
    {
        public void output()
        {
            Console.WriteLine("TrackOutput...");
            base.output();
        }
    }

測试结果例如以下:

总结:.在显式继承接口时,假设须要二次继承,记得在基类中添加一个虚方法的实现。不然就使用隐式继承。

转载请注明出处:http://blog.csdn.net/xxdddail/article/details/39393489

时间: 2024-10-14 17:56:36

基类显式继承接口,类继承基类时又继承同一接口,引发接口方法混乱(显式继承接口的弊端)的相关文章

类继承多个接口有相同的方法时,怎么办?(接口显式实现的作用)

在<接口的显式实现与隐式实现>中讲到了接口的显式实现,那有什么作用呢?我们来看一段代码. class Program { static void Main(string[] args) { SimpleOutput s = new SimpleOutput(); IOutput io = s; ILog il = s; s.output(); io.output(); il.output(); Console.ReadLine(); } } interface IOutput { void o

继承、类的高级概念、多态和抽象、接口

private 只能在自己的类中访问得到. public 表 示共有的,在任何类中调到. protected 在所有类中 defult 在自己以及类中调用到. 本类 同一包中不同类 不同包 子类 piviate 是 是 是 是 public 是 是 是 protected 是 是 default 是 extends继承类 super . 类名(): 操类 子类中调用副类方法 public class salary extends Employee{ } 使用“is a ”判断继承是否正确 所有类

【转载】 C++多继承中重写不同基类中相同原型的虚函数

本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: virtual void TestA(); }; class CBaseB { public: virtual void TestB(); }; class CDerived : public CBaseA, public CBaseB { public: virtual void TestA()

python开发面向对象基础:接口类&amp;抽象类&amp;多态&amp;多继承

一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能 开发中容易出现的问题 1 class Alipay: 2 ''' 3 支付宝支付 4 ''' 5 def pay(self,money): 6 print('支付宝支付了%s元'%money) 7 8 class Applepay: 9 ''' 1

Java通过继承thread类与实现Runnable接口实现多线程的区别

Java中线程的创建有两种方式: 1.  通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2.  通过实现Runnable接口,实例化Thread类 一.通过继承Thread类实现多线程 class MyThread extends Thread{ String name = null; int ticket = 0; public MyThread(String name){ this.name = name; } public synchronized v

实现多线程的两种方法:继承Thread类或实现Runnable接口

实现多线程的两种方法:继承Thread类或实现Runnable接口 Java中实现多线程有两种方法:继承Thread类和实现Runnable接口,在程序开发中只要是多线程,我们一般都是实现Runnable接口,原因归结为一点:实现接口比继承类要好. 多线程的第一种实现方式:继承Thread类 步骤如下 创建一个继承Thread的类(假定为A),并重写Thread的run方法 构造一个A类对象,假定为aa 调用aa的start方法.(start方法是从Thread继承过来的) 具体例子如下 pac

Java中继承thread类与实现Runnable接口的区别

Java中线程的创建有两种方式: 1.  通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2.  通过实现Runnable接口,实例化Thread类 在实际应用中,我们经常用到多线程,如车站的售票系统,车站的各个售票口相当于各个线程.当我们做这个系统的时候可能会想到两种方式来实现,继承Thread类或实现Runnable接口,现在看一下这两种方式实现的两种结果. Java代码   package com.threadtest; class MyThread e

JS原型继承和类式继承

类式继承(构造函数) JS中其实是没有类的概念的,所谓的类也是模拟出来的.特别是当我们是用new 关键字的时候,就使得"类"的概念就越像其他语言中的类了.类式继承是在函数对象内调用父类的构造函数,使得自身获得父类的方法和属性.call和apply方法为类式继承提供了支持.通过改变this的作用环境,使得子类本身具有父类的各种属性. JavaScript var father = function() { this.age = 52; this.say = function() { al

5、继承与派生6-虚基类

当某类的部分或全部直接基类是从另一个共同基类派生而来时,在这些直接基类中从上一级共同基类继承来的成员就拥有相同的名称.在派生类的对象中,这些同名数据成员在内存中同时拥有多个拷贝,同一个函数名会有多个映射.我们可以使用作用域分辨符来惟一标识并分别访问他们,也可以将共同基类设置为虚基类,这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射.这样就解决了同名成员的惟一标识问题. 虚基类的声明是在派生类的定义过程中进行的,语法形式: class 派生类名:virtua