What is polymorphism. Fundamentals of Object-Oriented Programming

JAVA is based on the concepts of object-oriented programming, which allows you to move to more high level abstractions to solve any problem in a realistic way. The object-oriented approach conceptualizes the solution to a problem in terms of real-world objects that are easier to reuse in an application. For example, Chair (chair), Fan (fan), Dog (Dog), Computer (computer) and so on. In JAVA, a class is a layout, template, or prototype that defines general behavior object of this type. An instance is a separate implementation of a class, and all instances of a class have the same properties, which are described in the class definition. For example, you can define a class named House with number of rooms as an attribute and create instances of the class such as a two-room house, a three-room house, and so on. Advantages: Listed below are some pros of object-oriented development software(BY).

  • Reduced software support costs, mainly due to the fact that it is carried out modularly.
  • Improved code reuse through features such as inheritance, resulting in faster software development.
  • Increased code reliability and flexibility.
  • Ease of understanding due to real world simulation.
  • Better abstraction at the object level.
  • Reducing the complexity of transition from one development phase to another.
There are four main characteristics of OOP:
  • Encapsulation
  • Inheritance
  • Polymorphism
  • Abstraction

Encapsulation

Encapsulation acts as a contract for an object what it should hide and what it should open for access by other objects. In JAVA, we use the private access modifier to hide a method and restrict access to a variable from outside world. JAVA also has various access modifiers: public, default, protected, private, which are used to restrict visibility at different levels. But the ultimate goal is to encapsulate those things that shouldn't be changed. The approach that works best is that a class should only have one reason to change, and encapsulation makes the design of that “one reason” a reality. The correct approach to encapsulation is to hide things that change frequently to avoid damaging other classes. Advantages: Below are some benefits of encapsulation:
  • We can protect the internal state of an object by hiding its attributes.
  • This improves code modularity because it prevents objects from interacting in unexpected ways.
  • Improves code usability.
  • This supports the contractual relationship of a specific entity.
  • Encapsulation makes software easier to maintain.
  • Changes to the code can be made independently of each other.

Polymorphism

Polymorphism in programming is the ability to provide the same interface for different underlying forms (data types). This means that classes having different functionality share the same interface and can be called dynamically by passing parameters by reference. A classic example is the Shape class and all the classes that inherit from it: square, circle, dodecahedron, irregular polygon, splat, and so on. In this example, each class will have its own Draw() method and the client code can simply do: Shape shape = new Shape() ; Shape.area() to get the correct behavior of any shape The beauty of polymorphism is that the code, when working with different classes, does not need to know which class it is using, since they all work on the same principle. The process used by object-oriented programming languages ​​to implement dynamic polymorphism is called dynamic binding. Note: Polymorphism is the ability to choose more specific methods to execute depending on the object. Polymorphism occurs when abstract classes are not involved. Advantages:
  • Creating reusable code. That is, once a class is created, implemented, and tested, it can be freely used without worrying about what exactly is written in it.
  • This allows for more generic and loosely coupled code.
  • Compilation time is reduced, which speeds up development.
  • Dynamic linking.
  • The same interface can be used to create methods with different implementations.
  • The entire implementation can be replaced by using the same method signatures.
Method overriding as part of polymorphism. An override interacts with two methods: a method in the parent class and a method in the derived class. These methods have the same name and signatures. Overriding allows you to perform the same operation in different ways for different types objects. For example: while (it. hasNext () ) ( Shape s = (Shape) it. next () ; totalArea += s. area (dim) ; //polymorphism will be applied and called desired method for each object. } Method overloading or ad-hoc polymorphism or static polymorphism Reloading interacts with multiple methods of the same class that are named the same but have different method signatures. Reloading allows you to describe the same operation in different ways for different data. It is sometimes called static polymorphism, but in fact it is not polymorphism. This is nothing more than just having two methods with same names, but with a different list of arguments. Rebooting has nothing to do with inheritance and polymorphism. And an overloaded method is not at all the same as an overridden method. Parametric polymorphism via generalization in JAVA When declaring a class, the name field can be associated with various types, and the method name can be associated with various parameters and return types. JAVA supports parametric polymorphism by using generics. List < String> list = new ArrayList < String> () ; Why can't we override a static method in JAVA? Overriding depends on the existence of an instance of the class. The idea of ​​polymorphism is that you can create a subclass, and the objects implemented by those subclasses will behave differently with the same methods of the parent class (overridden in the subclasses). A static method is not associated with any instances of the class, so the concept of overriding itself cannot be applied. The creators of JAVA were guided by two considerations that influenced this approach. Firstly, there are code execution problems: there was a lot of criticism against Smalltalk because slow work(garbage collection and polymorphism were part of this problem) and JAVA's design tried to avoid this. The second consideration was the decision that JAVA's target audience would be C++ developers. Having static methods work this way was very familiar to C++ programmers, and also speeded things up since there was no need to go up the class hierarchy to figure out which method to call. You go straight to the class and call a specific method.

Inheritance

Inheritance is the inclusion of behavior (i.e. methods) and state (i.e. variables) of a base class in a derived class, thus making them available in that derived class. The main advantage of inheritance is that it provides a formal mechanism reuse code and avoids duplication. An inherited class extends the functionality of the application by copying the behavior of the parent class and adding new functionality. This makes the code highly coupled. If you want to change the superclass, you will have to know all the details of the subclasses so as not to break the code. Inheritance is a form of software reuse when a new class (subclass) is created from an existing class (superclass) that extends its functionality and at the same time uses some of the properties of the superclass. So if you have a parent class and then a child class appears, the child inherits all the things that the parent has. Advantages:
  • Improved code reuse.
  • The logical relation “is a” (is someone, something) is established. For example: Dog is a n animal. (A dog is an animal).
  • Code modularization.
  • Repetitions are excluded.
Flaw:
  • Strong coupling: a subclass depends on the implementation of a parent class, making the code highly coupled.
What else to read:

Abstraction

Abstraction means designing classes based on their interfaces and functionality, without taking into account the implementation details. An abstract class represents interfaces without including the actual implementation. It distinguishes the implementation of an object from its behavior. Abstraction simplifies the code by hiding unimportant details. Advantages:
  • By using abstraction, we can separate out what can be grouped into some type.
  • Frequently modified properties and methods can be grouped into a separate type, so the main type will not be subject to changes. This reinforces the OOP principle: “The code should be open for Extension, but closed for Change”.
  • Abstraction simplifies the representation of domain models.
Difference between abstraction and encapsulation Encapsulation is a strategy used as part of abstraction. Encapsulation refers to the structure of an object: objects encapsulate their properties and hide them from outside access. Users of a class interact with it using its methods, but do not have direct access to the class structure. In this way, the class abstracts implementation details related to its design. Abstraction is a more general term. It can also be achieved, among other things, using subclasses. For example, the List class in the standard library is an abstraction for a sequence of elements indexed according to their position in a list. Specific examples of a List are ArrayList or LinkedList. Code that interacts with a List abstracts away the details of which list it uses. Often abstraction is not possible without hiding the underlying state using encapsulation. If a class reveals its internal structure, it cannot change its internal operations, and therefore cannot abstract. What are abstract class and abstract method? It happens that during development you want a base class to only provide an interface to its derived classes. That is, you don't want anyone to create instances of the base class. You need to use the interface in such a way that you only cast objects to it (this is an implicit cast that allows polymorphic behavior). This is achieved by making the given class abstract using the abstract keyword. This imposes some restrictions, such as the inability to create instances of an abstract class; when using an abstract class, it is necessary to implement abstract methods. This ensures polymorphism. An abstract class can contain both abstract and concrete methods. If at least one method in a class is declared abstract, the entire class must also be declared abstract. However, the rule in the opposite direction does not have to be observed. If a class is declared abstract, it may not contain abstract methods. A method that merely defines its signatures and does not provide an implementation is called abstract. Its actual implementation is left to its subclasses, which extend the abstract class. An abstract method cannot be used by an object, only another class can extend it. When should you use an abstract class? Abstract classes allow you to define some default behavior and have subclasses provide any specific behavior. For example: List (list) is an interface, in turn AbstractList defines the basic behavior of the List, which can be used as is or refined in a subclass, for example, in an ArrayList (list array). What is an interface? The interface concept is an abstract class, but the interface (defined keyword interface) took a step further. It prevents any implementation of a method or function at all. You can only declare a method or function, but not provide its implementation. The class that implements this interface, should just take care of the actual implementation. Interfaces are very useful and are widely used in OOP. Since they share the interface itself and the implementation, they provide many advantages of their use:
  1. Multiple inheritance.
  2. Loose coupling. There is an abstraction of the operation, such as layering, and the concrete implementation can be anything: JDBC, JPA, JTA, etc.
  3. The interface program is not implemented.
  4. Polymorphism with dynamic binding: Expands the programming interface of an object without revealing its actual implementation.
  5. Abstract levels, separation of functionality.
Difference between interface and abstract class.
  • An interface is a contractual relationship with the classes that implement this interface, stating that the implementation occurs in the way designated by the interface. This is an empty shell with declared methods.
  • An abstract class defines some general behavior and asks its subclasses to define atypical or specific behavior for their class.
  • Methods and members of an abstract class can be designated with any access modifier; in turn, all interface methods must be public.
  • When inheriting an abstract class, the descendant class must define abstract methods, while an interface can inherit another interface without necessarily defining its methods.
  • A descendant class can extend only one abstract class, but an interface can extend or a class can implement many other interfaces.
  • A descendant class can define abstract methods with the same or less restrictive access modifier, but the class implementing the interface must define methods with the same level of visibility.
  • An interface does not contain constructors, while an abstract class does.
  • Variables declared in the Java interface are final by default. An abstract class can contain variables that are not final.
  • All members of a Java interface are public by default. Members of an abstract class can allow themselves to be public, protected, etc.

Composition

Code reuse can be achieved using both inheritance and composition. But using composition provides a higher level of encapsulation than inheritance, since changes to the back-end class will not necessarily affect the code that belongs to the front-end class. Composition is a design technique that uses “has-a” (has, includes) relationships in classes. Both java inheritance and object composition can be used to reuse code. The essence of composition is to express the “has a” relationship between objects. Think about a chair. The chair has a seat. The chair has a back. A chair has a certain number of legs. The phrase “has a” suggests a relationship in which the chair has, or at least uses, another object. This is precisely the “has-a” relationship, which is the basis of the composition. Advantages:
  • Visibility control
  • The implementation can be replaced at run-time
  • Loose coupling, since the interface class does not depend on the implementation.
Differences between composition and inheritance
Composition (has a / has)Inheritance (is a / is)
1 Supports polymorphism and code reuse.
2 The run-time object has already been created.The object is created dynamically at compile time.
3 The implementation can be replaced at run-time.The implementation can be changed at compile time.
4 A subclass is independent of its parent class, which favors loose coupling (especially under interface control).The subclass is dependent on the implementation of the parent class, so the binding is considered strong.
5 Use: The House has a Bathroom. It is wrong to say that the House is the Bathroom.Inheritance is unidirectional: a House is a Building. But the building is not a home.
Note: Don't use inheritance just to ensure code reuse. If there is no relation “is a“ (is), composition is used for these purposes. The difference between composition and aggregation is in object relationships. Aggregation is a relationship in which one class fits into a collection. It is a part of a whole relationship, where the part can exist without the whole. Such relationships are much weaker. There is no cyclic dependency. For example: order and product. Composition is a relationship in which one class fits into a collection. It is a part of a whole relationship in which the part cannot exist without the whole. If the whole is destroyed, all its components will also be destroyed. It's a stronger relationship. For example: a polygon and its vertices, an order and its component.

s_a_p August 20, 2008 at 7:09 pm

Polymorphism for Beginners

  • PHP

Polymorphism is one of the three main OOP paradigms. In short, polymorphism is the ability of an object to use methods of a derived class that does not exist at the time the base one is created. For those who are not particularly knowledgeable in OOP, this probably sounds complicated. Therefore, let's look at the use of polymorphism using an example.

Formulation of the problem

Let's assume that the site needs three types of publications - news, announcements and articles. They are similar in some ways - they all have a title and text, news and announcements have a date. In some ways they are different - articles have authors, news has sources, and announcements have a date after which it becomes irrelevant.

The most simple options that come to mind is to write three separate classes and work with them. Or write one class that will contain all the properties inherent in all three types of publications, and only the necessary ones will be used. But for different types, methods that are similar in logic should work differently. Making several methods of the same type for different types (get_news, get_announcements, get_articles) is completely ignorant. This is where polymorphism comes in handy.

Abstract class

Roughly speaking, this is a template class. It implements functionality only at the level at which it is known in the this moment. Derived classes complement it. But, it's time to move from theory to practice. Let me make a reservation right away: we are considering a primitive example with minimal functionality. All explanations are in the comments in the code.

abstract class Publication
{
// table that stores data on the element
protected $table ;

// element properties are unknown to us
protected $properties = array();

// constructor

{
// note that we don't know which table we need to get the data from
$result = mysql_query ("SELECT * FROM `" . $this -> table . "` WHERE `id`="" . $id . "" LIMIT 1" );
// we don’t know what data we received either
$this -> properties = mysql_fetch_assoc ($result);
}

// method, the same for any type of publication, returns the property value
public function get_property ($name)
{
if (isset($this -> properties [ $name ]))
return $this -> properties [ $name ];

Return false ;
}

// method, the same for any type of publication, sets the property value
public function set_property ($name, $value)
{
if (!isset($this -> properties [ $name ]))
return false ;

$this -> properties [ $name ] = $value ;

Return $value ;
}

// and this method should print the publication, but we don’t know how exactly to do this, and therefore we declare it abstract
abstract public function do_print();
}

Derived classes

Now you can move on to creating derived classes that implement the missing functionality.

class News extends Publication
{
// constructor of the news class, derived from the publications class
public function __construct ($id)
{
// set the value of the table in which news data is stored
$this -> table = "news_table" ;
parent :: __construct ($id );
}

Public function do_print()
{
echo $this -> properties ["title" ];
echo "

" ;
echo $this -> properties ["text" ];
echo "
Source: " . $this -> properties [ "source" ];
}
}

Class Announcement extends Publication
{
// constructor of the ad class derived from the publication class
public function __construct ($id)
{
// set the value of the table in which ad data is stored
$this -> table = "announcements_table" ;
// call the constructor of the parent class
parent :: __construct ($id );
}

// override the abstract print method
public function do_print()
{
echo $this -> properties ["title" ];
echo "
Attention! The announcement is valid until "
. $this -> properties ["end_date" ];
echo "

" . $this -> properties [ "text" ];
}
}

Class Article extends Publication
{
// constructor of the article class, derived from the publication class
public function __construct ($id)
{
// set the value of the table in which data on articles is stored
$this -> table = "articles_table" ;
// call the constructor of the parent class
parent :: __construct ($id );
}

// override the abstract print method
public function do_print()
{
echo $this -> properties ["title" ];
echo "

" ;
echo $this -> properties ["text" ];
echo "
" . $this -> properties [ "author" ];
}
}

Now about use

The point is that the same code is used for objects of different classes.

// fill the publication array with objects derived from Publication
$publications = new News ($news_id);
$publications = new Announcement($announcement_id);
$publications = new Article($article_id);

Foreach ($publications as $publication) (
// if we work with Publication heirs
if ($publication instanceof Publication) (
// then print the data
$publication -> do_print();
) else (
// exception or error handling
}
}

That's all. With a slight movement of the hand, the trousers turn into elegant shorts :-).

The main benefit of polymorphism is the ease with which new classes can be created that behave similarly to related ones, which in turn allows for extensibility and modifiability. The article shows just a primitive example, but even it shows how the use of abstractions can make development easier. We can work with news just like we do with advertisements or articles, and we don't even have to know what we're working with! In real, much more complex applications, this benefit is even greater.

A little theory

  • Methods that require overriding are called abstract. It is logical that if a class contains at least one abstract method, then it is also abstract.
  • Obviously, an object of an abstract class cannot be created, otherwise it would not be abstract.
  • A derived class has properties and methods that belong to the base class, and can also have its own methods and properties.
  • A method that is overridden in a derived class is called a virtual method. There is no information about this method in the base abstract class.
  • The point of abstraction is to define a method in the place where there is the most complete information about how it should work.
UPD: Regarding sql-inj and MVC violations - gentlemen, this is just an example, and an example of polymorphism, in which I do not consider it necessary to pay attention to these things. This is a topic for completely different articles.

Polymorphism (programming)

Briefly, the meaning of polymorphism can be expressed in the phrase: “One interface, many implementations.”

Polymorphism is one of the four most important object-oriented programming mechanisms (along with abstraction, encapsulation and inheritance).

Polymorphism allows you to write more abstract programs and increase code reuse. The general properties of objects are combined into a system, which can be called differently - interface, class. Community has external and internal expression:

  • external commonality manifests itself as the same set of methods with the same names and signatures (names of methods, types of arguments and their number);
  • internal commonality - the same functionality of the methods. It can be described intuitively or expressed in the form of strict laws, rules to which methods must obey. The ability to assign different functionality to one method (function, operation) is called method overloading (function overloading, overload of operations).

Examples

A class of geometric shapes (ellipse, polygon) can have methods for geometric transformations (displacement, rotation, scaling).

In functional languages

There are two types of polymorphism in Haskell - parametric (pure) and special (class-based). Special is also called ad hoc(from Latin ad hoc - specially). They can be distinguished as follows:

Parametric polymorphism

Special polymorphism

Haskell has a division into classes and instances, which is not found in OOP. The class defines a set and signatures of methods (perhaps giving default implementations for some or all of them), and instances implement them. Thus, the problem of multiple inheritance automatically disappears. Classes do not inherit or override methods of other classes - each method belongs to only one class. This approach is simpler than the complex diagram of class relationships in OOP. A given data type can belong to several classes; a class may require that each of its types necessarily belong to another class, or even several; the same requirement may be put forward by an instance. These are analogues of multiple inheritance. There are also some properties that have no analogues in OOP. For example, implementing a list as an instance of the class of comparable quantities requires that the elements of the list also belong to the class of comparable quantities.

Programmers moving from OOP to FP should be aware of an important difference between their class systems. If in OOP a class is “tied” to an object, i.e., to data, then in FP it is tied to a function. In FP, information about class membership is passed when a function is called, rather than stored in the fields of the object. This approach, in particular, allows us to solve the problem of a method of several objects (in OOP, a method is called on one object). Example: the addition method (numbers, strings) requires two arguments, both of the same type.

Implicit typing

Some programming languages ​​(for example, Python and Ruby) use so-called duck typing (other names: latent, implicit), which is a type of signature polymorphism. Thus, for example, in Python, polymorphism is not necessarily associated with inheritance.

Forms of polymorphism

Static and dynamic polymorphism

(mentioned in the classic book by Sutter and Alexandrescu, which is the source).

Polymorphism can be understood as the presence of customization points in the code, when the same piece of code written by the programmer can mean different operations depending on something.

In one case, the specific meaning of a fragment depends on the environment in which the code was built. This is the so-called static polymorphism. Function overloading and templates in C++ implement static polymorphism. If, for example, std::sort is called in the code of a template class, then the real meaning of the call depends on which type parameters this template will be deployed for - one of std::sort will be called .

In another case, the specific meaning of the fragment is determined only at the execution stage and depends on how exactly and where exactly it was constructed this object. This is ordinary, dynamic polymorphism, implemented through virtual methods.

Inclusion polymorphism

This polymorphism is called pure polymorphism. By using this form of polymorphism, related objects can be used in a general way. Using substitution and inclusion polymorphism, you can write one method to work with all types of TPerson objects. Using inclusion and substitution polymorphism, you can work with any object that passes the “is-A” test. Inclusion polymorphism simplifies the work of adding new subtypes to a program, since there is no need to add a specific method for each new type; you can use an existing one, only by changing the behavior of the system in it. With polymorphism, you can reuse a base class; use any descendant or methods that the base class uses.

Parametric polymorphism

Using Parametric Polymorphism you can create universal base types. In the case of parametric polymorphism, the function is implemented equally for all types and thus the function is implemented for an arbitrary type. Parametric Polymorphism covers parametric methods and types.

Parametric Methods

If inclusion polymorphism affects our perception of an object, parametric polymorphism affects the methods used, since it is possible to create methods of related classes, deferring the declaration of types until runtime. To avoid writing a separate method for each type, parametric polymorphism is used, in which the type of the parameters will be the same parameter as the operands.

Parametric types

Instead of writing a class for each specific type, we should create types that will be implemented during program execution, that is, we create a parametric type.

Override polymorphism

Abstract methods are often referred to as deferred methods. The class in which this method is defined can call the method, and polymorphism ensures that the appropriate version of the deferred method is called in child classes. Ad hoc polymorphism allows a special implementation for each data type.

Polymorphism-overload

This is a special case of polymorphism. With the help of overloading, the same name can designate different methods, and the methods can differ in the number and type of parameters, that is, they do not depend on their arguments. The method may not be limited to specific parameter types of many different types.

Polymorphism (in programming languages) is the ability of objects with the same specification to have different implementations.

A programming language supports polymorphism if classes with the same specification can have different implementations - for example, the implementation of a class can be changed through the process of inheritance.

Briefly, the meaning of polymorphism can be expressed in the phrase: “One interface, many implementations.”

Polymorphism is one of the four most important mechanisms of object-oriented programming (along with abstraction, encapsulation and inheritance).

Polymorphism allows you to write more abstract programs and increase code reuse. The general properties of objects are combined into a system, which can be called differently - interface, class. Community has external and internal expression:

external commonality manifests itself as the same set of methods with the same names and signatures (name of methods and types of arguments and their number);

internal commonality - the same functionality of the methods. It can be described intuitively or expressed in the form of strict laws, rules to which methods must obey. The ability to assign different functionality to one method (function, operation) is called method overloading (function overloading, operation overloading).

A class of geometric shapes (ellipse, polygon) can have methods for geometric transformations (displacement, rotation, scaling).

The stream class has methods for serial data transfer. The stream can be information entered by the user from the terminal, data exchange via computer network, file (if sequential data processing is required, for example, when parsing source codes of programs).

In object-oriented languages

In object-oriented languages, a class is an abstract data type.[Note. 1] Polymorphism is implemented using class inheritance and virtual functions. A child class inherits the signatures of the methods of the parent class, and the implementation, as a result of method overriding, of these methods can be different, corresponding to the specifics of the descendant class. Other functions may treat an object as an instance of a parent class, but if the object is actually an instance of a child class, the method overridden in the child class will be called at runtime. This is called late binding. [An example use case would be the processing of an array containing instances of both a parent and a child class: obviously, such an array can only be declared as an array of the type of the parent class and only methods of that class can be called on objects of the array, but if in If some methods have been overridden in the descendant class, then in runtime mode for instances of this class they will be called, and not the methods of the parent class.]

A child class can itself be a parent. This allows you to build complex inheritance schemes - tree-like or network-like.

Abstract (or pure virtual) methods have no implementation at all (in fact, some languages, such as C++, allow abstract methods to be implemented in a parent class). They are specifically designed for inheritance. Their implementation must be defined in descendant classes.

A class can inherit functionality from multiple classes. This is called multiple inheritance. Multiple inheritance creates a well-known problem (in C++) when a class inherits from multiple proxy classes, which in turn inherit from the same class (the so-called "Diamond Problem"): if a common ancestor method was overridden in the proxy, it is unknown which implementation of the method must be inherited by a common descendant. This problem is solved by refusing multiple inheritance for classes and allowing multiple inheritance for completely abstract classes (that is, interfaces) (C#, Delphi, Java), or through virtual inheritance (C++).

In functional languages

Polymorphism in functional languages ​​will be discussed using Haskell as an example.

Polymorphism is one of the three main OOP paradigms. In short, polymorphism is the ability of an object to use methods of a derived class that does not exist at the time the base one is created. For those who are not particularly knowledgeable in OOP, this probably sounds complicated. Therefore, let's look at the use of polymorphism using an example.

Formulation of the problem

Let's assume that the site needs three types of publications - news, announcements and articles. They are similar in some ways - they all have a title and text, news and announcements have a date. In some ways they are different - articles have authors, news has sources, and announcements have a date after which it becomes irrelevant.

The simplest options that come to mind are to write three separate classes and work with them. Or write one class that will contain all the properties inherent in all three types of publications, and only the necessary ones will be used. But for different types, methods that are similar in logic should work differently. Making several methods of the same type for different types (get_news, get_announcements, get_articles) is completely ignorant. This is where polymorphism comes in handy.

Abstract class

Roughly speaking, this is a template class. It implements functionality only at the level at which it is currently known. Derived classes complement it. But, it's time to move from theory to practice. Let me make a reservation right away: we are considering a primitive example with minimal functionality. All explanations are in the comments in the code.

abstract class Publication
{
// table that stores data on the element
protected $table ;

// element properties are unknown to us
protected $properties = array();

// constructor

{
// note that we don't know which table we need to get the data from
$result = mysql_query ("SELECT * FROM `" . $this -> table . "` WHERE `id`="" . $id . "" LIMIT 1" );
// we don’t know what data we received either
$this -> properties = mysql_fetch_assoc ($result);
}

// method, the same for any type of publication, returns the property value
public function get_property ($name)
{
if (isset($this -> properties [ $name ]))
return $this -> properties [ $name ];

Return false ;
}

// method, the same for any type of publication, sets the property value
public function set_property ($name, $value)
{
if (!isset($this -> properties [ $name ]))
return false ;

$this -> properties [ $name ] = $value ;

Return $value ;
}

// and this method should print the publication, but we don’t know how exactly to do this, and therefore we declare it abstract
abstract public function do_print();
}

Derived classes

Now you can move on to creating derived classes that implement the missing functionality.

class News extends Publication
{
// constructor of the news class, derived from the publications class
public function __construct ($id)
{
// set the value of the table in which news data is stored
$this -> table = "news_table" ;
parent :: __construct ($id );
}

Public function do_print()
{
echo $this -> properties ["title" ];
echo "

" ;
echo $this -> properties ["text" ];
echo "
Source: " . $this -> properties [ "source" ];
}
}

Class Announcement extends Publication
{
// constructor of the ad class derived from the publication class
public function __construct ($id)
{
// set the value of the table in which ad data is stored
$this -> table = "announcements_table" ;
// call the constructor of the parent class
parent :: __construct ($id );
}

// override the abstract print method
public function do_print()
{
echo $this -> properties ["title" ];
echo "
Attention! The announcement is valid until "
. $this -> properties ["end_date" ];
echo "

" . $this -> properties [ "text" ];
}
}

Class Article extends Publication
{
// constructor of the article class, derived from the publication class
public function __construct ($id)
{
// set the value of the table in which data on articles is stored
$this -> table = "articles_table" ;
// call the constructor of the parent class
parent :: __construct ($id );
}

// override the abstract print method
public function do_print()
{
echo $this -> properties ["title" ];
echo "

" ;
echo $this -> properties ["text" ];
echo "
" . $this -> properties [ "author" ];
}
}

Now about use

The point is that the same code is used for objects of different classes.

// fill the publication array with objects derived from Publication
$publications = new News ($news_id);
$publications = new Announcement($announcement_id);
$publications = new Article($article_id);

Foreach ($publications as $publication) (
// if we work with Publication heirs
if ($publication instanceof Publication) (
// then print the data
$publication -> do_print();
) else (
// exception or error handling
}
}

That's all. With a slight movement of the hand, the trousers turn into elegant shorts :-).

The main benefit of polymorphism is the ease with which new classes can be created that behave similarly to related ones, which in turn allows for extensibility and modifiability. The article shows just a primitive example, but even it shows how the use of abstractions can make development easier. We can work with news just like we do with advertisements or articles, and we don't even have to know what we're working with! In real, much more complex applications, this benefit is even greater.

A little theory

  • Methods that require overriding are called abstract. It is logical that if a class contains at least one abstract method, then it is also abstract.
  • Obviously, an object of an abstract class cannot be created, otherwise it would not be abstract.
  • A derived class has properties and methods that belong to the base class, and can also have its own methods and properties.
  • A method that is overridden in a derived class is called a virtual method. There is no information about this method in the base abstract class.
  • The point of abstraction is to define a method in the place where there is the most complete information about how it should work.
UPD: Regarding sql-inj and MVC violations - gentlemen, this is just an example, and an example of polymorphism, in which I do not consider it necessary to pay attention to these things. This is a topic for completely different articles.
Internet