La Programación Orientada a Objetos es un concepto muy importante para que los programadores resuelvan problemas de la vida real. Este artículo explica el concepto de programación orientada a objetos y sus características.
- Objeto: Todo en este mundo está rodeado de objetos. Mesa, silla, monitor, celular, todo es un objeto. Hay dos cosas en un objeto para recordar para resolver problemas de la vida real. Uno es atributo y el otro es comportamiento. Si hablamos de monitor entonces… número de modelo, tamaño de pantalla, todos estos son atributos. Por otro lado, las funciones como subir o bajar el volumen son un comportamiento para el monitor. En programación, las variables son atributos y las funciones son comportamiento.
Ejemplo:
<?php
// Class definition
class
TV {
// Member variables
public
$model
=
'xyz'
;
public
$volume
= 1;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
}
// Create new object
$tv_one
=
new
TV;
// Calling member function
$tv_one
->volumeUp();
echo
$tv_one
->volume;
?>
Producción:2
En el ejemplo anterior, se crea un objeto $tv_one de la clase TV y se implementa una función que muestra el comportamiento del objeto. Inicialmente, $tv_one->volume era 1. Después de llamar a su función, el volumen aumentó y mostró el resultado actualizado. $this se refiere al objeto particular o actual. Puede crear varios objetos y mostrar su comportamiento. La implementación de este código tendrá el beneficio de la reutilización del código y el código será fácil de administrar en el futuro.
- Función constructora: la función constructora es una función especial para la cual no es necesario llamar a la función como lo hacíamos antes después de crear un objeto.
Ejemplo:
<?php
// Class definition
class
TV {
// Member variables
public
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
// Create new object
$tv
=
new
TV(
'xyz'
, 2);
echo
$tv
->model;
?>
Producción:xyz
En el ejemplo anterior, asignamos el valor de modelo y volumen cuando estamos creando el objeto. Este es el beneficio de usar una función constructora. No necesita cambiar el número de modelo para todos y cada uno de los proyectos que realizará. Todo lo que necesita hacer es incluir este archivo y cuando necesite crear un objeto de TV y asignar su valor, puede hacerlo instantáneamente mientras crea su objeto.
- Herencia: en pocas palabras, herencia significa heredar las propiedades o funcionalidades de una clase a otra clase. El modelo y el volumen se encontrarán en todo tipo de televisores, pero supongamos que necesita agregar un temporizador de función adicional. El temporizador no se puede incluir en todos los televisores. Por lo tanto, usará la herencia para ese televisor que incluye la propiedad del temporizador. Use la palabra clave ‘extiende’ para implementar la herencia.
Ejemplo:
<?php
// Class definition
class
TV {
// Member variables
public
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
class
TvWithTimer
extends
TV {
public
$timer
= true;
}
// Create new object
$tv
=
new
TvWithTimer(
'xyz'
, 2);
echo
$tv
->model;
?>
Producción:xyz
Aquí, la clase TVWithTimer es una clase secundaria para la clase de TV, mientras que la clase de TV es una clase principal. La clase TVWithTimer heredó todas las variables y funciones de su clase principal, por lo que todas las variables y funciones que están en la clase TV estarán disponibles en TvWithTimer. Así que cree varias clases y herede la propiedad de la clase TV. Otra cosa importante es la anulación de métodos . Si se define la función de constructor en la clase secundaria después de heredar todas las propiedades de la clase principal, las prioridades se otorgarán al constructor de la clase secundaria en lugar de a la clase principal.
class
plazmaTv
extends
TV {
function
__construct {
}
}
$plazma
=
new
plazmaTv;
echo
$plazma
->model;
Aquí, no se mostrará ningún resultado y la pantalla estará en blanco porque se está llamando al constructor de la clase secundaria y ha anulado al constructor de la clase principal. La misma lógica también se aplica a las variables y también puede anular las variables en una clase secundaria.
- Encapsulación: la encapsulación se trata de envolver los datos y el método en una sola unidad. La programación orientada a objetos establece el nivel de acceso para funciones miembro o variables. Significa desde donde se debe acceder. Hay tres tipos de niveles de acceso o especificadores de acceso.
- Público: Solo se puede acceder a las funciones o variables públicas desde cualquier lugar. En todos los ejemplos anteriores, podemos acceder a las funciones y variables públicas fuera de la clase y todos pueden llamarlas.
- Privado: solo la clase que lo creó puede acceder a las funciones o variables privadas.
Ejemplo:
<?php
// Class definition
class
TV {
// Member variables
private
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
// Create new object
$tv
=
new
TV(
'xyz'
, 2);
echo
$tv
->model;
?>
Producción:
Cannot access private property TV::$model in /home/65af96133e297a6da6c1ad3d75c9ff46.php:28
El error se mostrará después de ejecutar el código anterior. Significa que la función o variable no es accesible fuera de la clase.
- Protegido: las funciones o variables protegidas solo pueden ser utilizadas por la clase que creó y su clase secundaria significa todas las clases que heredan la propiedad de la clase principal que tiene un método o variable protegidos.
Ejemplo:
<?php
// Class definition
class
TV {
// Member variables
protected
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
getModel() {
return
$this
->model;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
class
plazma
extends
TV {
function
getModel() {
return
$this
->model;
}
}
// Create new object
$tv
=
new
plazma(
'xyz'
, 1);
echo
$tv
->getModel();
?>
Producción:xyz
- Clases abstractas: como dice la palabra clave, Abstract significa no completado. Las clases abstractas son aquellas clases donde las funciones se declaran pero no se implementan.
Ejemplo:
<?php
// Abstract class
abstract
class
ABC {
public
abstract
function
xyz();
}
class
def
extends
ABC {
public
function
xyz() {
echo
"Welcome to GeeksforGeeks"
;
}
}
// Create new object
$obj
=
new
def;
echo
$obj
->xyz();
?>
Producción:Welcome to GeeksforGeeks
Aquí, creamos una clase abstracta que tiene un método abstracto pero no hemos implementado el método en la clase base ABC. Todas las clases que extenderán la clase ABC tendrán la implementación para la función XYZ. Aquí no puedes hacer el objeto para la clase ABC. La clase ABC funciona como una clase base para todas sus clases secundarias y la implementación o creación de objetos se realizará para las clases secundarias. Declarar una clase de clase abstracta es hacer cumplir que no desea crear un objeto directo para esa clase.
Ejemplo:
<?php
abstract
class
BaseEmployee {
protected
$firstname
;
protected
$lastname
;
public
function
getFullName() {
return
$this
->firstname.
" "
.
$this
->lastname;
}
public
abstract
function
getMonthlySalary();
public
function
__construct(
$f
,
$l
) {
$this
->firstname =
$f
;
$this
->lastname =
$l
;
}
}
class
FullTimeEmployee
extends
BaseEmployee {
protected
$annualSalary
;
public
function
getMonthlySalary() {
return
$this
->annualSalary / 12;
}
}
class
ContractEmployee
extends
BaseEmployee {
protected
$hourlyRate
;
protected
$totalHours
;
public
function
getMonthlySalary() {
return
$this
->hourlyRate *
$this
->totalHours;
}
}
$fulltime
=
new
FullTimeEmployee(
'fulltime'
,
'Employee'
);
$contract
=
new
ContractEmployee(
'Contract'
,
'Employee'
);
echo
$fulltime
->getFullName();
echo
$contract
->getFullName();
echo
$fulltime
->getMonthlySalary();
echo
$contract
->getMonthlySalary();
?>
Producción:fulltime EmployeeContract Employee00
- Interfaces: Hay una limitación para la herencia en PHP que es que no puedes extender varias clases. A través de la interfaz puede lograr una propiedad de herencia múltiple. Las interfaces también funcionaron como clases abstractas. La palabra clave ‘implementos’ se utiliza para interfaces. Hay una diferencia entre la clase abstracta y la clase de interfaz. En la clase abstracta define variables pero en la interfaz, la clase no puede definir variables. Tampoco puede crear una función de constructor en las interfaces. No puede declarar una función privada o protegida.
Ejemplo:
<?php
interface
a {
public
function
abc();
}
interface
b {
public
function
xyz();
}
class
c
implements
a, b {
public
function
abc() {
echo
'GeeksforGeeks '
;
}
public
function
xyz() {
echo
'A computer science portal'
;
}
}
// Create an object
$obj
=
new
c;
$obj
->abc();
$obj
->xyz();
?>
Producción:GeeksforGeeks A computer science portal
- Miembros estáticos: Las variables estáticas o funciones estáticas están directamente relacionadas con la clase. Puede acceder a variables estáticas o funciones directamente con los nombres de clase. Utilice la palabra clave ‘static’ para declarar una función estática o una variable estática.
Ejemplo:
<?php
// Class definition
class
abc {
public
static
$data
=
'GeeksforGeeks '
;
public
static
function
xyz() {
echo
"A computer science portal"
;
}
}
echo
abc::
$data
;
abc::xyz();
?>
Producción:GeeksforGeeks A computer science portal
Ejemplo: este ejemplo cuenta cuántos objetos hemos creado para una clase.
<?php
class
abc {
public
static
$objectCount
= 0;
public
static
function
getCount() {
return
self::
$objectCount
;
}
public
function
__construct() {
self::
$objectCount
++;
}
}
$a
=
new
abc();
$b
=
new
abc();
$c
=
new
abc();
$d
=
new
abc();
echo
abc::getCount();
?>
Producción:4
Nota: si se crea un objeto en lugar de estático usando una función o variable estática cada vez que la salida será 1. Por lo tanto, la variable o palabra clave estática está relacionada con la clase, no con el objeto.
- Enlace estático tardío: en PHP 5.3 se introdujo un concepto de enlace estático tardío.
Ejemplo:
<?php
class
DB {
protected
static
$table
=
' basetable'
;
public
function
select() {
echo
'SELECT * FROM'
.self::
$table
;
}
public
function
insert() {
echo
'INSERT INTO'
.self::
$table
;
}
}
class
abc
extends
DB {
protected
static
$table
=
'abc'
;
}
$abc
=
new
abc;
$abc
->select();
?>
Producción:SELECT * FROM basetable
Aquí, la clase DB extiende la clase abc, pero cuando se ejecuta este código durante el tiempo de compilación, toma el nombre de la tabla de la clase abc, no de la base de datos. Durante el tiempo de compilación, el intérprete de PHP asigna inmediatamente el valor de la clase principal. Para obtener la variable del elemento secundario, el intérprete de clase debe asignar el valor durante el tiempo de ejecución en lugar del tiempo de compilación, como ocurre en el ejemplo anterior.
echo 'SELECT * FROM' .self::$table;
o
echo 'INSERT INTO' .self::$table;
Aquí, cuando el intérprete reciba la solicitud, no asignará el valor durante el tiempo de compilación. Estará en espera para el tiempo de ejecución. Asignará el valor durante el tiempo de ejecución y la salida será SELECCIONAR * DESDE abc
- Polimorfismo: Polimorfismo significa muchos tipos o muchas formas. Significa supongamos que ha creado una interfaz y también clases que implementarán esta clase de interfaz. Estas clases tendrán una funcionalidad diferente y todas compartirán esta interfaz común.
Cree una interfaz con el nombre LoggerInterface en el archivo LoggerInterface.php.
<?php
interface
LoggerInterface {
public
function
log(
$message
);
}
?>
Ahora crea un archivo EmailLogger.php que implementará esta interfaz.
<?php
class
EmailLogger
implements
LoggerInterface {
public
function
log(
$message
) {
echo
"Logging message to email: $message"
;
}
}
?>
Cree otro archivo FileLogger.php e implemente la clase de interfaz.
<?php
class
FileLogger
implements
LoggerInterface {
public
function
log(
$message
) {
echo
"Logging message to file: $message"
;
}
}
?>
Otro archivo es DBLogger.php
<?php
class
DBLogger
implements
LoggerInterface {
public
function
log(
$message
) {
echo
"logging message to DB: $message"
;
}
}
?>
Ahora, cree un archivo UserProfile.php donde llame a todos estos archivos definiendo solo el nombre de la interfaz usando sugerencias de tipo. No es necesario definir el nombre de la clase para llamar a todas y cada una de las clases creadas en un archivo.
<?php
class
UserProfile {
private
$logger
;
public
function
createUser() {
echo
"creating user"
;
$this
->logger->log(
"User Created"
);
}
public
function
updateUser() {
echo
"updating user"
;
$this
->logger->log(
"User Updated"
);
}
public
function
deleteUser() {
echo
"deleting user"
;
$this
->logger->log(
"Deleting User"
);
}
public
function
__construct(LoggerInterface
$logger
)
{
$this
->logger =
$logger
;
}
}
?>
Ahora, crea un archivo index.php
<?php
function
__autoload(
$class
) {
// classes is a directory where all
// the above files are placed.
include_once
"classes/$class.php"
;
}
function
getLogger(
$type
) {
switch
(
$type
) {
case
'email'
:
return
new
EmailLogger();
break
;
case
'database'
:
return
new
DBLogger();
break
;
case
'file'
:
return
new
FileLogger();
break
;
}
}
$logger
= getLogger(
'database'
);
$profile
=
new
UserProfile(
$logger
);
$profile
->createUser();
?>
Producción:
Creating User. Logging message to DB: User Created
Entonces, a partir de este ejemplo, cree varios archivos y defina su funcionalidad. Todos deben implementar la clase de interfaz y simplemente dar el nombre de la interfaz en el nombre de sugerencia de tipo como lo he definido en el archivo UserProfile.php.
- Rasgos: Los rasgos se introdujeron en PHP5.4. Es el mecanismo para la reutilización de código en lenguaje de herencia única. La palabra clave ‘trait’ se usa para definirlo.
Ejemplo:
<?php
class
abc {
public
function
test() {
echo
"test from class ABC"
;
}
}
trait
test {
public
function
test2() {
echo
"test2 method of test trait"
;
}
}
class
one
extends
abc {
use
test;
}
class
two
extends
abc {
use
test;
}
class
three
extends
abc {
}
class
four
extends
abc {
}
class
five
extends
abc {
}
$obj
=
new
one;
$obj
->test2();
?>
Producción:test2 method of test trait
Aquí, tomando una clase abc y su funcionalidad en todas las clases secundarias. Entonces, accediendo a las propiedades de la clase abc en todas las clases secundarias. Ahora considere un escenario en el que necesitamos acceder a otra función solo en la clase uno y dos, pero no en el resto de las clases. Si definirá esa función en la misma clase abc, estará disponible en todas las clases que están extendiendo la clase abc. Entonces, la solución es que podemos definir ese método en el rasgo.
El rasgo también es similar a las clases. Aquí, defina la función test2 en la prueba de rasgos y use este rasgo usando la palabra clave ‘usar’ en la clase secundaria. Entonces, hemos usado este rasgo solo en la clase uno y dos porque necesitamos acceder a este método en la clase uno y dos. - Anulación de métodos en rasgos: si se define el mismo método implementado en la clase y en el rasgo también, se dará preferencia a la implementación del método de la clase de rasgo. Significa que un método de clase de rasgo anulará el método de clase principal.
Ejemplo:
<?php
class
Base {
public
function
abc() {
echo
"ABC method from base class"
;
}
}
Trait Test {
public
function
abc() {
echo
"ABC method from test trait"
;
}
}
class
child
extends
Base {
use
Test;
}
$obj
=
new
Child;
$obj
->abc();
?>
Producción:
ABC method from test trait
Entonces, el orden de preferencia es método de clase hijo > método de clase rasgo > método de clase padre.
- Nivel de acceso en rasgos: puede cambiar el nivel de acceso de rasgos en la clase secundaria.
Ejemplo:
<?php
trait
abc {
public
function
xyz() {
echo
"xyz method from trait abc"
;
}
}
class
test {
use
abc {
abc::xyz
as
public
abcXyz;
}
}
$obj
=
new
test;
$obj
->abcXyz();
?>
Producción:xyz method from trait abc
- Espacios de nombres: en PHP, la clase no se puede volver a declarar. Significa que una clase no se puede declarar más de una vez. Mostrará un mensaje de error. Para resolver este problema se utiliza el concepto de espacio de nombres.
Ejemplo:
<?php
namespace
def {
class
xyz {
public
function
__construct() {
echo
"XYZ from DEF namespace"
;
}
}
}
namespace
{
class
xyz {
public
function
__construct() {
echo
"XYZ from Global namespace"
;
}
}
$obj
=
new
def/xyz();
}
?>
Producción:
XYZ from DEF namespace
De forma predeterminada, todas las clases forman parte del espacio de nombres global. El espacio de nombres global declarado con solo la palabra clave ‘espacio de nombres’ (no es necesario definir el nombre del espacio de nombres). El código no se puede declarar fuera del espacio de nombres. Además, el espacio de nombres debe ser la primera línea de su código si está declarando una clase en él.
También hay una forma alternativa de llamar a la función desde la clase def. simplemente reemplace el código como se muestra a continuación cuando cree un objeto.use def\xyz as def; $obj = new def();
La salida será la misma. También puede crear un subespacio de nombres para un espacio de nombres. Todo lo que necesita hacer cuando lo declara está debajo de la línea.
namespace def\ghi
- Sugerencia de tipo: en PHP, no es necesario definir el tipo de datos de la variable que está declarando. Define automáticamente el tipo de datos al crear una variable, pero a veces, cuando recibe una variable, necesita definir qué tipo de variable está recibiendo.
Ejemplo:
<?php
// Function definition
function
test(
array
$arr
) {
foreach
(
$arr
as
$k
=>
$v
) {
echo
$k
.
" "
.
$v
.
"\n"
;
}
}
// Declare an array
$array
= [
'abc'
=>
'ABC'
,
'xyz'
=>
'XYZ'
];
// Function call
test(
$array
);
?>
Producción:abc ABC
xyz XYZEntonces, al recibir la variable y definir que debería ser un tipo de array. Si analizará datos de tipo string $array =’abcdefgh’, obtendrá un error fatal y el código no se ejecutará. También puede hacer sugerencias de tipo para el nombre de la clase y la interfaz.
Publicación traducida automáticamente
Artículo escrito por anuupadhyay y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA