接口与抽象类(一般面向对象)

发布于 2024-07-17 10:21:25 字数 1244 浏览 7 评论 0原文

我最近接受了两次电话采访,被问到接口和抽象类之间的区别。 我已经把我能想到的各个方面都解释了,但他们似乎在等我说一些具体的东西,而我也不知道那是什么。

根据我的经验,我认为以下内容是正确的。 如果我遗漏了一个要点,请告诉我。

接口:

接口中声明的每个方法都必须在子类中实现。 接口中只能存在事件、委托、属性 (C#) 和方法。 一个类可以实现多个接口。

抽象类:

只有抽象方法必须由子类实现。 抽象类可以有普通方法和实现。 除了事件、委托、属性和方法之外,抽象类还可以具有类变量。 由于C#中不存在多重继承,一个类只能实现一个抽象类。

  1. 毕竟,面试官提出了这样的问题:“如果你有一个只有抽象方法的抽象类怎么办?这与接口有什么不同?” 我不知道答案,但我认为这是上面提到的继承,对吗?

  2. 另一位面试官问我:“如果接口中有一个 Public 变量,这与抽象类中有什么不同?” 我坚持认为接口中不能有公共变量。 我不知道他想听什么,但他也不满意。

另请参阅

I have recently had two telephone interviews where I've been asked about the differences between an Interface and an Abstract class. I have explained every aspect of them I could think of, but it seems they are waiting for me to mention something specific, and I don't know what it is.

From my experience I think the following is true. If I am missing a major point please let me know.

Interface:

Every single Method declared in an Interface will have to be implemented in the subclass.
Only Events, Delegates, Properties (C#) and Methods can exist in an Interface. A class can implement multiple Interfaces.

Abstract Class:

Only Abstract methods have to be implemented by the subclass. An Abstract class can have normal methods with implementations. An Abstract class can also have class variables besides Events, Delegates, Properties and Methods. A class can implement one abstract class only due to the non-existence of Multi-inheritance in C#.

  1. After all that, the interviewer came up with the question "What if you had an Abstract class with only abstract methods? How would that be different from an interface?" I didn't know the answer but I think it's the inheritance as mentioned above right?

  2. Another interviewer asked me, "What if you had a Public variable inside the interface, how would that be different than in a Abstract Class?" I insisted you can't have a public variable inside an interface. I didn't know what he wanted to hear but he wasn't satisfied either.

See Also:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

黎歌 2024-07-24 10:21:25

打个比方:当我在空军时,我参加了飞行员培训并成为一名 USAF(美国空军)飞行员。 那时我没有资格驾驶任何东西,必须参加飞机型号培训。 获得资格后,我成为一名飞行员(抽象类)和 C-141 飞行员(具体类)。 在我的一项任务中,我被赋予了一项额外职责:安全官。 现在我仍然是一名飞行员和 C-141 飞行员,但我还履行安全官职责(可以说,我实施了 ISafetyOfficer)。 飞行员不需要成为安全官员,其他人也可以这样做。

所有美国空军飞行员都必须遵守某些空军范围内的规定,所有 C-141(或 F-16 或 T-38)飞行员“都是”美国空军飞行员。 任何人都可以成为安全员。 因此,总结一下:

  • Pilot:抽象类
  • C-141 Pilot:具体类
  • ISafety 官员:接口

添加注释:这是一个帮助解释概念的类比,而不是编码建议。 看看下面的各种评论,讨论很有趣。

How about an analogy: when I was in the Air Force, I went to pilot training and became a USAF (US Air Force) pilot. At that point I wasn't qualified to fly anything, and had to attend aircraft type training. Once I qualified, I was a pilot (Abstract class) and a C-141 pilot (concrete class). At one of my assignments, I was given an additional duty: Safety Officer. Now I was still a pilot and a C-141 pilot, but I also performed Safety Officer duties (I implemented ISafetyOfficer, so to speak). A pilot wasn't required to be a safety officer, other people could have done it as well.

All USAF pilots have to follow certain Air Force-wide regulations, and all C-141 (or F-16, or T-38) pilots 'are' USAF pilots. Anyone can be a safety officer. So, to summarize:

  • Pilot: abstract class
  • C-141 Pilot: concrete class
  • ISafety Officer: interface

added note: this was meant to be an analogy to help explain the concept, not a coding recommendation. See the various comments below, the discussion is interesting.

尐籹人 2024-07-24 10:21:25

虽然您的问题表明它是针对“一般 OO”,但它似乎确实关注这些术语的 .NET 使用。

在 .NET 中(与 Java 类似):

  • 接口可以没有状态或实现
  • 实现接口的类必须提供该接口的所有方法的实现
  • 抽象类可以包含状态(数据成员)和/或实现(方法)
  • 抽象类可以在不实现抽象方法的情况下被继承(尽管这样的派生类本身就是抽象的)
  • 接口可以是多重继承的,抽象类则不能(这可能是接口与抽象类分开存在的关键具体原因 - 它们允许多重继承的实现消除了一般 MI 的许多问题)。

作为一般的面向对象术语,这些差异不一定是明确定义的。 例如,有些 C++ 程序员可能持有类似的严格定义(接口是不能包含实现的抽象类的严格子集),而有些人可能会说具有某些默认实现的抽象类仍然是一个接口,或者是一个非抽象类。类仍然可以定义接口。

事实上,有一种称为非虚拟接口 (NVI) 的 C++ 习惯用法,其中公共方法是“thunk”到私有虚拟方法的非虚拟方法:

While your question indicates it's for "general OO", it really seems to be focusing on .NET use of these terms.

In .NET (similar for Java):

  • interfaces can have no state or implementation
  • a class that implements an interface must provide an implementation of all the methods of that interface
  • abstract classes may contain state (data members) and/or implementation (methods)
  • abstract classes can be inherited without implementing the abstract methods (though such a derived class is abstract itself)
  • interfaces may be multiple-inherited, abstract classes may not (this is probably the key concrete reason for interfaces to exist separately from abtract classes - they permit an implementation of multiple inheritance that removes many of the problems of general MI).

As general OO terms, the differences are not necessarily well-defined. For example, there are C++ programmers who may hold similar rigid definitions (interfaces are a strict subset of abstract classes that cannot contain implementation), while some may say that an abstract class with some default implementations is still an interface or that a non-abstract class can still define an interface.

Indeed, there is a C++ idiom called the Non-Virtual Interface (NVI) where the public methods are non-virtual methods that 'thunk' to private virtual methods:

半枫 2024-07-24 10:21:25

我认为他们正在寻找的答案是根本的或 OPPS 哲学差异。

当派生类共享抽象类的核心属性和行为时,使用抽象类继承。 实际定义类的行为类型。

另一方面,当类共享外围行为(不一定定义派生类)时,使用接口继承。

例如。 汽车和卡车共享汽车抽象类的许多核心属性和行为,但它们也共享一些外围行为,例如生成排气,甚至非汽车类(例如钻机或发电机)也共享这些行为,并且不一定定义汽车或卡车,因此汽车、卡车、钻机和发电机都可以共享相同的接口 IExhaust。

I think the answer they are looking for is the fundamental or OPPS philosophical difference.

The abstract class inheritance is used when the derived class shares the core properties and behaviour of the abstract class. The kind of behaviour that actually defines the class.

On the other hand interface inheritance is used when the classes share peripheral behaviour, ones which do not necessarily define the derived class.

For eg. A Car and a Truck share a lot of core properties and behaviour of an Automobile abstract class, but they also share some peripheral behaviour like Generate exhaust which even non automobile classes like Drillers or PowerGenerators share and doesn't necessarily defines a Car or a Truck, so Car, Truck, Driller and PowerGenerator can all share the same interface IExhaust.

殊姿 2024-07-24 10:21:25

简而言之:抽象类用于建模类似外观类的类层次结构(例如 Animal 可以是抽象类,Human、Lion、Tiger 可以是具体的派生类)

并且

Interface 用于 2个相似/不相似的类之间的通信,不关心实现接口的类的类型(例如,高度可以是接口属性,它可以由人类,建筑,树来实现。如果你能吃东西并不重要,你可以游泳,你可以死或任何东西......这只是你需要有高度(在你的班级中实现)的事情。

Short: Abstract classes are used for Modelling a class hierarchy of similar looking classes (For example Animal can be abstract class and Human , Lion, Tiger can be concrete derived classes)

AND

Interface is used for Communication between 2 similar / non similar classes which does not care about type of the class implementing Interface(e.g. Height can be interface property and it can be implemented by Human , Building , Tree. It does not matter if you can eat , you can swim you can die or anything.. it matters only a thing that you need to have Height (implementation in you class) ).

笑忘罢 2024-07-24 10:21:25

还有一些其他差异 -

接口不能有任何具体的实现。 抽象基类可以。 这允许您在那里提供具体的实现。 这可以允许抽象基类实际上提供更严格的契约,而接口实际上仅描述类的使用方式。 (抽象基类可以具有定义行为的非虚拟成员,这为基类作者提供了更多控制权。)

一个类可以实现多个接口。 一个类只能从一个抽象基类派生。 这允许使用接口的多态层次结构,但不允许使用抽象基类。 这还允许使用接口进行伪多重继承。

可以在 v2+ 中修改抽象基类,而不会破坏 API。 界面的改变是破坏性的改变。

[C#/.NET 特定] 与抽象基类不同,接口可以应用于值类型(结构)。 结构不能从抽象基类继承。 这允许将行为契约/使用指南应用于价值类型。

There are a couple of other differences -

Interfaces can't have any concrete implementations. Abstract base classes can. This allows you to provide concrete implementations there. This can allow an abstract base class to actually provide a more rigorous contract, wheras an interface really only describes how a class is used. (The abstract base class can have non-virtual members defining the behavior, which gives more control to the base class author.)

More than one interface can be implemented on a class. A class can only derive from a single abstract base class. This allows for polymorphic hierarchy using interfaces, but not abstract base classes. This also allows for a pseudo-multi-inheritance using interfaces.

Abstract base classes can be modified in v2+ without breaking the API. Changes to interfaces are breaking changes.

[C#/.NET Specific] Interfaces, unlike abstract base classes, can be applied to value types (structs). Structs cannot inherit from abstract base classes. This allows behavioral contracts/usage guidelines to be applied on value types.

酒儿 2024-07-24 10:21:25

继承
考虑一辆汽车和一辆公共汽车。 它们是两种不同的车辆。 但它们仍然有一些共同的特性,比如它们有转向、刹车、齿轮、发动机等。
因此,通过继承概念,这可以表示为以下内容......

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

现在是一辆自行车......

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

还有一辆汽车......

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

这就是继承。 正如我们上面所看到的,我们使用它们将对象分类为更简单的基本形式及其子形式。

抽象类

抽象类是不完整对象。 为了进一步理解它,让我们再次考虑车辆的类比。
可以驾驶车辆。 正确的? 但不同的车辆以不同的方式驾驶......例如,你不能像驾驶自行车一样驾驶汽车。
那么如何表示车辆的驱动功能呢? 更难检查它是什么类型的车辆并以其自身的功能驾驶它; 添加新类型的车辆时,您必须一次又一次地更改 Driver 类。
这就说到了抽象类和方法的作用。 您可以将drive方法定义为抽象方法,以告诉每个继承的孩子必须实现此功能。
因此,如果您修改车辆类别...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

Bicycle 和 Car 也必须指定如何驾驶它。 否则,代码将无法编译并引发错误。
简而言之......抽象类是一个部分不完整的类,具有一些不完整的功能,继承的子类必须指定自己的功能。

接口
接口完全不完整。 他们没有任何属性。 它们只是表明继承的孩子有能力做某事......
假设您有不同类型的手机。 他们每个人都有不同的方式来完成不同的功能; 例如:给一个人打电话。 手机制造商指定了如何操作。 这里手机可以拨打号码——即可以拨打。 让我们将其表示为一个接口。

public interface Dialable {
    public void dial(Number n);
}

这里 Dialable 的制造商定义了如何拨打号码。 您只需给它一个号码即可拨打。

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

通过使用接口而不是抽象类,使用 Dialable 的函数的编写者不必担心它的属性。 例如:它是否有触摸屏或拨号盘,是固定电话还是移动电话。 您只需要知道它是否可拨号即可; 它是否继承(或实现)Dialable 接口。

更重要的是,如果有一天您将 Dialable 切换为另一个,

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

您可以确定代码仍然可以完美运行,因为使用 dialable 的函数不会(也不能)依赖于除那些在Dialable 接口中指定的。 它们都实现了 Dialable 接口,这是该函数唯一关心的事情。

开发人员通常使用接口来确保对象之间的互操作性(可互换使用),只要它们共享共同的功能(就像您可以更改为固定电话或移动电话,只要您只需要拨打一个号码)。 简而言之,接口是抽象类的简单版本,没有任何属性。
另请注意,您可以实现(继承)任意数量的接口,但只能扩展(继承)单个父类。

更多信息
抽象类与接口

Inheritance
Consider a car and a bus. They are two different vehicles. But still, they share some common properties like they have a steering, brakes, gears, engine etc.
So with the inheritance concept, this can be represented as following ...

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

Now a Bicycle ...

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

And a Car ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

That's all about Inheritance. We use them to classify objects into simpler Base forms and their children as we saw above.

Abstract Classes

Abstract classes are incomplete objects. To understand it further, let's consider the vehicle analogy once again.
A vehicle can be driven. Right? But different vehicles are driven in different ways ... For example, You cannot drive a car just as you drive a Bicycle.
So how to represent the drive function of a vehicle? It is harder to check what type of vehicle it is and drive it with its own function; you would have to change the Driver class again and again when adding a new type of vehicle.
Here comes the role of abstract classes and methods. You can define the drive method as abstract to tell that every inheriting children must implement this function.
So if you modify the vehicle class ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

The Bicycle and Car must also specify how to drive it. Otherwise, the code won't compile and an error is thrown.
In short.. an abstract class is a partially incomplete class with some incomplete functions, which the inheriting children must specify their own.

Interfaces
Interfaces are totally incomplete. They do not have any properties. They just indicate that the inheriting children are capable of doing something ...
Suppose you have different types of mobile phones with you. Each of them has different ways to do different functions; Ex: call a person. The maker of the phone specifies how to do it. Here the mobile phones can dial a number - that is, it is dial-able. Let's represent this as an interface.

public interface Dialable {
    public void dial(Number n);
}

Here the maker of the Dialable defines how to dial a number. You just need to give it a number to dial.

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Hereby using interfaces instead of abstract classes, the writer of the function which uses a Dialable need not worry about its properties. Ex: Does it have a touch-screen or dial pad, Is it a fixed landline phone or mobile phone. You just need to know if it is dialable; does it inherit(or implement) the Dialable interface.

And more importantly, if someday you switch the Dialable with a different one

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

You can be sure that the code still works perfectly because the function which uses the dialable does not (and cannot) depend on the details other than those specified in the Dialable interface. They both implement a Dialable interface and that's the only thing the function cares about.

Interfaces are commonly used by developers to ensure interoperability(use interchangeably) between objects, as far as they share a common function (just like you may change to a landline or mobile phone, as far as you just need to dial a number). In short, interfaces are a much simpler version of abstract classes, without any properties.
Also, note that you may implement(inherit) as many interfaces as you want but you may only extend(inherit) a single parent class.

More Info
Abstract classes vs Interfaces

风透绣罗衣 2024-07-24 10:21:25

这些答案都太长了。

  • 接口用于定义行为。

  • 抽象类用于定义事物本身,包括其行为。 这就是为什么我们有时会创建一个带有一些继承接口的额外属性的抽象类。

这也解释了为什么Java只支持类的单继承,而对接口没有限制。 因为一个具体的对象不可能是不同的事物,但它可以有不同的行为。

These answers are all too long.

  • Interfaces are for defining behaviors.

  • Abstract classes are for defining a thing itself, including its behaviors. That's why we sometimes create an abstract class with some extra properties inheriting an interface.

This also explains why Java only supports single inheritance for classes but puts no restriction on interfaces. Because a concrete object can not be different things, but it can have different behaviors.

怎言笑 2024-07-24 10:21:25

采访者们正在对一棵奇怪的树咆哮。 对于 C# 和 Java 等语言,存在差异,但在 C++ 等其他语言中则没有差异。 面向对象理论并不区分两者,只是区分语言的语法。

抽象类是同时具有将被继承的实现和接口(纯虚方法)的类。 接口通常没有任何实现,只有纯虚函数。

在 C# 或 Java 中,没有任何实现的抽象类与接口的不同之处仅在于用于继承它的语法以及只能从一个接口继承这一事实。

The interviewers are barking up an odd tree. For languages like C# and Java, there is a difference, but in other languages like C++ there is not. OO theory doesn't differentiate the two, merely the syntax of language.

An abstract class is a class with both implementation and interface (pure virtual methods) that will be inherited. Interfaces generally do not have any implementation but only pure virtual functions.

In C# or Java an abstract class without any implementation differs from an interface only in the syntax used to inherit from it and the fact you can only inherit from one.

山人契 2024-07-24 10:21:25

通过实现接口,您可以实现组合(“has-a”关系)而不是继承(“is-a”关系)。 当涉及到设计模式之类的事情时,这是一个需要记住的重要原则,在设计模式中,您需要使用接口来实现行为组合而不是继承。

By implementing interfaces you are achieving composition ("has-a" relationships) instead of inheritance ("is-a" relationships). That is an important principle to remember when it comes to things like design patterns where you need to use interfaces to achieve a composition of behaviors instead of an inheritance.

椵侞 2024-07-24 10:21:25

从概念上讲,保持语言特定的实现、规则、好处,并通过使用任何人或两者来实现任何编程目标,可以或不能有代码/数据/属性,等等,单继承或多继承,全部放在一边

1-抽象(或纯抽象) ) 类的目的是实现层次结构。 如果您的业务对象在结构上看起来有些相似,表示父子(层次结构)类型的关系,那么才会使用继承/抽象类。 如果您的业务模型没有层次结构,则不应使用继承(这里我不是在谈论编程逻辑,例如某些设计模式需要继承)。 从概念上讲,抽象类是 OOP 中实现业务模型层次结构的一种方法,它与接口无关,实际上将抽象类与接口进行比较是没有意义的,因为两者在概念上是完全不同的东西,在面试中被要求只是为了检查概念,因为在实现方面,它们看起来都提供了一些相同的功能,而我们程序员通常更强调编码。 [还要记住,抽象与抽象类不同]。

2- 接口是一种契约,是由一组或多组功能表示的完整业务功能。 这就是为什么它是被实现而不是被继承的。 业务对象(无论是否属于层次结构的一部分)可以具有任意数量的完整业务功能。 它与抽象类无关,抽象类意味着一般的继承。 例如,人可以RUN,大象可以RUN,鸟可以RUN等等,所有这些不同层次的对象都将实现RUN接口或EAT或SPEAK接口。 不要进入实现,因为您可能会将其实现为为实现这些接口的每种类型提供抽象类。 任何层次结构的对象都可以具有与其层次结构无关的功能(接口)。

我相信,接口不是为了实现多重继承或公开公共行为而发明的,同样,纯抽象类也不是为了推翻接口,而是接口是对象可以执行的功能(通过该接口的函数),而抽象类代表一个层次结构的父级产生具有父级核心结构(属性+功能)的子级

当您被问及差异时,它实际上是概念上的差异,而不是特定于语言的实现中的差异,除非明确询问。

我相信,两位面试官都期望这两者之间有一个直接的区别,当你失败时,他们试图通过将一个作为另一个来驱使你走向这一差异

如果您有一个仅包含抽象方法的抽象类怎么办?

Conceptually speaking, keeping the language specific implementation, rules, benefits and achieving any programming goal by using anyone or both, can or cant have code/data/property, blah blah, single or multiple inheritances, all aside

1- Abstract (or pure abstract) Class is meant to implement hierarchy. If your business objects look somewhat structurally similar, representing a parent-child (hierarchy) kind of relationship only then inheritance/Abstract classes will be used. If your business model does not have a hierarchy then inheritance should not be used (here I am not talking about programming logic e.g. some design patterns require inheritance). Conceptually, abstract class is a method to implement hierarchy of a business model in OOP, it has nothing to do with Interfaces, actually comparing Abstract class with Interface is meaningless because both are conceptually totally different things, it is asked in interviews just to check the concepts because it looks both provide somewhat same functionality when implementation is concerned and we programmers usually emphasize more on coding. [Keep this in mind as well that Abstraction is different than Abstract Class].

2- an Interface is a contract, a complete business functionality represented by one or more set of functions. That is why it is implemented and not inherited. A business object (part of a hierarchy or not) can have any number of complete business functionality. It has nothing to do with abstract classes means inheritance in general. For example, a human can RUN, an elephant can RUN, a bird can RUN, and so on, all these objects of different hierarchy would implement the RUN interface or EAT or SPEAK interface. Don't go into implementation as you might implement it as having abstract classes for each type implementing these interfaces. An object of any hierarchy can have a functionality(interface) which has nothing to do with its hierarchy.

I believe, Interfaces were not invented to achieve multiple inheritances or to expose public behavior, and similarly, pure abstract classes are not to overrule interfaces but Interface is a functionality that an object can do (via functions of that interface) and Abstract Class represents a parent of a hierarchy to produce children having core structure (property+functionality) of the parent

When you are asked about the difference, it is actually conceptual difference not the difference in language-specific implementation unless asked explicitly.

I believe, both interviewers were expecting one line straightforward difference between these two and when you failed they tried to drove you towards this difference by implementing ONE as the OTHER

What if you had an Abstract class with only abstract methods?

风尘浪孓 2024-07-24 10:21:25

我将解释接口和抽象类的深度细节。如果您了解接口和抽象类的概述,那么第一个问题就会出现在您的脑海中:什么时候应该使用接口,什么时候应该使用抽象类。
因此,请检查以下接口和抽象类的解释。

  1. 什么时候应该使用接口?

    如果您不了解实现,只是我们有需求规范,那么我们就使用接口

  2. 什么时候应该使用抽象类?

    如果您知道实现但不完全(部分实现),那么我们使用抽象类。

    界面

    默认情况下,每个方法都是公共抽象,意味着接口是 100% 纯抽象。

    摘要

    可以有具体方法和抽象方法,什么是具体方法,具体方法在抽象类中有实现,
    抽象类是被声明为抽象的类,它可能包含抽象方法,也可能不包含抽象方法。

    界面

    我们不能将接口声明为私有的、受保护的

    问。 为什么我们不将接口声明为私有且受保护的?

    因为默认情况下接口方法是公共抽象的,所以我们没有将接口声明为私有和受保护的。

    接口方法
    我们也不能将接口声明为 private、protected、final、static、synchronized、native...

    我会给出原因:
    为什么我们没有声明同步方法,因为我们无法创建接口对象,并且同步是在对象上工作的,所以我们没有声明同步方法的原因
    瞬态概念也不适用,因为瞬态与同步一起工作。

    摘要

    我们很乐意与公共、私有最终静态一起使用......意味着抽象中没有适用的限制。

    界面

    默认情况下,变量在接口中声明为公共静态最终变量,因此我们也没有将变量声明为私有、受保护的变量。

    Volatile 修饰符也不适用于接口,因为接口变量默认是 public static Final 和 Final 变量,一旦将值分配给变量,您就无法更改该值,并且一旦将变量声明到接口中,您必须分配该变量。< /p>

    并且 volatile 变量会不断变化,所以它是 opp。 到final,这就是我们不在接口中使用易失性变量的原因。

    摘要

    抽象变量不需要声明 public static final。

我希望这篇文章有用。

i will explain Depth Details of interface and Abstract class.if you know overview about interface and abstract class, then first question arrive in your mind when we should use Interface and when we should use Abstract class.
So please check below explanation of Interface and Abstract class.

  1. When we should use Interface?

    if you don't know about implementation just we have requirement specification then we go with Interface

  2. When we should use Abstract Class?

    if you know implementation but not completely (partially implementation) then we go with Abstract class.

    Interface

    every method by default public abstract means interface is 100% pure abstract.

    Abstract

    can have Concrete method and Abstract method, what is Concrete method, which have implementation in Abstract class,
    An abstract class is a class that is declared abstract—it may or may not include abstract methods.

    Interface

    We cannot declared interface as a private, protected

    Q. Why we are not declaring Interface a private and protected?

    Because by default interface method is public abstract so and so that reason that we are not declaring the interface as private and protected.

    Interface method
    also we cannot declared interface as private,protected,final,static,synchronized,native.....

    i will give the reason:
    why we are not declaring synchronized method because we cannot create object of interface and synchronize are work on object so and son reason that we are not declaring the synchronized method
    Transient concept are also not applicable because transient work with synchronized.

    Abstract

    we are happily use with public,private final static.... means no restriction are applicable in abstract.

    Interface

    Variables are declared in Interface as a by default public static final so we are also not declared variable as a private, protected.

    Volatile modifier is also not applicable in interface because interface variable is by default public static final and final variable you cannot change the value once it assign the value into variable and once you declared variable into interface you must to assign the variable.

    And volatile variable is keep on changes so it is opp. to final that is reason we are not use volatile variable in interface.

    Abstract

    Abstract variable no need to declared public static final.

i hope this article is useful.

丶情人眼里出诗心の 2024-07-24 10:21:25

对于.Net,

您对第二个面试官的回答也是对第一个面试官的回答...抽象类可以有实现,并且状态,接口不能...

编辑:在另一个注释中,我什至不会使用短语'子类”(或“继承”短语)来描述“定义为实现”接口的类。 对我来说,接口是一个契约的定义,如果类被定义为“实现”该接口,则该类必须遵守该契约。 它不会继承任何东西...您必须自己显式地添加所有内容。

For .Net,

Your answer to The second interviewer is also the answer to the first one... Abstract classes can have implementation, AND state, interfaces cannot...

EDIT: On another note, I wouldn't even use the phrase 'subclass' (or the 'inheritance' phrase) to describe classes that are 'defined to implement' an interface. To me, an interface is a definition of a contract that a class must conform to if it has been defined to 'implement' that interface. It does not inherit anything... You have to add everything yourself, explicitly.

自演自醉 2024-07-24 10:21:25

接口:如果你想在组件上暗示一条规则,该规则可能是也可能不是,则应该使用
彼此相关

优点:

  1. 允许多重继承
  2. 通过不公开上下文中使用的对象的确切类型来提供抽象,
  3. 通过合约的特定签名提供一致性

缺点:

  1. 必须实现所有定义的契约
  2. 不能有变量或委托
  3. 一旦定义就不能在不破坏所有类的情况下进行更改

抽象类:应该在您想要一些基本或默认值的地方使用彼此相关的组件的行为或实现

优点:

  1. 比接口更快
  2. 实现具有灵活性(您可以完全或部分实现它)
  3. 可以轻松更改,而不会破坏派生类

缺点:< /strong>

  1. 无法实例化
  2. 不支持多重继承

Interface : should be used if you want to imply a rule on the components which may or may not be
related to each other

Pros:

  1. Allows multiple inheritance
  2. Provides abstraction by not exposing what exact kind of object is being used in the context
  3. provides consistency by a specific signature of the contract

Cons:

  1. Must implement all the contracts defined
  2. Cannot have variables or delegates
  3. Once defined cannot be changed without breaking all the classes

Abstract Class : should be used where you want to have some basic or default behaviour or implementation for components related to each other

Pros:

  1. Faster than interface
  2. Has flexibility in the implementation (you can implement it fully or partially)
  3. Can be easily changed without breaking the derived classes

Cons:

  1. Cannot be instantiated
  2. Does not support multiple inheritance
财迷小姐 2024-07-24 10:21:25

我认为他们不喜欢你的回应,因为你给出了技术差异而不是设计差异。 这个问题对我来说就像一个巨魔问题。 事实上,接口和抽象类具有完全不同的性质,因此您无法真正比​​较它们。 我将向您介绍接口的作用和抽象类的作用是什么。

接口:用于确保契约并在类之间实现低耦合,以便拥有更可维护、可扩展和可测试的应用程序。

抽象类:仅用于分解具有相同职责的类之间的一些代码。 请注意,这是 OOP 中多重继承是一件坏事的主要原因,因为 类不应该处理许多职责(使用组合代替)。

因此,接口具有真正的架构作用,而抽象类几乎只是实现的细节(当然,如果你正确使用它的话)。

I think they didn't like your response because you gave the technical differences instead of design ones. The question is like a troll question for me. In fact, interfaces and abstract classes have a completely different nature so you cannot really compare them. I will give you my vision of what is the role of an interface and what is the role of an abstract class.

interface: is used to ensure a contract and make a low coupling between classes in order to have a more maintainable, scalable and testable application.

abstract class: is only used to factorize some code between classes of the same responsability. Note that this is the main reason why multiple-inheritance is a bad thing in OOP, because a class shouldn't handle many responsabilities (use composition instead).

So interfaces have a real architectural role whereas abstract classes are almost only a detail of implementation (if you use it correctly of course).

夜巴黎 2024-07-24 10:21:25
  1. 界面:
    • 我们不实现(或定义)方法,而是在派生类中实现。
    • 我们不在接口中声明成员变量。
    • 接口表达了HAS-A关系。 这意味着它们是物体的面具。
  2. 抽象类:
    • 我们可以在抽象类中声明和定义方法。
    • 我们隐藏它的构造函数。 这意味着没有直接从它创建的对象。
    • 抽象类可以保存成员变量。
    • 派生类继承到抽象类,这意味着派生类的对象不会被屏蔽,而是继承到抽象类。 本例中的关系是 IS-A。

这是我的意见。

  1. Interface:
    • We do not implement (or define) methods, we do that in derived classes.
    • We do not declare member variables in interfaces.
    • Interfaces express the HAS-A relationship. That means they are a mask of objects.
  2. Abstract class:
    • We can declare and define methods in abstract class.
    • We hide constructors of it. That means there is no object created from it directly.
    • Abstract class can hold member variables.
    • Derived classes inherit to abstract class that mean objects from derived classes are not masked, it inherit to abstract class. The relationship in this case is IS-A.

This is my opinion.

墟烟 2024-07-24 10:21:25
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

Docs明确指出,如果抽象类只包含抽象方法声明,则应该声明它作为一个接口。

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

接口中的变量默认是公共静态和最终的。 问题可以这样设计:如果抽象类中的所有变量都是公共的怎么办? 与接口中的变量不同,它们仍然可以是非静态和非最终的。

最后,我想对上面提到的内容再补充一点——抽象类仍然是类,并且属于单个继承树,而接口可以存在于多重继承中。

After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

Docs clearly say that if an abstract class contains only abstract method declarations, it should be declared as an interface instead.

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

Variables in Interfaces are by default public static and final. Question could be framed like what if all variables in abstract class are public? Well they can still be non static and non final unlike the variables in interfaces.

Finally I would add one more point to those mentioned above - abstract classes are still classes and fall in a single inheritance tree whereas interfaces can be present in multiple inheritance.

叫思念不要吵 2024-07-24 10:21:25

太长;博士; 当您看到“Is A”关系时,请使用继承/抽象类。 当您看到“有”关系时,创建成员变量。 当您看到“依赖于外部提供者”时,请实现(而不是继承)接口。

面试问题:接口和抽象类有什么区别? 您如何决定何时使用什么? 我大多得到以下一个或全部答案: 答案1:你不能创建抽象类和接口的对象。

ZK(这是我名字的缩写):你不能创建其中任何一个的对象。 所以这没有区别。 这是接口和抽象类之间的相似之处。 反问:为什么不能创建抽象类或接口的对象?

答案 2:抽象类可以有一个函数体作为部分/默认实现。

ZK:反问:所以如果我将其更改为纯抽象类,将所有虚函数标记为抽象,并且不为任何虚函数提供默认实现。 这会使抽象类和接口相同吗? 之后它们可以互换使用吗?

答案 3:接口允许多重继承,而抽象类则不允许。

ZK:反问:你真的继承了接口吗? 或者您只是实现一个接口并从抽象类继承? 实现和继承有什么区别? 这些反问问题让候选人感到困惑,让大多数人摸不着头脑,或者直接转向下一个问题。 这让我认为人们需要有关面向对象编程的这些基本构建块的帮助。 原始问题和所有反问题的答案可以在英语和 UML 中找到。 您必须至少了解以下内容才能更好地理解这两个结构。

普通名词:普通名词是同一类或同类事物的“共同”名称。 例如水果、动物、城市、汽车等。

专有名词:专有名词是物体、地点或事物的名称。 苹果、卡特彼勒、纽约、本田雅阁等。

汽车是一个普通名词。 本田雅阁是一个专有名词,并且可能是一个复合专有名词,一个使用两个名词组成的专有名词。

来到 UML 部分。 您应该熟悉以下关系:

  • Is A
  • Has A
  • Uses

让我们考虑以下两个句子。 - 本田雅阁是汽车吗? - 本田雅阁有车吗?

哪一个听起来正确? 简单的英语和理解能力。 本田雅阁和汽车公司有着“Is A”的关系。 本田雅阁里面没有汽车。 这是辆车。 本田雅阁“有一个”音乐播放器。

当两个实体共享“Is A”关系时,它是继承的更好候选者。 Has a 关系是创建成员变量的更好候选者。 建立后,我们的代码如下所示:

abstract class Car
{
   string color;
   int speed;
}
class HondaAccord : Car
{
   MusicPlayer musicPlayer;
}

现在本田不生产音乐播放器。 或者至少这不是他们的主要业务。

于是他们联系其他公司并签订了合同。 如果您在这里接收电源并在这两条线上接收输出信号,那么这些扬声器就会正常播放。

这使得音乐播放器成为界面的完美候选者。 只要连接工作正常,您并不关心谁为其提供支持。

您可以将 LG 的 MusicPlayer 替换为 Sony 或其他方式。 这不会改变本田雅阁的任何事情。

为什么不能创建抽象类的对象?

因为你不能走进陈列室并说给我一辆车。 您必须提供一个专有名词。 什么车? 应该是本田雅阁。 那时销售代理可以为您提供一些东西。

为什么不能创建接口的对象? 因为你不能走进陈列室并说给我一份音乐播放器合同。 这不会有帮助。 消费者和提供商之间的接口只是为了促进达成协议。 您将如何处理协议副本? 它不会播放音乐。

为什么接口允许多重继承?

接口不是继承的。 接口已实现。 界面是与外部世界交互的候选者。 本田雅阁有一个加油接口。 它具有用于给轮胎充气的接口。 以及用于给足球充气的同一软管。 因此,新代码将如下所示:

abstract class Car
{
    string color;
    int speed;
}
class HondaAccord : Car, IInflateAir, IRefueling
{
    MusicPlayer musicPlayer;
}

英文将如下所示:“本田雅阁是一款支持轮胎充气和加油的汽车”。

tl;dr; When you see “Is A” relationship use inheritance/abstract class. when you see “has a” relationship create member variables. When you see “relies on external provider” implement (not inherit) an interface.

Interview Question: What is the difference between an interface and an abstract class? And how do you decide when to use what? I mostly get one or all of the below answers: Answer 1: You cannot create an object of abstract class and interfaces.

ZK (That’s my initials): You cannot create an object of either. So this is not a difference. This is a similarity between an interface and an abstract class. Counter Question: Why can’t you create an object of abstract class or interface?

Answer 2: Abstract classes can have a function body as partial/default implementation.

ZK: Counter Question: So if I change it to a pure abstract class, marking all the virtual functions as abstract and provide no default implementation for any virtual function. Would that make abstract classes and interfaces the same? And could they be used interchangeably after that?

Answer 3: Interfaces allow multi-inheritance and abstract classes don’t.

ZK: Counter Question: Do you really inherit from an interface? or do you just implement an interface and, inherit from an abstract class? What’s the difference between implementing and inheriting? These counter questions throw candidates off and make most scratch their heads or just pass to the next question. That makes me think people need help with these basic building blocks of Object-Oriented Programming. The answer to the original question and all the counter questions is found in the English language and the UML. You must know at least below to understand these two constructs better.

Common Noun: A common noun is a name given “in common” to things of the same class or kind. For e.g. fruits, animals, city, car etc.

Proper Noun: A proper noun is the name of an object, place or thing. Apple, Cat, New York, Honda Accord etc.

Car is a Common Noun. And Honda Accord is a Proper Noun, and probably a Composit Proper noun, a proper noun made using two nouns.

Coming to the UML Part. You should be familiar with below relationships:

  • Is A
  • Has A
  • Uses

Let’s consider the below two sentences. - HondaAccord Is A Car? - HondaAccord Has A Car?

Which one sounds correct? Plain English and comprehension. HondaAccord and Cars share an “Is A” relationship. Honda accord doesn’t have a car in it. It “is a” car. Honda Accord “has a” music player in it.

When two entities share the “Is A” relationship it’s a better candidate for inheritance. And Has a relationship is a better candidate for creating member variables. With this established our code looks like this:

abstract class Car
{
   string color;
   int speed;
}
class HondaAccord : Car
{
   MusicPlayer musicPlayer;
}

Now Honda doesn't manufacture music players. Or at least it’s not their main business.

So they reach out to other companies and sign a contract. If you receive power here and the output signal on these two wires it’ll play just fine on these speakers.

This makes Music Player a perfect candidate for an interface. You don’t care who provides support for it as long as the connections work just fine.

You can replace the MusicPlayer of LG with Sony or the other way. And it won’t change a thing in Honda Accord.

Why can’t you create an object of abstract classes?

Because you can’t walk into a showroom and say give me a car. You’ll have to provide a proper noun. What car? Probably a honda accord. And that’s when a sales agent could get you something.

Why can’t you create an object of an interface? Because you can’t walk into a showroom and say give me a contract of music player. It won’t help. Interfaces sit between consumers and providers just to facilitate an agreement. What will you do with a copy of the agreement? It won’t play music.

Why do interfaces allow multiple inheritance?

Interfaces are not inherited. Interfaces are implemented. The interface is a candidate for interaction with the external world. Honda Accord has an interface for refueling. It has interfaces for inflating tires. And the same hose that is used to inflate a football. So the new code will look like below:

abstract class Car
{
    string color;
    int speed;
}
class HondaAccord : Car, IInflateAir, IRefueling
{
    MusicPlayer musicPlayer;
}

And the English will read like this “Honda Accord is a Car that supports inflating tire and refueling”.

用心笑 2024-07-24 10:21:25

由 Jeffrey Richter 通过 C# 从 CLR 复制...

我经常听到这样的问题:“我应该设计基本类型还是接口?” 答案并不总是明确的。

以下是一些可能对您有所帮助的准则:

IS-A 与 CAN-DO 关系 类型只能继承一种实现。 如果导出的
类型不能声明与基类型的 IS-A 关系,不要使用基类型; 使用一个接口。
接口意味着 CAN-DO 关系。 如果 CAN-DO 功能似乎属于
对于各种对象类型,使用接口。 例如,类型可以转换其自身的实例
到另一种类型(IConvertible),类型可以序列化其自身的实例(ISerialized),
等等。请注意,值类型必须派生自 System.ValueType,因此,它们不能
从任意基类派生。 在这种情况下,您必须使用 CAN-DO 关系
并定义一个接口。

■■ 易于使用 作为开发人员,通常更容易定义从派生的新类型
基类型而不是实现接口的所有方法。 基本类型可以提供
很多功能,因此派生类型可能只需要对其行为进行相对较小的修改。 如果您提供接口,则新类型必须实现所有成员。

■■ 一致的实现无论接口契约的文档记录得多么好,它
每个人都 100% 正确执行合同的可能性很小。 事实上,COM
就遇到了这个问题,这就是为什么某些 COM 对象只能在以下情况下正常工作的原因:
微软
Word 或 Windows Internet Explorer。 通过提供一个具有良好性能的基本类型
默认实现,您首先使用有效且经过良好测试的类型; 那么你可以
修改需要修改的部分。

■■ 版本控制如果向基类型添加方法,则派生类型将继承新方法,
您开始使用一种有效的类型,并且用户的源代码甚至不需要重新编译。
向接口添加新成员会强制接口的继承者发生更改
其源代码并重新编译。

Copied from CLR via C# by Jeffrey Richter...

I often hear the question, “Should I design a base type or an interface?” The answer isn’t always clearcut.

Here are some guidelines that might help you:

■■ IS-A vs. CAN-DO relationship A type can inherit only one implementation. If the derived
type can’t claim an IS-A relationship with the base type, don’t use a base type; use an interface.
Interfaces imply a CAN-DO relationship. If the CAN-DO functionality appears to belong
with various object types, use an interface. For example, a type can convert instances of itself
to another type (IConvertible), a type can serialize an instance of itself (ISerializable),
etc. Note that value types must be derived from System.ValueType, and therefore, they cannot
be derived from an arbitrary base class. In this case, you must use a CAN-DO relationship
and define an interface.

■■ Ease of use It’s generally easier for you as a developer to define a new type derived from a
base type than to implement all of the methods of an interface. The base type can provide a
lot of functionality, so the derived type probably needs only relatively small modifications to its behavior. If you supply an interface, the new type must implement all of the members.

■■ Consistent implementation No matter how well an interface contract is documented, it’s
very unlikely that everyone will implement the contract 100 percent correctly. In fact, COM
suffers from this very problem, which is why some COM objects work correctly only with
Microsoft
Word or with Windows Internet Explorer. By providing a base type with a good
default implementation, you start off using a type that works and is well tested; you can then
modify parts that need modification.

■■ Versioning If you add a method to the base type, the derived type inherits the new method,
you start off using a type that works, and the user’s source code doesn’t even have to be recompiled.
Adding a new member to an interface forces the inheritor of the interface to change
its source code and recompile.

我的痛♀有谁懂 2024-07-24 10:21:25

接口定义一个服务或一组服务的契约。 它们以水平方式提供多态性,两个完全不相关的类可以实现相同的接口,但可以互换地用作它们实现的接口类型的参数,因为这两个类都承诺满足接口定义的服务集。 接口不提供实现细节。

抽象类定义其子类的基本结构,以及可选的部分实现。 抽象类以垂直但有方向的方式提供多态性,因为任何继承抽象类的类都可以被视为该抽象类的实例,但反之则不然。 抽象类通常可以包含实现细节,但不能自行实例化 - 只有它们的子类可以“更新”。

请注意,C# 也允许接口继承。

An interface defines a contract for a service or set of services. They provide polymorphism in a horizontal manner in that two completely unrelated classes can implement the same interface but be used interchangeably as a parameter of the type of interface they implement, as both classes have promised to satisfy the set of services defined by the interface. Interfaces provide no implementation details.

An abstract class defines a base structure for its sublcasses, and optionally partial implementation. Abstract classes provide polymorphism in a vertical, but directional manner, in that any class that inherits the abstract class can be treated as an instance of that abstract class but not the other way around. Abstract classes can and often do contain implementation details, but cannot be instantiated on their own- only their subclasses can be "newed up".

C# does allow for interface inheritance as well, mind you.

寂寞笑我太脆弱 2024-07-24 10:21:25

接口是强制执行特定行为的轻量级方法。 这是一种思考方式。

Interfaces are light weight way to enforce a particular behavior. That is one way to think of.

戴着白色围巾的女孩 2024-07-24 10:21:25

大多数答案都集中在抽象类和接口之间的技术差异,但由于从技术上讲,接口基本上是一种抽象类(没有任何数据或实现),我认为概念< /strong> 差异要有趣得多,这可能就是面试官所追求的。

接口是一个协议。 它指定:“这就是我们彼此交谈的方式”。 它不能有任何实现,因为它不应该有任何实现。 这是一份合同。 它就像 C 中的 .h 头文件。

抽象类是一个不完整的实现。 类可以实现也可以不实现接口,并且抽象类不必完全实现它。 没有任何实现的抽象类有点无用,但完全合法。

基本上任何类,无论是否抽象,都是关于它是什么的,而接口则是关于你如何使用它的。 例如:Animal可能是一个实现一些基本代谢功能的抽象类,并指定呼吸和运动的抽象方法而不给出实现,因为它不知道是否应该通过鳃或肺呼吸,并且无论它飞、游泳、走还是爬。 另一方面,Mount 可能是一个接口,它指定您可以骑乘动物,而无需知道它是什么类型的动物(或者它是否是动物!)。

事实上,在幕后,接口基本上是一个只有抽象方法的抽象类,这一点并不重要。 从概念上讲,它们扮演着完全不同的角色。

Most answers focus on the technical difference between Abstract Class and Interface, but since technically, an interface is basically a kind of abstract class (one without any data or implementation), I think the conceptual difference is far more interesting, and that might be what the interviewers are after.

An Interface is an agreement. It specifies: "this is how we're going to talk to each other". It can't have any implementation because it's not supposed to have any implementation. It's a contract. It's like the .h header files in C.

An Abstract Class is an incomplete implementation. A class may or may not implement an interface, and an abstract class doesn't have to implement it completely. An abstract class without any implementation is kind of useless, but totally legal.

Basically any class, abstract or not, is about what it is, whereas an interface is about how you use it. For example: Animal might be an abstract class implementing some basic metabolic functions, and specifying abstract methods for breathing and locomotion without giving an implementation, because it has no idea whether it should breathe through gills or lungs, and whether it flies, swims, walks or crawls. Mount, on the other hand, might be an Interface, which specifies that you can ride the animal, without knowing what kind of animal it is (or whether it's an animal at all!).

The fact that behind the scenes, an interface is basically an abstract class with only abstract methods, doesn't matter. Conceptually, they fill totally different roles.

昵称有卵用 2024-07-24 10:21:25

由于您可能已经从专家那里获得了理论知识,因此我不会在这里花太多文字重复所有这些内容,而是让我用一个简单的示例来解释我们可以使用/不能使用 Interface抽象类

假设您正在设计一个应用程序来列出汽车的所有功能。 在各个方面,您都需要共同的继承,因为数字燃油表、空调、座椅调节等一些属性对于所有汽车来说都是通用的。 同样,我们只需要继承某些类,因为制动系统(ABS、EBD)等某些属性仅适用于某些汽车。

下面的类作为所有汽车的基类:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

假设我们为每辆车都有一个单独的类。

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

考虑我们需要一种继承 Verna 和 Cruze 汽车(不适用于 Alto)制动技术的方法。 虽然两者都采用制动技术,但“技术”是不同的。 因此,我们创建一个抽象类,其中的方法将被声明为 Abstract,并且应该在其子类中实现。

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

现在我们尝试继承这个抽象类,并在Verna和Cruze中实现制动系统的类型:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

看到上面两个类中的问题了吗? 它们继承自 C#.Net 不允许的多个类,即使该方法是在子类中实现的。 这时候就需要Interface了。

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

实现如下:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

现在Verna和Cruze可以借助Interface实现自己的制动技术的多重继承。

As you might have got the theoretical knowledge from the experts, I am not spending much words in repeating all those here, rather let me explain with a simple example where we can use/cannot use Interface and Abstract class.

Consider you are designing an application to list all the features of Cars. In various points you need inheritance in common, as some of the properties like DigitalFuelMeter, Air Conditioning, Seat adjustment, etc are common for all the cars. Likewise, we need inheritance for some classes only as some of the properties like the Braking system (ABS,EBD) are applicable only for some cars.

The below class acts as a base class for all the cars:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

Consider we have a separate class for each Cars.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

Consider we need a method for inheriting the Braking technology for the cars Verna and Cruze (not applicable for Alto). Though both uses braking technology, the "technology" is different. So we are creating an abstract class in which the method will be declared as Abstract and it should be implemented in its child classes.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

Now we are trying to inherit from this abstract class and the type of braking system is implemented in Verna and Cruze:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

See the problem in the above two classes? They inherit from multiple classes which C#.Net doesn't allow even though the method is implemented in the children. Here it comes the need of Interface.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

And the implementation is given below:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

Now Verna and Cruze can achieve multiple inheritance with its own kind of braking technologies with the help of Interface.

雨后咖啡店 2024-07-24 10:21:25

1)接口可以看成是一个纯抽象类,是一样的,但尽管如此,实现接口和继承抽象类还是不一样的。 当您从这个纯抽象类继承时,您正在定义一个层次结构 -> 继承,如果你实现了你不是的接口,你可以实现任意多个接口,但你只能继承一个类。

2) 您可以在接口中定义属性,因此实现该接口的类必须具有该属性。

例如:

  public interface IVariable
  {
      string name {get; set;}
  }

实现该接口的类必须具有这样的属性。

1) An interface can be seen as a pure Abstract Class, is the same, but despite this, is not the same to implement an interface and inheriting from an abstract class. When you inherit from this pure abstract class you are defining a hierarchy -> inheritance, if you implement the interface you are not, and you can implement as many interfaces as you want, but you can only inherit from one class.

2) You can define a property in an interface, so the class that implements that interface must have that property.

For example:

  public interface IVariable
  {
      string name {get; set;}
  }

The class that implements that interface must have a property like that.

明月夜 2024-07-24 10:21:25

虽然这个问题已经很老了,但我想添加另一点支持接口:

接口可以使用任何依赖注入工具来注入,而抽象类注入很少得到支持。

Though this question is quite old, I would like to add one other point in favor of interfaces:

Interfaces can be injected using any Dependency Injection tools where as Abstract class injection supported by very few.

海拔太高太耀眼 2024-07-24 10:21:25

来自我的另一个答案,主要涉及何时使用其中一种:

根据我的经验,界面是最好的
当您有多个课程时使用
每个人都需要响应相同的
方法或方法,以便它们可以
与其他代码互换使用
这将针对那些写
类的公共接口。 最好的
使用接口是当
协议很重要,但
底层逻辑可能不同
每堂课。 如果你不这样的话
重复逻辑,考虑抽象
类或标准类继承
相反。

From another answer of mine, mostly dealing with when to use one versus the other:

In my experience, interfaces are best
used when you have several classes
which each need to respond to the same
method or methods so that they can be
used interchangeably by other code
which will be written against those
classes' common interface. The best
use of an interface is when the
protocol is important but the
underlying logic may be different for
each class. If you would otherwise be
duplicating logic, consider abstract
classes or standard class inheritance
instead.

匿名的好友 2024-07-24 10:21:25

接口类型与抽象基类

改编自Pro C# 5.0 和 .NET 4.5 Framework< /a> 书。

接口类型可能看起来与抽象基类非常相似。 记起
当一个类被标记为抽象时,它可以定义任意数量的抽象成员来提供
所有派生类型的多态接口。 然而,即使一个类确实定义了一组抽象
成员,也可以自由定义任意数量的构造函数、字段数据、非抽象成员(带有
实施)等。 另一方面,接口仅包含抽象成员定义。
由抽象父类建立的多态接口有一个主要限制
因为只有派生类型支持抽象父类定义的成员。 然而,在较大的
在软件系统中,开发没有共同父级的多个类层次结构是很常见的
超越 System.Object。 鉴于抽象基类中的抽象成员仅适用于派生类
类型,我们没有办法在不同的层次结构中配置类型来支持相同的多态
界面。 举例来说,假设您定义了以下抽象类:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

根据此定义,只有扩展 CloneableType 的成员才能支持 Clone()
方法。 如果您创建一组不扩展此基类的新类,则无法获得此
多态接口。 另外,您可能还记得 C# 不支持类的多重继承。
因此,如果您想创建一个既是 Car 又是 CloneableType 的 MiniVan,您将无法这样做:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

正如您所猜测的,接口类型可以解决问题。 定义好接口后,可以
可以由任何类或结构、任何层次结构、任何命名空间或任何程序集中实现
(用任何 .NET 编程语言编写)。 正如您所看到的,接口是高度多态的。
考虑名为 ICloneable 的标准 .NET 接口,它在 System 命名空间中定义。 这
接口定义了一个名为 Clone() 的方法:

public interface ICloneable
{
object Clone();
}

Interface Types vs. Abstract Base Classes

Adapted from the Pro C# 5.0 and the .NET 4.5 Framework book.

The interface type might seem very similar to an abstract base class. Recall
that when a class is marked as abstract, it may define any number of abstract members to provide a
polymorphic interface to all derived types. However, even when a class does define a set of abstract
members, it is also free to define any number of constructors, field data, nonabstract members (with
implementation), and so on. Interfaces, on the other hand, contain only abstract member definitions.
The polymorphic interface established by an abstract parent class suffers from one major limitation
in that only derived types support the members defined by the abstract parent. However, in larger
software systems, it is very common to develop multiple class hierarchies that have no common parent
beyond System.Object. Given that abstract members in an abstract base class apply only to derived
types, we have no way to configure types in different hierarchies to support the same polymorphic
interface. By way of example, assume you have defined the following abstract class:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Given this definition, only members that extend CloneableType are able to support the Clone()
method. If you create a new set of classes that do not extend this base class, you can’t gain this
polymorphic interface. Also, you might recall that C# does not support multiple inheritance for classes.
Therefore, if you wanted to create a MiniVan that is-a Car and is-a CloneableType, you are unable to do so:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

As you would guess, interface types come to the rescue. After an interface has been defined, it can
be implemented by any class or structure, in any hierarchy, within any namespace or any assembly
(written in any .NET programming language). As you can see, interfaces are highly polymorphic.
Consider the standard .NET interface named ICloneable, defined in the System namespace. This
interface defines a single method named Clone():

public interface ICloneable
{
object Clone();
}
苏佲洛 2024-07-24 10:21:25

第二个问题的答案:interface中定义的public变量默认是static final,而public变量在< code>abstract 类是一个实例变量。

Answer to the second question : public variable defined in interface is static final by default while the public variable in abstract class is an instance variable.

剪不断理还乱 2024-07-24 10:21:25

从编码的角度来看,

如果抽象类仅具有抽象方法,则接口可以替换抽象类。 否则,将抽象类更改为接口意味着您将失去继承提供的代码可重用性。

从设计角度

来看,如果它是“是”关系并且您需要部分或全部功能,请将其保留为抽象类。 如果它是“应该做”的关系,则将其保留为接口。

决定您需要什么:只是策略执行,还是代码可重用性和策略。

From Coding Perspective

An Interface can replace an Abstract Class if the Abstract Class has only abstract methods. Otherwise changing Abstract class to interface means that you will be losing out on code re-usability which Inheritance provides.

From Design Perspective

Keep it as an Abstract Class if it's an "Is a" relationship and you need a subset or all of the functionality. Keep it as Interface if it's a "Should Do" relationship.

Decide what you need: just the policy enforcement, or code re-usability AND policy.

梦毁影碎の 2024-07-24 10:21:25

当然,理解 OOP 中接口和抽象类的行为(以及语言如何处理它们)很重要,但我认为理解每个术语的确切含义也很重要。 您能想象 if 命令并不完全按照该术语的含义工作吗? 另外,实际上有些语言正在减少甚至更多地减少接口和抽象之间的差异......如果有一天这两个术语的操作几乎相同,至少你可以定义自己应该在哪里(以及为什么)它们中的任何一个用于。

如果您阅读一些词典和其他字体,您可能会发现同一术语有不同的含义,但有一些共同的定义。 我认为我在这个网站中找到的这两个含义真的非常好而且合适。

界面:

使独立且有时不兼容的元素能够有效协调的事物或情况。

抽象的:

某种东西集中了任何更广泛或更普遍的事物或几个事物的本质品质; 本质。

示例:

您买了一辆汽车,它需要燃料。

输入图片此处描述

您的汽车模型是 XYZ,属于 ABC 流派,因此它是一辆具体汽车,是汽车的特定实例。 汽车不是真实的物体。 事实上,它是创建特定对象的一组抽象标准(质量)。 简而言之,Car 是一个抽象类,它是“集中了更广泛或更一般事物的基本品质的东西”

应使用唯一符合汽车手册规格的燃油来填充汽车油箱。 实际上,没有什么限制您添加任何燃油,但发动机只有使用指定的燃油才能正常工作,因此最好遵循其要求。 这些要求表明,与其他同类型ABC汽车一样,它接受一套标准燃料。

在面向对象的视图中,类型 ABC 的燃料不应声明为类,因为没有针对特定类型汽车的具体燃料。 尽管您的汽车可以接受抽象类 Fuel 或 VehillaryFuel,但您必须记住,只有部分现有的车辆燃料符合规范,即那些实现汽车手册中要求的燃料。 简而言之,他们应该实现接口 ABCGenreFuel,该“...使单独且有时不兼容的元素能够有效地协调”

附录

此外,我认为您应该记住术语“类”的含义,即(来自前面提到的同一站点):

类:

由于共同的属性、特征、品质或特征而被视为形成一个群体的许多人或事物; 种类;

这样,类(或抽象类)不应仅表示公共属性(如接口),而应表示某种具有公共属性的组。 接口不需要代表一种。 它必须代表共同属性。 这样,我认为类和抽象类可以用来表示不应该经常改变其方面的事物,比如人类和哺乳动物,因为它代表了某些种类。 物种不应该那么频繁地改变自己。

For sure it is important to understand the behavior of interface and abstract class in OOP (and how languages handle them), but I think it is also important to understand what exactly each term means. Can you imagine the if command not working exactly as the meaning of the term? Also, actually some languages are reducing, even more, the differences between an interface and an abstract... if by chance one day the two terms operate almost identically, at least you can define yourself where (and why) should any of them be used for.

If you read through some dictionaries and other fonts you may find different meanings for the same term but having some common definitions. I think these two meanings I found in this site are really, really good and suitable.

Interface:

A thing or circumstance that enables separate and sometimes incompatible elements to coordinate effectively.

Abstract:

Something that concentrates in itself the essential qualities of anything more extensive or more general, or of several things; essence.

Example:

You bought a car and it needs fuel.

enter image description here

Your car model is XYZ, which is of genre ABC, so it is a concrete car, a specific instance of a car. A car is not a real object. In fact, it is an abstract set of standards (qualities) to create a specific object. In short, Car is an abstract class, it is "something that concentrates in itself the essential qualities of anything more extensive or more general".

The only fuel that matches the car manual specification should be used to fill up the car tank. In reality, there is nothing to restrict you to put any fuel but the engine will work properly only with the specified fuel, so it is better to follow its requirements. The requirements say that it accepts, as other cars of the same genre ABC, a standard set of fuel.

In an Object Oriented view, fuel for genre ABC should not be declared as a class because there is no concrete fuel for a specific genre of car out there. Although your car could accept an abstract class Fuel or VehicularFuel, you must remember that your only some of the existing vehicular fuel meet the specification, those that implement the requirements in your car manual. In short, they should implement the interface ABCGenreFuel, which "... enables separate and sometimes incompatible elements to coordinate effectively".

Addendum

In addition, I think you should keep in mind the meaning of the term class, which is (from the same site previously mentioned):

Class:

A number of persons or things regarded as forming a group by reason of common attributes, characteristics, qualities, or traits; kind;

This way, a class (or abstract class) should not represent only common attributes (like an interface), but some kind of group with common attributes. An interface doesn't need to represent a kind. It must represent common attributes. This way, I think classes and abstract classes may be used to represent things that should not change its aspects often, like a human being a Mammal, because it represents some kinds. Kinds should not change themselves that often.

放我走吧 2024-07-24 10:21:25

其他几个区别:

抽象类可以有静态方法、属性、字段等,而运算符、接口则不能。
强制转换运算符允许与抽象类进行强制转换,但不允许与接口强制转换。

因此,即使抽象类从未实现(通过其静态成员),您也可以单独使用抽象类,并且您不能以任何方式单独使用接口。

Couple of other differences:

Abstract classes can have static methods, properties, fields etc. and operators, interfaces can't.
Cast operator allows casting to/from abstract class but don't allow casting to/from interface.

So pretty much you can use abstract class on its own even if it is never implemented (through its static members) and you can't use interface on its own in any way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文