Oop 一个对象的行为可以像它实现了一个它有方法签名的接口,而不显式实现该接口?

Oop 一个对象的行为可以像它实现了一个它有方法签名的接口,而不显式实现该接口?,oop,object,programming-languages,duck-typing,Oop,Object,Programming Languages,Duck Typing,我想问一下,这是否是一个有用的概念,其他语言是否做过类似的事情,或者这个想法是否有问题,或者只是不好。如果它有问题,解释它违反了什么原则也将非常感谢 为了明确我的意思,我编写了一些C#伪代码,其中我创建了一个虚构的“lazy”关键字,它提供了这个想法的具体实现。“lazy”关键字指示编译器1)显式将任何具有符合接口约定的函数的对象强制转换为该接口,即使所述对象未显式实现该接口;2)如果所述显式转换函数不存在,则创建它;3。)可以将该对象强制转换回原来的状态,4.)如果对象未实现接口所需的方法,则

我想问一下,这是否是一个有用的概念,其他语言是否做过类似的事情,或者这个想法是否有问题,或者只是不好。如果它有问题,解释它违反了什么原则也将非常感谢

为了明确我的意思,我编写了一些C#伪代码,其中我创建了一个虚构的“lazy”关键字,它提供了这个想法的具体实现。“lazy”关键字指示编译器1)显式将任何具有符合接口约定的函数的对象强制转换为该接口,即使所述对象未显式实现该接口;2)如果所述显式转换函数不存在,则创建它;3。)可以将该对象强制转换回原来的状态,4.)如果对象未实现接口所需的方法,则会出现编译器错误

然后编译并运行以下代码

class Program
{
    public interface iRoll
    {
        public void Roll();
        public int Dimensions { get; set;}
    }

    public class Basketball
    {
        public void Roll()
        {
            Console.WriteLine("I'm a rolling basketball");
        }
        private int _dimensions = 3;
        public int Dimensions { get { return _dimensions; } set { _dimensions = value; } }
        public string Brand = "BallCo.";
    }

    public class Tire
    {
        public void Roll()
        {
            Console.WriteLine("I'm a rolling tire");
        }
        private int _dimensions = 3;
        public int Dimensions { get { return _dimensions; } set { _dimensions = value; } }
    }

    static void Main(string[] args)
    {
        Tire MyTire = new Tire();
        Basketball MyBall = new Basketball();
        var myList = new List<iRoll>();
        myList.Add(lazy iRoll MyTire);
        myList.Add(lazy iRoll MyBall);
        foreach(iRoll myIRoll in myList)
        {
            myIRoll.Roll();
            Console.WriteLine("My dimensions: " + myIRoll.Dimensions);
        }
    }
}
类程序
{
公共接口iRoll
{
公众作废登记册();
公共整数维度{get;set;}
}
公共篮球课
{
公众登记册()
{
WriteLine(“我是一个滚动的篮球”);
}
私有整数维=3;
公共整数维度{get{return}u Dimensions;}set{{u Dimensions=value;}}
public string Brand=“BallCo。”;
}
公营轮胎
{
公众登记册()
{
Console.WriteLine(“我是一个滚动的轮胎”);
}
私有整数维=3;
公共整数维度{get{return}u Dimensions;}set{{u Dimensions=value;}}
}
静态void Main(字符串[]参数)
{
轮胎MyTire=新轮胎();
Basketball MyBall=新篮球();
var myList=新列表();
添加(lazy-iRoll-MyTire);
添加(lazy-iRoll-MyBall);
foreach(我的列表中的iRoll-myIRoll)
{
myIRoll.Roll();
Console.WriteLine(“我的维度:+myIRoll.dimensions”);
}
}
}
这样做的好处不是总是让类疯狂地实现接口,也不必在基类已经具有所需的方法和属性(例如,具有外部库的某些情况下,某些UI控件)时从基类派生来实现自定义接口


好主意,坏主意,坏主意?有没有其他语言对此进行过实验?

谢谢大家提供的信息。我发现了一个有一些有趣信息的网站。需要学习的两个非常重要的相关和不同的概念是和,这两个概念都符合我最初的问题

在我的示例中,C#使用与结构类型不兼容的类型。我提出的“lazy”关键字是一个关键字,它使非imally类型的系统做某些事情,使程序员觉得它像一个结构化类型的系统。例如,在本例中,这应该是一种名义上类型化的语言中的静态duck类型

我想知道是否有人会说lazy关键字不是“真正的”duck类型,而是语义糖让类实现接口,如果lazy关键字的实现细节导致编译器对类进行操作以实现它在编译时需要实现的任何接口。然而,我认为duck类型化是一个面向对象的概念,所以无论编译器做什么,只要最终结果像duck类型化一样,这都应该是duck类型化。请随时纠正我的错误或不同意


中有一个很好的部分,展示了编程语言中的许多例子。

看看Go中使用的“结构类型”(structural typing)。听起来像是你在描述。如果我没有弄错的话,这非常准确地描述了Groovy是如何处理接口的——除了Groovy使用不太明确的机制,任何显式或隐式转换的行为都类似于“Lazy”关键字。事实上,它们有一个相似的语法,你会说“MyTire as iRoll”而不是lazy iRoll MyTire。我有点喜欢有一个关键字,只有当你特别想这样做的时候,你才能这么做,尽管我认为“lazy”不一定是正确的词(考虑到与延迟加载的关联)。可能是“胁迫”之类的?也被称为