An abstract class is a class that is
only partially implemented by the
programmer. It may contain one or more
abstract methods. An abstract method
is simply a function definition that
serves to tell the programmer that the
method must be implemented in a child
class.
An interface is similar to an abstract
class; indeed interfaces occupy the
same namespace as classes and abstract
classes. For that reason, you cannot
define an interface with the same name
as a class. An interface is a fully
abstract class; none of its methods
are implemented and instead of a class
sub-classing from it, it is said to
implement that interface.
// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();
int getFuel();
}
// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{
int fuel;
void run()
{
print("Wrroooooooom");
}
int getFuel()
{
return this.fuel;
}
}
// I say all motor vehicles should look like this:
abstract class MotorVehicle
{
int fuel;
// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}
// That can be very different, force them to provide their
// own implementation.
abstract void run();
}
// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}
根据定义,接口不能具有任何方法的实现,并且无法初始化成员变量。
但是,抽象类可以实现方法并初始化成员变量。
当您期望合同发生变化时,请使用抽象类,即,将来您可能需要添加新方法。
在这种情况下,如果您决定使用接口,当接口更改为包含接口时,您的应用程序将在您转储新接口DLL时中断。
要详细阅读,请访问difference between abstract class and a interface
1.Main difference is methods of a Java interface are implicitly abstract and cannot have implementations. A Java abstract class can
have instance methods that implements a default behavior.
2.Variables declared in a Java interface is by default final. An abstract class may contain non-final variables.
3.Members of a Java interface are public by default. A Java abstract class can have the usual flavors of class members like private,
protected, etc..
4.Java interface should be implemented using keyword “implements”; A Java abstract class should be extended using keyword “extends”.
5.An interface can extend another Java interface only, an abstract class can extend another Java class and implement multiple Java
interfaces.
6.A Java class can implement multiple interfaces but it can extend only one abstract class.
7.Interface is absolutely abstract and cannot be instantiated; A Java abstract class also cannot be instantiated, but can be invoked if a
main() exists.
8.In comparison with java abstract classes, java interfaces are slow as it requires extra indirection.
不是原始问题的答案,但是一旦你得到它们之间的差异的答案,你将进入使用时 - 每个困境:
When to use interfaces or abstract classes? When to use both?
我对OOP的知识有限,但是看到界面作为语法形容词的等价物直到现在都适用于我(如果这种方法是假的,请纠正我!)。例如,接口名称就像您可以为类提供的属性或功能,并且类可以包含许多类:ISerializable,ICountable,IList,ICacheable,IHappy,...
abstract class animals
{
// They all love to eat. So let's implement them for everybody
void eat()
{
System.out.println("Eating...");
}
// The make different sounds. They will provide their own implementation.
abstract void sound();
}
class dog extends animals
{
void sound()
{
System.out.println("Woof Woof");
}
}
class cat extends animals
{
void sound()
{
System.out.println("Meoww");
}
}
以下是Java中的接口实现:
interface Shape
{
void display();
double area();
}
class Rectangle implements Shape
{
int length, width;
Rectangle(int length, int width)
{
this.length = length;
this.width = width;
}
@Override
public void display()
{
System.out.println("****\n* *\n* *\n****");
}
@Override
public double area()
{
return (double)(length*width);
}
}
class Circle implements Shape
{
double pi = 3.14;
int radius;
Circle(int radius)
{
this.radius = radius;
}
@Override
public void display()
{
System.out.println("O"); // :P
}
@Override
public double area()
{
return (double)((pi*radius*radius)/2);
}
}
public abstract class DesireCar
{
//It is an abstract method that defines the prototype.
public abstract void Color();
// It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.
// and hence no need to define this in all the sub classes in this way it saves the code duplicasy
public void Wheel() {
Console.WriteLine("Car has four wheel");
}
}
**Here is the sub classes:**
public class DesireCar1 : DesireCar
{
public override void Color()
{
Console.WriteLine("This is a red color Desire car");
}
}
public class DesireCar2 : DesireCar
{
public override void Color()
{
Console.WriteLine("This is a red white Desire car");
}
}
接口示例:
public interface IShape
{
// Defines the prototype(template)
void Draw();
}
// All the sub classes follow the same template but implementation can be different.
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("This is a Circle");
}
}
public class Rectangle : IShape
{
public void Draw()
{
Console.WriteLine("This is a Rectangle");
}
}
class Box implements Package, Property {
@Override
String address() {
return "5th Street, New York, NY";
}
@Override
Human owner() {
// this method is part of another contract
}
}
abstract class GpsBox implements Package {
@Override
public abstract String address();
protected Coordinates whereAmI() {
// connect to GPS and return my current position
}
}
class Circle {
protected $radius;
public function __construct($radius)
{
$this->radius = $radius
}
public function area()
{
return 3.14159 * pow(2,$this->radius); // simply pie.r2 (square);
}
}
//Our area calculator class would look like
class Areacalculator {
$protected $circle;
public function __construct(Circle $circle)
{
$this->circle = $circle;
}
public function areaCalculate()
{
return $circle->area(); //returns the circle area now
}
}
我们会这样做
$areacalculator = new Areacalculator(new Circle(7));
Interface Shape {
public function area(); //Defining contract for the classes
}
Class Square implements Shape {
$protected length;
public function __construct($length) {
//settter for length like we did on circle class
}
public function area()
{
//return l square for area of square
}
Class Rectangle implements Shape {
$protected length;
$protected breath;
public function __construct($length,$breath) {
//settter for length, breath like we did on circle,square class
}
public function area()
{
//return l*b for area of rectangle
}
}
现在为区域计算器
class Areacalculator {
$protected $shape;
public function __construct(Shape $shape)
{
$this->shape = $shape;
}
public function areaCalculate()
{
return $shape->area(); //returns the circle area now
}
}
$areacalculator = new Areacalculator(new Square(1));
$areacalculator->areaCalculate();
$areacalculator = new Areacalculator(new Rectangle(1,2));
$areacalculator->;areaCalculate();
Abstract Animal {
public function breathe(){
//all animals breathe inhaling o2 and exhaling co2
}
public function hungry() {
//every animals do feel hungry
}
abstract function communicate();
// different communication style some bark, some meow, human talks etc
}
33 个回复
hquae
赞同来自:
内容太长未翻译
yeum
赞同来自:
接口仅包含功能的定义/签名,如果我们有一些共同的功能以及常见的签名,那么我们需要使用抽象类。通过使用抽象类,我们可以同时提供行为和功能。继承抽象类的另一个开发人员可以轻松使用此功能,因为他们只需填写空白。
xqui
赞同来自:
可在此处找到解释:http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm
无论如何,我发现接口的这种解释有点令人困惑。更常见的定义是:接口定义实现类必须满足的合同。接口定义由公共成员的签名组成,没有任何实现代码。paut
赞同来自:
总结起来的最简单方法是
interface
是:default
和static
方法之外;虽然它有default
和static
方法的定义(方法签名+实现),但它只有其他方法的声明(方法签名)。interface
s,interface
可以从多个interface
继承)。无论是否指定为public static final
,所有变量都是隐式常量。无论是否指定,所有成员都隐含地为public
。abstract
类是:abstract
方法。可以包含声明和定义,声明标记为abstract
。protected
,private
或私有包(未指定)。interface
就是实现类所具有的,但是abstract
类就是子类。nin
赞同来自:
jalias
赞同来自:
在接口中,所有方法必须只是定义,而不是单个应该实现。 但是在抽象类中必须有一个只有定义的抽象方法,但是其他方法也可以在抽象类中实现...
benim
赞同来自:
接口 H2> 一个接口是一个契约:编写界面的人说:“嘿,我接受看起来那样的东西”,使用界面的人说“好吧,我写的课看起来那样”。 接口是一个空壳。只有方法的签名,这意味着方法没有正文。界面无能为力。这只是一种模式。 例如(伪代码):
实现一个接口消耗很少的CPU,因为它不是一个类,只是一堆名称,因此没有任何昂贵的查找。它很重要,例如在嵌入式设备中。抽象类 h2> 与接口不同,抽象类是类。它们的使用成本更高,因为当你继承它们时会有一个查找。 抽象类看起来很像接口,但它们还有更多东西:您可以为它们定义行为。它更多的是关于一个人说,“这些类应该看起来像那样,并且他们有共同点,所以填补空白!”。 例如:
实施 H2> 虽然抽象类和接口应该是不同的概念,但实现使得该语句有时不真实。有时,它们甚至不是你认为的那样。 在Java中,强制执行此规则,而在PHP中,接口是没有声明方法的抽象类。 在Python中,抽象类更像是一个可以从ABC模块获得的编程技巧,实际上是使用元类,因此也就是类。接口与这种语言中的duck typing更相关,它是约定和调用描述符的特殊方法( __method__ 方法)之间的混合。 与编程一样,有另一种语言的理论,实践和实践:-)
taut
赞同来自:
abstract class和interface之间的主要技术差异是:
public
(默认情况下它们是公共的)。kaut
赞同来自:
没有任何实现的抽象类看起来像一个接口;但是,抽象类和接口之间存在许多差异而不是相似之处。让我们解释这两个概念并比较它们的相似点和不同点。 什么是抽象类? 抽象类是一种无法实例化的特殊类。所以问题是为什么我们需要一个无法实例化的类?抽象类只是被分类(继承自)。换句话说,它只允许其他类继承它但不能实例化。优点是它为所有子类强制执行某些层次结构。简单来说,它是一种强制所有子类进行相同层次结构或标准的契约。 什么是界面? 接口不是类。它是一个由Interface定义的实体。接口没有实现;它只有签名或换言之,只是没有正文的方法的定义。作为与Abstract类相似的一个,它是一个用于定义所有子类的层次结构的契约,或者它定义了特定的方法集及其参数。它们之间的主要区别在于类可以实现多个接口,但只能从一个抽象类继承。由于C#不支持多重继承,因此接口用于实现多重继承。 两者一起 当我们创建一个接口时,我们基本上创建了一组方法,没有任何必须被实现的类重写的实现。它的优点是它为类提供了一种方法,使其成为两个类的一部分:一个来自继承层次结构,另一个来自接口。 当我们创建一个抽象类时,我们创建一个可能有一个或多个已完成方法的基类,但至少有一个或多个方法未完成并声明为抽象。如果抽象类的所有方法都未完成,那么它与接口相同。抽象类的目的是为一组派生类如何工作提供基类定义,然后允许程序员填充派生类中的实现。
接口和抽象类之间存在一些相似之处和不同之处。
ksequi
赞同来自:
根据定义,接口不能具有任何方法的实现,并且无法初始化成员变量。 但是,抽象类可以实现方法并初始化成员变量。 当您期望合同发生变化时,请使用抽象类,即,将来您可能需要添加新方法。 在这种情况下,如果您决定使用接口,当接口更改为包含接口时,您的应用程序将在您转储新接口DLL时中断。 要详细阅读,请访问difference between abstract class and a interface
icum
赞同来自:
一些重要的差异: 以表格的形式:
lnon
赞同来自:
不是原始问题的答案,但是一旦你得到它们之间的差异的答案,你将进入使用时 - 每个困境: When to use interfaces or abstract classes? When to use both? 我对OOP的知识有限,但是看到界面作为语法形容词的等价物直到现在都适用于我(如果这种方法是假的,请纠正我!)。例如,接口名称就像您可以为类提供的属性或功能,并且类可以包含许多类:ISerializable,ICountable,IList,ICacheable,IHappy,...
dquis
赞同来自:
如果要在继承层次结构中提供多态行为,请使用抽象类。 当您想要完全不相关的类的多态行为时,请使用接口。
qea
赞同来自:
如果您有一些可供多个类使用的常用方法,请转到抽象类。 否则,如果您希望类遵循一些明确的蓝图,请转到接口。 以下示例证明了这一点 Java中的抽象类:
以下是Java中的接口实现: 简而言之,一些重要的关键点:ueum
赞同来自:
实际上它非常简单。 您可以将接口视为一个类,只允许使用抽象方法而不允许其他方法。 因此,接口只能“声明”而不能定义您希望该类具有的行为。 抽象类允许您同时执行声明(使用抽象方法)以及定义(使用完整方法实现)您希望类具有的行为。 普通类只允许您定义,而不是声明您希望类具有的行为/操作。 最后一件事, 在Java中,您可以实现多个接口,但是您只能扩展一个(抽象类或类)... 这意味着定义行为的继承被限制为只允许每个类一个...即,如果你想要一个封装了A,B和C类行为的类,你需要执行以下操作:A类扩展B,C类扩展A ..它有点关于多重继承的方式... 另一方面,接口可以简单地做:接口C实现A,B 所以实际上Java只在“声明的行为”即接口中支持多重继承,并且只支持具有已定义行为的单继承..除非你按照我描述的方式进行循环... 希望这是有道理的。
gest
赞同来自:
唯一的区别是,一个人可以参与多重继承,而其他人则不能。 接口的定义随着时间的推移而发生了变化。你认为一个接口只有方法声明而且只是合同吗?那么静态最终变量以及Java 8之后的默认定义呢? 接口被引入Java,因为the diamond problem具有多重继承,这就是他们实际打算做的事情。 接口是为了避免多重继承问题而创建的构造,可以包含抽象方法,默认定义和静态最终变量。 请参阅Why does Java allow static final variables in interfaces when they are only intended to be contracts?。
met
赞同来自:
我想补充一点其他有意义的差异。 例如,您有一个包含数千行代码的框架。现在,如果要使用方法enhanceUI()在整个代码中添加新功能,那么最好在抽象类中添加该方法,而不是在接口中添加。因为,如果在接口中添加此方法,则应在所有实现的类中实现它,但如果在抽象类中添加该方法则不是这种情况。
ut_quo
赞同来自:
抽象类和接口之间的差异代表真正的实现。 接口:它是一个关键字,用于定义对象的模板或蓝图,它强制所有子类都遵循相同的原型,对于实现,所有子类都可以自由地实现功能。这是要求。 我们应该使用接口的一些其他用例。 通过Interface here接口完成两个外部对象之间的通信(在我们的应用程序中进行第三方集成)作为Contract。 抽象类:抽象,它是一个关键字,当我们在任何类之前使用这个关键字然后它变成抽象类。它主要用于我们需要定义模板以及一个对象的一些默认功能,后面跟着所有子类和这种方式它删除了冗余代码和一个我们可以使用抽象类的用例,比如我们希望没有其他类可以直接实例化类的对象,只有派生类才能使用该功能。 抽象类的示例:
接口示例:jquia
赞同来自:
重点是:
qanimi
赞同来自:
我正在建造一个300层的建筑 建筑的蓝图界面
eos_et
赞同来自:
我不想强调差异,这些差异已在许多答案中说过(关于接口中变量的公共静态最终修饰符,以及对抽象类中受保护的私有方法的支持) 简单来说,我想说: interface:通过多个不相关的对象实现合同 抽象类:在多个相关对象之间实现相同或不同的行为 来自Oracle documentation 考虑使用抽象类,如果:
Serializable
接口。Java
作为编程语言,这里还有一些更新: Java 8通过提供default
方法功能在一定程度上缩小了interface
和abstract
类之间的差距。接口没有方法的实现现在不再有效。 有关更多详细信息,请参阅此文档page。 看看这个SE问题,以便更好地理解代码示例。 How should I have explained the difference between an Interface and an Abstract class?gnihil
赞同来自:
抽象类是无法创建其对象的类或无法实例化的类。 抽象方法使类抽象。 需要继承抽象类以覆盖抽象类中声明的方法。 访问说明符没有限制。 抽象类可以有构造函数和其他具体(非abstarct方法)方法,但接口不能有。 界面是方法的蓝图/模板。(例如,纸上的房子被给出(界面房屋),不同的建筑师将使用他们的想法来构建它(实现房屋界面的建筑师类)。 它是抽象方法,默认方法,静态方法,最终变量和嵌套类的集合。 所有成员都将是最终成员或公共成员,不允许使用受保护和私有访问说明符。不允许创建对象。 必须创建一个类才能使用实现接口,并且还要覆盖接口中声明的抽象方法。接口是松耦合的一个很好的例子(动态多态/动态绑定) 接口实现了多态性和抽象。它告诉我们该做什么但是如何做是由实现类定义的。 对于Eg。有一个汽车公司,它希望这样一些功能是相同的所有它是制造所以,该公司将形成交界面的车辆将有那些特点和不同类别的汽车(如马鲁蒂Suzkhi,马鲁蒂800)的车会覆盖这些功能(功能)。 为什么我们已经有抽象类的接口? Java仅支持多级和层级继承,但在接口的帮助下,我们可以实现多重继承。
killo
赞同来自:
接口和抽象类之间有什么区别?
uet
赞同来自:
界面:转动(向左转,向右转。) 抽象类:轮子。 类别:方向盘,源自轮子,暴露界面转向 一个用于对可以在各种事物中提供的行为进行分类,另一个用于对事物的本体建模。
yut
赞同来自:
简而言之,差异如下: 接口和抽象类之间的语法差异:
public static
- 支持的public abstract
- 支持的public default
- 支持的private static
- 支持的private abstract
- 编译错误private default
- 编译错误private
- 支持esaepe
赞同来自:
您可以在界面和抽象类之间找到明显的区别。 接口
dmodi
赞同来自:
让我们再次讨论这个问题: 让你知道的第一件事是1/1和1 * 1会产生相同的结果,但这并不意味着乘法和除法是相同的。显然,他们保持着良好的关系,但请注意,两者都是不同的。 我将指出主要的不同之处,其余的已经解释过了: 抽象类对于类层次结构的建模很有用。乍一看任何要求,我们都清楚地知道要构建什么,但我们知道要构建什么。所以你的抽象类是你的基类。 接口对于让其他层次结构或类知道我能够做什么很有用。当你说我有能力时,你必须具备这种能力。接口将标记为类必须实现相同的功能。
iaut
赞同来自:
可以在Interface VS Abstract Class in PHP中找到解释。
结论 H3> 抽象类用于共享函数。接口用于分享您必须执行的操作。
bea
赞同来自:
继承用于两个目的:
uautem
赞同来自:
关键点:
nautem
赞同来自:
为了给出一个简单但明确的答案,有助于设置上下文:当您不想提供完整实现时,可以使用两者。 那么主要的区别是接口根本没有实现(只有没有主体的方法),而抽象类也可以有成员和方法,也可以部分实现。
csequi
赞同来自:
接口与抽象类的比较是错误的。应该有另外两个比较:1)接口与类和2)抽象与最终类。
接口与类 h1> 接口是两个对象之间的契约。例如,我是邮递员,你是一个提供的套餐。我希望你知道你的送货地址。当有人给我一个包裹时,它必须知道它的送货地址:
类是一组遵守合同的对象。例如,我是“Box”组的一个盒子,我遵守邮递员要求的合同。同时我遵守其他合同:摘要与最终 h1> 抽象类是一组不完整的对象。他们不能使用,因为他们错过了一些部分。例如,我是一个抽象的GPS感知框 - 我知道如何检查我在地图上的位置:
如果由另一个类继承/扩展,该类可能非常有用。但它本身 - 它没用,因为它不能有物体。抽象类可以构建最终类的元素。 最终类是一组完整的对象,可以使用,但不能修改。他们确切知道如何工作和做什么。例如,我是一个总是进入其构造期间指定地址的Box: 在大多数语言中,如Java或C++,可能只有一个类,既不是抽象的也不是最终的。这样的类可以继承并可以实例化。但我并不认为这严格符合面向对象的范式。 同样,将接口与抽象类进行比较是不正确的。uanimi
赞同来自:
接口通常是没有逻辑的类,只是一个签名。抽象类是具有逻辑的类。支持契约作为接口所有方法都应该在子类中实现,但是在抽象中只应该实现抽象方法。何时使用界面以及何时抽象?为何使用Interface?
我们会这样做 几天后我们需要矩形,正方形,四边形等区域。如果是这样,我们每次都要更改代码并检查实例是方形还是圆形或矩形?现在OCP所说的是代码接口而不是实现。 解决方案是: 现在为区域计算器 这不是更灵活吗?如果我们在没有接口的情况下编码,我们将检查每个形状冗余代码的实例。 现在何时使用抽象? 现在,当一个人不需要那个类的实例,具有类似的逻辑,需要合同时,应该使用abstract。