我似乎不太理解两个OOP概念。您能解释一下抽象和多态是什么,最好附带实际示例和代码吗?
谢谢。
我似乎不太理解两个OOP概念。您能解释一下抽象和多态是什么,最好附带实际示例和代码吗?
谢谢。
想象一个分数类:
class fraction:
int denominator
int numerator
现在是关于两个物体的:
fraction(obj1): denominator=-1 numerator=-1
fraction(obj2): denominator=1 numerator=1
两个对象的值都为1:(1/1) == (-1)/(-1)
。你不会期望它们在外部有任何不同的行为。这就是抽象。你将对象所持有的数据抽象成逻辑视图,即使在幕后有其他的东西。从理论上讲,你有一个等价关系,有不同的等价组:
[1]=(1, 1), (-1, -1), (5, 5), ...
[2]=(2, 4), (-2, -4), ...
...
有一个抽象化函数将内部细节抽象出来展现给外部:
f((1, 1)) = [1]
f((-1, -1)) = [1]
它将具体的值映射到对象的抽象值上。您可以通过编写构造函数的映射(-1,-1)到(1,1)和编写类的equals函数来实现。
想象一个笔和两个派生类:
class pen:
void draw(int x, int y)
class pen_thin extends pen:
void draw(int x, int y) { color(x, y) = green; }
class pen_thick extends pen:
void draw(int x, int y) { color(x, y) = green;
color(x, y+1) = green; }
and two objects:
pen_thin(p1)
pen_thick(p2)
两支笔都可以画图。普通的“笔”本身不能画图,它只是笔尖、笔粗和很多其他笔的接口。你说:obj1.draw(1, 0); 无论obj1是粗笔还是细笔,对于用户和编译器来说都没有影响。这个调用表现为多态。这是 动态多态性(发生在运行时),这通常是人们所说的。 静态多态性 是发生在编译时的:
class colorizer:
void colorize(shirt s)
void colorize(pants p)
这被称为重载。您调用obj.colorize(something)
。如果您使用衬衣引用调用它,则将调用接受衬衣的版本。如果您使用裤子引用调用它,则将调用裤子版本。在这里做出的选择是在编译时。
抽象和多态性是关键概念,绝不仅限于面向对象。增加混淆的是,“抽象”这个词被用多种方式。这里有一个快速参考指南,附有一个例子:
数据抽象意味着信息隐藏。通常,隐藏的是数据结构的表示。例如:我实现了集合,但我不告诉你一个集合是作为列表、平衡二叉树还是非平衡二叉树表示的。如果做得对,我可以改变表示方式而不破坏你的代码。
多态性意味着不同类型的重用。因此,使用我的集合示例,您可以创建使用相同代码的社保号码集合、全名集合或果蝠集合。
显然,您可以定义一个既是抽象的又是多态的类。
多态性进一步让人困惑,因为有两种实现多态性的方法。在参数化多态性中,您可以重用带有任何类型或可能满足某些约束的值的集合。最明显的示例是C ++模板;如果您编写
class Set <T> { ... }
然后T
是集合中包含的对象的类型(记法<T>
表示所谓的“类型参数”,这使它成为参数多态性)。
在<强>子类型多态强>中,你只能重复使用对象类型为某个特定类型的子类型的集合。例如,您可能只能创建提供小于或等于方法的对象集合。在真正的面向对象语言中,例如Smalltalk或Ruby,它们提供所谓的<强>鸭子类型强>(我们这些理论家有时称其为行为子类型化),方法的存在已经足够了。在Java或C ++等语言中,将子类型化与继承混淆,您的多态使用可能<强>仅限于特定类的子类。(Java通过在类上使用一种形式的子类型和在接口上使用另一种形式进一步混淆了这个问题。)
最后,像我这样的老家伙讨论”过程抽象”,它只是指能够将经常一起使用的一堆语句放入一个可以重复使用的过程或方法中。这可能与你的问题无关。
所以,你感觉对于感到困惑更好了吗? (Suo yi, ni gan jue dui yu gan dao kun nao geng hao le ma?)
这两个是面向对象范式中最重要的特征之一。
对象导向将软件建模为现实世界的对象。然而,对于一个顾客可能拥有的所有属性或一个员工可能拥有的所有属性进行建模将是过于困难(并且无用)的。
通过仅列出对象的有趣属性,OO可以成功地将该对象用于特定的域。那就是抽象。
例如,在人力资源系统中的员工可能具有与在线书店非常不同的属性。我们抽象细节以使其有用。
对象的行为可能因“类型”而异,同时保持相同的接口。
这是什么意思?
例如,一个在线商店系统可能有两个雇员的子类
A) 內部員工。
B) 承包商
一种计算内部购买折扣的方法
内部员工的折扣计算方式为:10% + 在公司工作的每一年额外增加2% + 每个子女额外增加2%。
承包商的折扣为10%。
以下代码用于计算应付金额:
public Amount getAmountToPay( Product product, Employee internalCustomer ) {
Amount amount = product.getPrice();
amount.applyDiscount( internalCustomer.getDiscount() );
return amount;
}
两种不同类型员工会产生不同的结果
class Employee {
public int getDiscount();
}
class InternalEmployee extends Employee {
public int getDiscount() {
return 10 + 2 * getWorkedYears() + 2 * getNumberOfChilds();
}
}
class Contractor extends Employee {
public int getDiscount() {
return 10;
}
}
这就是多态的实现。不是像拥有像...的东西,
Amount amount = product.getPrice();
if( employee.isContractor() ) {
amount.applyDiscount( 10 );
} else if( employee.isSomthingElse() ) {
amount.applyDiscount( 10 * 2 * getYrs() + 2 * getChilds() );
} else if ( employee.contidions, condigions, conditions ) {
amount.applyDiscount( getSomeStrageRuleHere() );
}
我们让运行时选择要进行计算的类型。就像程序根据类型的不同表现出不同的行为。
Amount amount = product.getPrice();
amount.applyDiscount( internalCustomer.getDiscount() );
return amount;
顺便说一下,在这个例子中,“金额”是一个真实生活概念的抽象,也可以表示为double或Integer,但也许我们内部有更好的方法,如果设置在自己的类中会更好。
我希望这能帮到你。
抽象化是指在不包含背景细节或解释的情况下表示基本特征的行为。类使用抽象化的概念,并被定义为一组抽象属性。
一种软件抽象的例子是Java的Object.equals(Object o)
方法。你知道它会将此对象与传递的对象参数进行比较,但你不知道,也不需要知道它将如何实现(除非你是该类的实现者)。
多态性指的是具有多种形式的能力。一个方法在不同的实例中可能具有不同的行为。行为取决于操作中使用的数据类型。
多态的经典例子之一使用以Animal类为根的继承树。所有的Animal都有一个makeNoise()方法,但是Dog类和Cat类实现的方式不同。这使您能够使用Animal引用类型引用任何Dog和Cat。
Animal a = new Dog();
Animal b = new Cat();
现在,您可以在任何动物实例上调用makeNoise()
,并知道它会发出适当的噪音。如果您拥有一组动物,并且在运行时不确切知道每个类型,这特别有用。
简短回答:抽象是概念性的,多态是行为性的。
这两个术语在面向对象编程中被广泛使用,但它们并不特定限于那个上下文。
抽象是对其他事物的概括;从更高的角度看待问题。例如,阶层可以被视为公司组织结构的一种抽象。通常在事物的底层使用抽象(如它们的基本类型)。抽象的目的是编写更通用的代码,以便可以运行更广泛的问题,从而写更少的代码。例如,电子表格是一种抽象,它允许特定类型的信息存储。更多?
多态性也是一种泛化,但发生在运行时的情况下。如果存在某种方式可以访问它们且它们彼此无法区分,那么一堆不同的对象类型就具有多态性。也就是说,所有的对象看起来都是一样的,即使它们并不相同。其目的是显著减少代码量;您可以编写一个通用的解决方案,从而避免编写每种不同类型的所有不同排列组合的代码。如果您编写一个图形库,您宁愿编写一些抽象代码来处理形状,而不是编写每种不同类型的代码,例如圆形、正方形等等。
这两个术语都是围绕着代码中的属性来制定的,这将使程序员在使用更少的代码时能够做更多的事情。更少的代码会减少错误,更加稳定并且更易于维护。另一种选择是使用“暴力”来撰写数百万行非常特定(并且非常脆弱)的代码。更多的代码更难修复,并且更难以保持最新。
保罗。
简而言之,抽象是概念性的,多态是行为性的。为了实现面向对象编程中的抽象,你需要多态。
面向对象编程中的抽象是一个概念或设计模式,它可以实现更好的隔离、松散耦合从而提高可测试性、可重用性和可扩展性。为了实现这一切,我们需要多态、继承/扩展等等。
The confusion regarding the actual meaning of abstraction in the context of object orientation is comprehensible: it adds little, if something, to the concepts of inheritance, encapsulation and even polymorphism. If you master these three concepts, there is no need to concern too much with "abstraction" once it is naturally embedded in them (particularly inheritance).
To start with, note that the term "abstraction" has multiple meanings and it is not incorrect to state, e.g., that encapsulation requires abstraction: when you use access modifiers to protect the attributes of a class while exposing the methods that handle them (that s what encapsulation is), the class user no longer needs to worry how to handle them by herself. So, in a sense, when you design a class, you abstract by properly encapsulating methods and attributes - everything the class user needs to do is use it by invoking the right methods, and this is a form of abstraction.
Furthermore, if you think straight, polymorphism is also a form of abstraction: your code calls a method provided by some class and you have no idea how it is gonna act until that actual class type is determined (at runtime). So, it is correct to state that the polymorphic behavior is a kind of abstraction.
However, when used as a standalone term to describe the characteristics of OOP, abstraction must be understood as the proper representation of the system under discussion in the form of a suitable class hierarchy. As such, abstraction is the result of the designer s mental processes that culminate in an appropriate design for the classes that are gonna be used in a program. To quote an (excellent!) post that can be found at the javarevisited blog:
... Abstraction hides details at the design level, while Encapsulation hides details at the implementation level.
While the above statement is correct, I find the "hides details" part misstated - I would rephrase it as something like
Abstraction concerns with design details, deciding how the class hierarchy should look like, Encapsulation hides details implementation.
To be fair with the author, this very idea is put beautifully along his article. The term "abstraction" with this connotation is also seen in good books like Head First Object-Oriented Analysis and Design, and I quote a statement from there:
Whenever you find common behavior in two or more places, look to abstract that behavior into a class, and then reuse that behavior in the common classes
Notice the usage of abstraction here: "look to abstract that behavior into a class". Now, if to abstract means to design a class hierarchy properly as suggested above, abstraction could be defined as the representation of a domain by using classes conveniently, taking advantage of the concepts of inheritance and encapsulation.
In the particular case of Java, abstraction is implemented by using interfaces and abstract classes while encapsulation is implemented with the private, protected and package access modifiers.
Abstraction and Polymorphism are similar in nature with a different purpose.
For ex.
A driving license: you are given a license mentioning the class of vehicles you are allowed to drive. The license mentions the class of vehicle allowed by the authority but it doesn t define or mention which specific car or brand you should drive. This is Abstraction.
here License is an Abstract class and its method, the allowed vehicles is its Abstract method.
Now, here, Polymorphism is different ways individual License is alloted by the authority to different people, some are issued for light vehicles while some for heavy and some are given for commercial vehicles, according to different requirement. Here, License is a base class, and other kinds of licenses are its child classes, also obeying the is-a relationship. Commercial License is a License.
So, Abstraction is a general guideline giving independence of implementation to the follower classes while Polymorphism is differential approach which override the methods/rules set by parent class.
P.S: recently started learning java answer is based on my observation please correct me if i am wrong.
Abstraction and Polymorphism basically deep down does almost same work in programming .
let s Take a car for example..
it doesn t matter whether it is a Ford mini-van, Ferrari exotic, Land-Rover SUV or a BMW sedan they all follow a basic design of a car i.e an engine, a steering wheel , a gear box , lights , indicators and list goes on . what makes them different is their specific implementations like Ferrari might have a more powerful engine than a mini van, a suv might have a different gear box hence A car (Superclass over here) has been implemented by subclasses (sedan, suv , mini-van, exotic) This is polymorphism, a basic idea being inherited or implemented by adding other specification. a 4 wheel vehicle (superclass) being implemented in various forms (subclasses)
Now, Abstraction , by definition it means hiding the details and making user see what is required by him..
Let s take example of car again.. You use gear but you don t know exactly the mechanism of how exactly the gear works and changes speed and all..
Now over to coding Part.
Abstract classes are incomplete classes and for a class to be abstract as the name suggest they need to have an incomplete method that needs to be completed by the subclass inheriting the superclass , IF they don t complete the abstract method they will stay incomplete as well.
abstract class car {
abstract void gear();
}
class sedan extends car {
public void gear()
{
//complete the method
}
}
also you can not create objects of abstract classes because class is not complete. Yet these abstract classes can have static methods , arguments , concrete methods BUT for them to be abstract they need one abstract method. So one basic abstract superclass is implemented in other subclasses where they complete it By looking at the method declaration we can estimate what exactly the method is doing, what it is going to return. But we don t know how exactly the abstract method will be implemented.
By using abstract classes or interfaces , we can achieve abstraction in Java. As we all know that abstract classes, interfaces contains abstract methods
We can only estimate how they will work . We get to know how they work, once we provided the method implementation in the classes which implement the corresponding abstract class or interface.
HENCE, abstract basically helps polymorphism.