Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Relaciones entre
clases
Lima, 2018
Abraham Sopla Maslucán
El trabajo que presentamos a continuación, tiene un propósito totalmente académico, es una
lista de ejemplos prácticos de codificación de cada de las relaciones entre clases en lenguaje C++,
entre ellos: relación de dependencia/uso, relación de asociación, relación de agregación, relación
de composición, relación de generalización/ herencia y relación de especialización. En todos ellos
se aplican los principios de la programación orientada a objetos.
Algunos de los ejemplos han sido recopilados, revisados y modificados, con especial cuidado, de
tal manera que cumplan con las reglas tratando de cubrir todos los tipos de relaciones entre
clases. Las imágenes y diagramas han sido elaborados en LuciChart.
Relaciones entre clases en C++
Abraham Sopla Maslucán
Contenido
1. Protected, private y public .......................................................................................................... 4
2. Dependencia/Uso: área de círculo ............................................................................................. 4
3. Dependencia/Uso: Clase1 usa objetos de la clase2 y viceversa .............................................. 5
4. Asociación: una laptop usa parlantes......................................................................................... 5
5. Composición: una laptop tiene microprocesador ..................................................................... 8
6. Agregación: agreguemos contactos a una agenda ................................................................. 10
7. Herencia simple: un estudiante hereda las características de una persona ......................... 14
8. Herencia simple: un automóvil es un vehículo, un camión también ..................................... 15
9. Herencia simple: un médico y un obrero son asalariados, un asalariado es una persona .. 18
10. Especialización: el hijo tiene dos apellidos, el primero del padre y el segundo de la madre
20
11. Cíclica: un empleado puede ser jefe de otro empleado .................................................... 21
12. Problema del diamante ........................................................................................................ 24
13. Caso 1: Un atributo public .................................................................................................... 25
14. Caso 2: un atributo protected .............................................................................................. 25
15. Caso 3: un atributo private ................................................................................................... 26
16. Caso 4: Probando herencia pública, protegida y privada .................................................. 26
17. Caso: superclase con nivel de acceso private ..................................................................... 27
18. Caso: superclase con nivel de acceso protected ................................................................ 28
19. Caso 5: un almacén tiene cuenta y puede estar asociado a cliente ................................. 29
Referencias .......................................................................................................................................... 33
3|Página
Relaciones entre clases en C++
Abraham Sopla Maslucán
Protected: se puede acceder a un atributo o método de una clase A directamente desde esta
clase A y desde sus subclases B, C, D, etc.
Public: se puede acceder a los atributos o métodos de una clase A directamente desde la misma
clase A, subclase B, C, D, etc., además desde otras clases externas, incluido el archivo que tiene
la clase main, mediante el objeto respectivo A.
Circulo.h
#include<iostream>
class Circulo {
private:
const double pi = 3.1416;
double radio;
public:
Circulo(){}
Circulo(double _radio) {
radio = _radio;
}
double hallaDiametro()
{
return 2 * radio;
}
double hallaArea()
{
return pi*pow(radio,2);
}
double hallaLongitudCircunferencia()
{
return 2 * pi*radio;
4|Página
Relaciones entre clases en C++
Abraham Sopla Maslucán
}
};
Principal
#include<iostream>
#include<string>
#include"Circulo.h"
using namespace std;
void main()
{
double radio;
cout << "Calculo del area del cuadrado " << endl;
cout << "Valor del radio: ";
cin >> radio;
//Dependencia de uso
Circulo *circulo = new Circulo(radio);
//Cálculos
cout<<"Diametro: "<<circulo->hallaDiametro()<<endl;
cout<<"Longitud de la circunferencia: "<<circulo-
>hallaLongitudCircunferencia()<<endl;
cout<<"Area del circulo: "<<circulo->hallaArea()<<endl;
system("pause");
}
class Clase1 {
public:
void metodo(Clase2* objeto2) {
}
};
Clase2.h
#include "Clase1.h"
class Clase2 {
public:
void metodo(Clase1* objeto1) {
}
};
5|Página
Relaciones entre clases en C++
Abraham Sopla Maslucán
private:
string energia;
public:
Parlante() {}
~Parlante() {}
void setEnergia(string _energia) { energia = _energia; }
string getEnergia() { return energia; }
//Comportamientos
void muestraDatos()
{
cout << "Energía que soporta en Watts: " << energia << endl;
}
};
Laptop.h
#include<iostream>
#include<string>
#include"Parlante.h"
using namespace std;
class Laptop {
private:
string marca="HP";
Parlante *parlante;
public:
//Crear objeto Laptop sin asignarle un objeto de parlante
Laptop() {
}
//Crear objeto Laptop asignándole un objeto de parlante
//Para ello el objeto parlante debe prepararse
Laptop(Parlante *_parlante)
{
parlante = _parlante; //asignamos la dirección del objeto parlante
}
~Laptop() {
}
//Seters y getetrs
//Crear objeto Laptop asignándole un objeto de parlante mediante set
void setParlante(Parlante *_parlante)
{
parlante = _parlante;
}
Parlante* getParlante()
{
return parlante;
}
//Comportamientos
void muestraDatos()
{
cout << "Marca de la Laptop: " << marca << " Energía del parlante: "
<< parlante->getEnergia() << endl;
}
};
Prueba.cpp
#include<iostream>
6|Página
Relaciones entre clases en C++
Abraham Sopla Maslucán
#include<string>
#include "Laptop.h"
using namespace std;
void main()
{
Laptop *laptop = new Laptop();
Parlante *parlante = new Parlante();
Microprocesador.h
#include<iostream>
using namespace std;
class Microprocesador
{
private:
int velocidad;
public:
Microprocesador()
{
}
~Microprocesador()
{
}
};
Laptop.h
//Composicion: Una laptop tiene un mricroprocesador
#include<iostream>
#include"Microprocesador.h"
using namespace std;
class Laptop {
private:
7|Página
Relaciones entre clases en C++
Abraham Sopla Maslucán
string marca="Toshiba";
Microprocesador *micro;
public:
Laptop() {
micro = new Microprocesador();
micro = NULL;
//Lo que sea que el constructor haga
}
~Laptop() {
//Lo que sea que el destructor haga
delete micro;
}
}
//Comportamientos
void muestraDatos()
{
cout << "Velocidad del microprocesador: " << velocidad << endl;
}
};
Laptop.h
//Una laptop TIENE microprocesador
#include<iostream>
#include<string>
#include"Microprocesador.h"
using namespace std;
class Laptop {
string marca="HP";
Microprocesador *microprocesador;
public:
Laptop() {
microprocesador = new Microprocesador();
}
~Laptop() {
delete microprocesador;
microprocesador = NULL;
}
//Metodo importante para acceder a un objeto microprocesador
//Por principio de comprosicion
//No se puede acceder a un objeto microprocesador si no es mediante el objeto
Laptop
8|Página
Relaciones entre clases en C++
Abraham Sopla Maslucán
Microprocesador *getMicroprocesador()
{
return microprocesador;
}
//Comportamientos
void muestraDatos()
{
cout << "Marca de la Laptop: " << marca << " Velocidad del
microprocesador: " << microprocesador->getVelocidad() << endl;
}
};
Prueba.cpp
#include<iostream>
#include<string>
#include "Laptop.h"
using namespace std;
void main()
{
Laptop *laptop = new Laptop();
//Obteniendo la dirección del objeto microprocesador con laptop-
>getMicroprocesador()
//Destruir laptop
delete laptop;
laptop = NULL;
Tarjeta.h
#include<string>
#include<iostream>
using namespace std;
class Tarjeta
{
private:
string banco;
long numero;
9|Página
Relaciones entre clases en C++
Abraham Sopla Maslucán
public:
Tarjeta()
{
}
~Tarjeta()
{
}
};
Cliente.h
//El cliente usa tarjeta de crédito
#include<string>
#include"Tarjeta.h"
using namespace std;
public class Cliente {
private:
int dni;
string nombre;
Tarjeta *otarjeta;
public:
Cliente() {
//Lo que sea que el constructor haga
}
~Cliente() {
//Lo que sea que el destructor haga
}
//Aquí se da la agregación, en realidad se da en una relación de 1 a
muchos
//Una agregación de uno a uno es una asociación
void setTarjeta(Tarjeta *tarjeta) {
otarjeta=new Tarjeta();
otarjeta = tarjeta;
}
// Más código aquí
}
10 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
//Comportamiento
void muestraContacto()
{
cout << "Nombre: " << nombre << " Edad: " << edad << " Distrito: "
<< distrito << " Universidad: " << universidad << endl;
}
};
Agenda.h
Aquí se gestionan los objetos
#pragma once
#include<iostream>
#include<string>
#include "Contacto.h"
using namespace std;
class Agenda{
private:
int tamanio;
Contacto **listaContacto;
public:
Agenda() {
tamanio = 0;
listaContacto = NULL;
}
void agregaContacto(Contacto *_contacto)
{ //Realmente aquí se agregan los contactos a la agenda
Contacto **listaTemporal = new Contacto*[tamanio+1];
for (int i = 0; i < tamanio; i++)
{
listaTemporal[i] = listaContacto[i];
}
listaTemporal[tamanio] = _contacto;
tamanio += 1;
delete[] listaContacto;
listaContacto = listaTemporal;
}
void leeDatos()
{ //variables temporales
string tNombre;
int tEdad;
string tDistrito;
string tUniversidad;
cout << "Nombre : " << endl; cin >> tNombre;
11 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
Principal.cpp
Se usa un menú para llamar a cada uno de los métodos de la clase contenedora
#pragma once
#include<iostream>
#include<string>
#include"Agenda.h"
using namespace std;
void main()
{
int opcion;
Agenda oa;
while (true)
{
cout << "1 agregar un dato "<<endl;
cout << "2 mostrar la lista de datos "<<endl;
cout << "3 mostrar la lista de estudiante de 15 a 19 años " << endl;
cout << "6 salir ... "<<endl;
cin >> opcion;
switch (opcion)
{
case 1:
oa.leeDatos();
break;
case 2:
oa.muestraListaContactos();
break;
case 3:
oa.muestraListaDe15a19();
break;
default:
exit(0);
}
12 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
}
system("pause");
}
13 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
La generalización es un tipo de relación entre clases que permite compartir información entre dos
entidades para evitar la redundancia. El proceso que se sigue para implementar la generalización
se denomina herencia. El proceso inverso de la generalización por el cual se definen nuevas clases
a partir de otras ya existentes se denomina especialización, al proceso de implementación se le
denomina herencia múltiple.
Por ejemplo: las lavadoras, refrigeradoras, hornos de microondas, tostadoras, lavavajillas, etc.,
tienen características algunas características iguales, es decir todos son electrodomésticos. La
clase animal se divide en anfibios, mamíferos, insectos, pájaros, etc., y la clase vehículo en carros,
motos, camiones, buses, etc.
14 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
}
~Persona() {}
void muestraPersona()
{
cout << "Nombre: " << nombre << endl;
cout << "Edad: " << edad << endl;
};
Estudiante.h
#pragma once
#include<iostream>
#include<string>
#include "Persona.h"
using namespace std;
class Estudiante :public Persona {
private:
string codigo;
double nota;
public:
Estudiante() {}
Estudiante(string _nombre, int _edad, string _codigo, double
_nota):Persona(_nombre, _edad) {
codigo = _codigo;
nota = _nota;
}
~Estudiante() {}
void muestraEstudiante()
{
muestraPersona();
cout << "Codigo: " << codigo << endl;
cout << "Nota : " << nota << endl;
}
};
Principal.cpp
#pragma once
#include<iostream>
#include<string>
#include "Estudiante.h"
using namespace std;
void main()
{
//Estudiante oe1("Juan Perez", 16, "2018205", 16.8);
Estudiante *oe1;
oe1= new Estudiante("Juan Perez", 16, "2018205", 16.8);
oe1->muestraEstudiante();
system("pause");
}
15 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
#include <iostream>
using namespace std;
//Definición de clase base
class Vehiculo
{
private:
int canRuedas;
int capPasajeros;
public:
void setCanRuedas(int num)
{
this->canRuedas = num;
}
int getCanRuedas()
{
return this->canRuedas;
}
16 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
void Mostrar(void)
{
cout << "Ruedas: " << this->getCanRuedas() << endl;
cout << "Pasajeros: " << this->setCapPasajeros() << endl;
cout << "Capacidad de carga en pies cúbicos: " << this->getCarga()
<< endl;
}
};
/*
* Este enumerador sirve para definir diferentes tipos de automóvil
*/
enum tipo { deportivo, berlina, turismo };
void Mostrar(void)
{
cout << "Ruedas: " << this->getCanRuedas() << endl;
cout << "Pasajeros: " << this->setCapPasajeros() << endl;
cout << "Tipo: ";
switch (this->getTipo())
{
case deportivo:
cout << "deportivo";
break;
case berlina:
cout << "berlina";
break;
case turismo:
cout << "turismo";
}
cout << endl;
}
};
int main(void)
{
Camion Camion1;
Camion Camion2;
Automovil Automovil1;
Camion1.setCanRuedas(18);
Camion1.setCapPasajeros(2);
17 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
Camion1.setCarga(3200);
Camion2.setCanRuedas(6);
Camion2.setCapPasajeros(3);
Camion2.setCarga(1200);
Camion1.Mostrar();
cout << endl;
Camion2.Mostrar();
cout << endl;
Automovil1.setCanRuedas(4);
Automovil1.setCapPasajeros(6);
Automovil1.setTipo(berlina);
Automovil1.Mostrar();
system("pause");
return 0;
}
#include <iostream>
#include <string>
using namespace std;
//Definicion de la clase Persona
class Persona
{
protected:
string nombre;
int edad;
public:
Persona(string _nombre, int _edad) {
nombre=_nombre;
edad = _edad;
}
void setNombre(string _nom) { nombre=_nom; }
void muestraNombre(void) { cout << "Nombre: " << nombre << endl; }
18 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
};
19 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
ob1.muestraEdad();
ob1.muestraSueldo();
ob1.muestraCargo();
cout << "********************" << endl;
Medico med2;
med2.muestraNombre();
med2.muestraEdad();
med2.muestraSueldo();
med2.muestraCantPacientes();
cin.get();
return 0;
}
class Papa {
protected:
string apellidoPapa;
double edad;
public:
void muestraApellidoPapa() {
cout << "Apellido Paterno: " << apellidoPapa <<endl;
}
20 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
};
class Mama {
protected:
string apellidoMama;
public:
void muestraApellidoMama() {
cout << "Apellido materno: "<<apellidoMama <<endl; }
};
int main()
{
Hijo *hijo1=new Hijo("Jose Manuel", "Mori", "Romero"); // proveida por
Derivada.
hijo1->imprimeNombre(); //desde hijo
hijo1->muestraApellidoPapa(); // desde Papa
hijo1->muestraApellidoMama(); // desde Mama
cin.get();
return 0;
}
Empleado.h Empleado
*
#pragma once
#include<string>
#include<iostream>
21 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
Empleado(string _nombre) {
nombre = _nombre;
}
Empleado(string nombre, Empleado *_jefe) {
this->nombre = nombre;
jefe = _jefe;
}
//Seter y Geter
void setNombre(string nombre) {
this->nombre = nombre;
}
string getNombre()
{
return nombre;
}
void setJefe(Empleado *_jefe)
{
jefe=_jefe;
}
Empleado * getJefe()
{
return jefe;
}
//Comportamiento
void imprimeJefe()
{
cout << "Empleado : "<<nombre <<" - No tiene jefe, puede ser
jefe"<<endl;
}
void imprimeEmpleado()
{
cout << "Empleado : " << nombre << " su jefe es: "<<jefe->getNombre()
<< endl;
}
};
Principal.cpp
#pragma once
#include<string>
#include<iostream>
#include "Empleado.h"
jefe1->imprimeJefe();
jefe2->imprimeJefe();
empleado3->imprimeEmpleado();
empleado4->imprimeEmpleado();
system("pause");
22 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
23 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
Anexos:
12. Problema del diamante
El problema del diamante está representado en un conjunto de relaciones de herencia entre
cases donde: Una clase D hereda de B y C (Herencia múltiple), y las clases B y C heredan de A.
1
Tomado de https://es.stackoverflow.com/questions/104165/por-qu%C3%A9-la-herencia-
m%C3%BAltiple-no-se-admite-en-java/104171
24 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
//Heredar .
class Hijo : public Papa {
public:
void setApellido(string _apellidoPapa)
{
apellidoPapa = _apellidoPapa;
}
};
int main()
{
Hijo hijo;
hijo.setApellido("Mori"); // proveída por Derivada.
//además estoy accediendo
al apellido directamente mediante el método
// desde Papa
hijo.apellidoPapa = "Asenjo";//Accediendo directamente al atributo
apellidoPapa
hijo.muestraApellidoPapa();
system("pause");
return 0;
}
//Heredar .
class Hijo : public Papa {
public:
void setApellido(string _apellidoPapa)
{
apellidoPapa = _apellidoPapa;
}
};
25 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
int main()
{
Hijo hijo;
hijo.setApellido("Mori"); // proveida por Derivada.
//ademas estoy accediendo
al apellido directamente mediante el metodo
hijo.muestraApellidoPapa(); // desde Papa
system("pause");
return 0;
}
string getApellidoPapa()
{
return apellidoPapa;
}
void muestraApellidoPapa() {
cout << "Apellido: " << apellidoPapa << "\n";
}
};
//Heredar .
class Hijo : public Papa {
public:
void setApellido(string _apellidoPapa)
{
setApellidoPapa(_apellidoPapa);
}
};
int main()
{
Hijo hijo;
hijo.setApellido("Mori"); // proveída por Derivada.
//además estoy accediendo al apellido
directamente mediante el método
hijo.muestraApellidoPapa(); // desde Papa
system("pause");
return 0;
}
26 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
Primero: deje el nivel de acceso de la clase base en públic y cambie los niveles de acceso
del atributo apellidoPapa entre protected, public y private. También debe observar el
comportamiento en la función principal main.
Segundo: deje el nivel de acceso de la clase base en protected y cambie los niveles de
acceso del atributo apellidoPapa entre protected, public y private. También debe
observar el comportamiento en la función principal main.
Tercero: deje el nivel de acceso de la clase base en private y cambie los niveles de acceso
del atributo apellidoPapa entre protected, public y private. También debe observar el
comportamiento en la función principal main.
// Un ejemplo de herencia
#include <iostream>
#include<string>
using namespace std;
class Papa {
protected:
string apellidoPapa;
public:
void muestraApellidoPapa() {
cout << "Apellido: " << apellidoPapa << "\n";
}
};
//Heredar .
class Hijo : public Papa {
public:
void setApellido(string _apellidoPapa)
{
apellidoPapa = _apellidoPapa;
}
};
int main()
{
Hijo hijo;
hijo.setApellido("Mori"); // proveida por Derivada.
//ademas estoy accediendo
al apellido directamente mediante el metodo
hijo.muestraApellidoPapa(); // desde Papa
system("pause");
return 0;
}
"Cuando una clase base es heredada como 'private' sus miembros públicos se convierten en
miembros privados en la clase derivada."
En el siguiente código: class Derivada : private Base { … }; tenemos que cambiar private
a public para que el código compile sin problemas
// Este programa no compilara.
27 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
#include <iostream>
using namespace std;
class Base {
private:
int a, b;
public:
void setAB(int _a, int _b) { a = _a; b = _b; }
void mostrarAB() { cout << a << " -- " << b << "\n"; }
};
int main()
{
Derivada obj(30);
obj.setAB(10, 20); // Error, no se puede acceder _i set()
obj.mostrarAB(); // Error, no se puede acceder _i mostrar()
obj.mostrarC(); // Error, no se puede acceder _i mostrar()
cin.get();
return 0;
}
28 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
int main()
{
Derivada obj;
obj.setC();
obj.mostrarC();
cin.get();
return 0;
}
Cuenta.h
#include<iostream>
#include<string>
using namespace std;
class Cuenta {
private:
int nroCuenta;
public:
Cuenta() {} //No se puede asignar valores a los atributos
~Cuenta() {}
29 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
Cliente.h
#include<iostream>
#include<string>
using namespace std;
class Cliente {
private:
string nombre;
public:
Cliente() {}
Cliente(string _nombre) {
nombre = _nombre;
}
~Cliente() {}
//Comportamiento
void muestraCliente()
{
cout << "Nombre: " << nombre << endl;
}
};
Almacen.h
//En el almacen siempre registramos cuenta aunque no cliente o los dos juntos
//Podemos crear una lista de clientes
//Podemos crear una lista de cuentas
//Podemos crear una lista de almacenes
//Siempre que se crea un almacen se crea una cuenta si o si
//Siempre que se crea un almacen se crea una cuenta si o si, y si quieres puedes
incluir un cliente
//Cuando borras un almacen se borra una cuenta pero no el cliente
#include<iostream>
#include<string>
#include"Cuenta.h"
#include"Cliente.h"
using namespace std;
class Almacen {
private:
Cuenta *cuenta;
Cliente *cliente;
public:
//Acceder a una cuenta con get
Almacen() {
cuenta = new Cuenta();
}
//Por si quiera agregar los atributos objeto al instante de crear almacen
//En los tres constructores asignamos una direcion de un objeto cuenta al
atributo cuenta
30 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
//Por si quiera asignar objetos a los dos atributos a la vez mediante seter
y geters
void setCuentaCliente(Cuenta *_cuenta, Cliente *_cliente)
{
cuenta = _cuenta;
cliente = _cliente;
}
//Comportamientos
void muestraDatos()
{
cout << "Cuenta : " << cuenta->getNroCuenta() << " Nombre: "<<cliente-
>getNombre()<<endl;
}
};
Principal.cpp
//En el almacen siempre registramos cuenta aunque no cliente o los dos juntos
//Podemos crear una lista de clientes
//Podemos crear una lista de cuentas
//Podemos crear una lista de almacenes
//Siempre que se crea un almacen se crea una cuenta si o si
//Siempre que se crea un almacen se crea una cuenta si o si, y si quieres puedes
incluir un cliente
//Cuando borras un almacen se borra una cuenta pero no el cliente
#include<iostream>
#include<string>
31 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
#include "Almacen.h"
32 | P á g i n a
Relaciones entre clases en C++
Abraham Sopla Maslucán
Referencias
Deitel, P. J. & Deitel, H. M. (2008). Como programar en Java, 6ta edición. Pearson
Educación: México.
Laza, R. y García, B. (2008). Metodología y tecnología de la programación. Pearson
Educación: México.
Mañas, J. A. (2010). Java vademécum. Departamento de Ingeniería de Sistemas
Telemáticos, Universidad Politécnica Madrid, España.
Moltó, G. (S/A). Conceptos de java para estructuras de datos. Escuela Técnica
Superior de Ingeniería Informática, Universidad Politécnica de Valencia,
España.
Cibertec. (S/A). Algoritmos y estructura de datos – TI. Cibertec, Perú.
Wikibooks (2018) Programación en C++/Herencia. Recuperado el 10 de setiembre
de 2018 de
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/H
erencia
33 | P á g i n a