提问人:bokabokaboka 提问时间:10/15/2023 最后编辑:bokabokaboka 更新时间:10/26/2023 访问量:82
为什么类继承和接口实现会涉及对象?
Why does class inheritance and interface implementation involve objects?
问:
了解类之间的区别也很重要 继承和接口继承(或子类型化)。类 继承根据另一个对象的实现来定义另一个对象的实现 对象的实现。简而言之,它是一种代码和 表示共享。相反,接口继承(或 subtyping) 描述何时可以使用对象代替 另一个。
这两个概念很容易混淆,因为许多语言没有区分 明确。在C++和Eiffel等语言中,继承意味着两个接口 和实现继承。在 C++ 中继承接口的标准方法是 从具有(纯)虚拟成员函数的类公开继承。纯净的界面 继承可以在 C++ 中通过从纯抽象公开继承来近似 类。纯实现或类继承可以用 private 近似 遗产。在 Smalltalk 中,继承意味着实现继承。您可以 将任何类的实例分配给变量,只要这些实例支持该操作 对变量的值执行。---《设计模式:面向对象的可重用元素》 软件第一版》
继承,不就是子类从父类“继承”属性和方法吗? 它如何成为“一个对象的实现与另一个对象的实现”? 当我在代码中实现从类 A 继承的类 B 时,我根本不实例化任何对象!
接口不就是一种特殊的抽象类吗?(与抽象类相比,接口只声明方法,不声明属性或字段。当一个具体的类实现一个接口时,它不就是一个继承了“接口”并实现接口中声明的方法的类吗?这如何变成“一个对象可以代替另一个对象”? 当我在代码中让类 B 实现接口 A 时,我根本不实例化任何对象!
答:
术语会随着时间的推移而演变;如今,你听到“界面”,就会想到Java、C++和Go等语言的特性,但是当设计模式在1994年问世时,这些语言都还不存在。因此,当它谈到“接口继承”时,它不是它所指的。interface
相反,通过“接口”,它意味着类向其客户端公开的一组功能。当应用于 Java 时,这通常意味着它的公共方法——它们的名称、签名和约定——甚至是 Java 意义上的任何“接口”都没有指定的方法。
在Java等语言中,所有的继承都是“接口继承”;如果类 A 扩展了类 B,那么它会自动实现类 B 的接口(嗯,有一些边缘情况——例如,java.sql.Timestamp 的 Javadoc 说虽然它扩展了 java.util.Date,但我们应该假装它没有,因为它不能 100% 正确地表现为 java.util.Date——但至少就 Java 语言本身而言, 所有的继承都是接口继承,有些类只是有错误。;-) )但对于某些语言来说,情况并非如此;例如,C++ 允许类 A 以“私有”方式从类 B 继承,其中类 A 具有类 B 的所有方法,但它们都是 ,因此客户端无法调用它们。在这种继承中,实现是继承的,但接口不是。这就是设计模式做出这种区分的原因。private
评论
它如何成为“一个对象在另一个对象的实现方面的实现”?当我在代码中实现从类 A 继承的类 B 时,我根本不实例化任何对象!
让我通过 C# 举个例子:
public abstract class Animal
{
public virtual string WhoIAm()
{
return "I am an animal"; // Class inheritance defines an object's
// implementation in terms of
// another object's implementation.
}
}
public class Cow : Animal
{
}
让我们运行上面的代码:
Animal cow = new Cow();
cow.WhoIAm(); // "I am an animal" - this is an example of class inheritance
// defines an object's implementation in terms of
// another object's implementation.
但是,您可以在不违反 Liskov 替换原则的情况下覆盖一些行为:
public class Cow : Animal
{
public override string WhoIAm()
{
return "I am a cow!:)";
}
}
这如何变成“一个对象可以代替另一个对象”?
界面类似于对对象外观的描述。例如,牛通常有四条腿,上面写着“哞哞”。因此,让我们创建以下描述或接口:
public interface IAnimal
{
string WhoIAm();
}
然后,我们将创建上述描述的具体实现:
public class Cow : IAnimal
{
public string WhoIAm()
{
return "I am a cow!:)";
}
}
public class Pig : IAnimal
{
public string WhoIAm()
{
return "I am a pig!:)";
}
}
然后,您可以使用此描述或接口的任何具体实现。可以这样完成:
IAnimal animal = new Cow();
animal.WhoIAm(); // "I am a cow!:)"
animal = new Pig();
animal.WhoIAm(); // "I am a pig!:)"
评论