Trabajando con dominios de difusión en redes WAN

Rutear paquetes entre dominios de difusión de distintas redes

¿Qué es un dominio de difusión?

Dominios de difusión en redes domésticas LAN

Por lo general, las redes domésticas interconectan una amplia variedad de dispositivos finales, como computadoras portátiles, computadoras de escritorio, tablet,  smartphone, televisores inteligentes y reproductores de medios de red que cumplen con los requisitos de la Digital Living Network Alliance (DLNA), como las consolas Xbox 360 o PlayStation y entre otros equipos de demótica.
Por lo general, todos estos dispositivos finales están conectados a una red LAN y se comunican todos entre sí, formando un dominio de difusión único para todos los equipos presentes. Normalmente hay un router que comunica la red LAN a internet.

Los routers domésticos o de oficina cumplen cuatro funciones:
  1. Router: reenvía y recibe paquetes de datos desde Internet.
  2. Conectividad: se conecta al switch y se integra a la red como puerta de enlace a internet.
  3. Punto de acceso inalámbrico: consta de un transmisor de radio que puede conectar dispositivos finales en forma inalámbrica.
  4. Firewall: protege el tráfico saliente y restringe el tráfico entrante desde Internet.

Dominios de difusión en redes empresariales, Intranet, WAN

En las redes empresariales más grandes es necesario instalar router para comunicar muchas redes, con una gran cantidad de dispositivos distribuidos en distintas redes y mucho más tráfico, los router se incorporan como dispositivos independientes y autónomos que proporcionan un servicio dedicado. Los dispositivos finales, como las computadoras portátiles y de escritorio, se conectan a los switches de red mediante conexiones por cable. Para enviar paquetes más allá de la red local LAN, los switches de red se conectan a routers de red y los router se conectan a equipos ADSL proporcionados por los ISP y el resultado final es permitir comunicación entre redes. En una red de redes empresariales es muy importante la función de los firewalls.

Para saber más de firewalls visitar los siguientes enlaces:

Para saber más de dominios de difusión visitar las siguientes publicaciones:

 Función de los sistemas operativos de redes

Cada dispositivo es muy diferente en lo que respecta al hardware, el uso y las capacidades. Sin embargo, en todos los casos, el sistema operativo es lo que permite que el hardware funcione, los sistemas operativos de red cumplen una función muy importante en la configuración de la red lógica y de la instalación de los driver que hacen funcionar el hardware de comunicaciones.

Básicamente los sistemas operativos de red cumplen tres funciones:
  1. Configurar la red lógica
  2. Cargar los driver y protocolos de la red
  3. Cargar los programas, software de soporte a la red. Ejemplo: cortafuegos
La correcta configuración de los sistemas operativos de redes permitirá a las redes corporativas conectar sus redes distribuidas.
Sistema operativo Internetwork (IOS, Internetwork Operating System) es un término genérico para la colección de sistemas operativos de red que se utilizan en los router para interconectar redes. Algunos sistemas operativos de redes cargan programas que brindan servicios, por ejemplo: servidores de páginas WEB, servidores de bases de datos, etc. Los sistemas operativos que brindan servicios y recursos se llaman servidores de red.

Relación que hay entre broadcast de red lógica y broadcast de red física

Los paquetes de broadcast de red lógica contienen una dirección IP de destino que contiene solo números uno (1) en la porción de host. Esta numeración en la dirección de broadcast significa que todos los hosts de esa red local (dominio de broadcast) recibirán y procesarán el paquete. Muchos protocolos de red, como DHCP y el protocolo de resolución de direcciones (ARP), ARP utiliza los broadcasts para asignar direcciones de Capa 2 física a direcciones de Capa 3 de red lógica. ARP es un protocolo que arma tablas para relacionar números IP con números MAC, los números MAC arman la red física y los números IP arman la red lógica.
No es posible hacer en IPv4 broadcast entre redes, solamente es posible hacer broadcast en redes LAN.

Para realizar comunicaciones entre redes hay que usar estas dos técnicas:
  1. unicast, una dirección destino se corresponde con una dirección de origen, por ejemplo una máquina se comunica con un servidor. Los router permiten simular la función unicast con tablas de rutas.
  2. anycast también hay una asociación de una dirección destino a varias direcciones de origen. La diferencia está en que se selecciona una dirección destino para ser la destinataria de la información de las computadoras origen, por ejemplo cuando varias máquinas se quieren conectar a un servidor. Los router permiten simular la función anycast con tablas de rutas.
En IPv4 la única forma de simular unicast, anycast y broadcast entre redes es configurando en los sistemas operativos de red de los router tablas de rutas. Las tablas de rutas son una forma de educar o enseñarle a los router los caminos que deben tomar los paquete para llegar a una red.  El responsable de crear las tablas de ruteo es el administrador de la red, en última instancia siempre es un humano quien debe enseñar, educar, a un router.
En IPv4 no está permitido hacer broadcast entre redes, inundar de paquetes una red LAN está permitido pero permitir que paquetes de inundación broadcast de una red inunden otra red es una situación muy peligrosa e insegura. Se aconseja usar la técnica de unicast para comunicar dos redes con el protocolo IPv4.

Ataque DDoS distribuido y anycast

El uso de anycast en Internet ayuda a contener un ataque distribuido de denegación de servicio, DDoS,  y reducir su efectividad. Es una de las razones por las que se propuso el uso de anycast en DNS. Dado que el tráfico es enrutado al nodo más cercano y el atacante usualmente no puede controlar esto, se distribuye el ataque entre los servidores cercanos. Esto a menudo supone que no todos los servidores sufren el ataque y es una razón importante para usar anycast.

Dominios de difusión, broadcast, en la red física

Una dirección lógica IP de broadcast para una red requiere una dirección física MAC de broadcast correspondiente en la trama de Ethernet. En las redes Ethernet, la dirección MAC de broadcast está compuesta por 48 unos, que se muestran como el valor hexadecimal FF-FF-FF-FF-FF-FF. El protocolo ARP es el encargado de llevar en tablas la correspondencia entre los números IP y números MAC sean o no de broadcast.

Números MAC

Los números MAC tienen la forma xx-xx-xx-xx-xx-xx, están compuesto por 6 dígitos de 8 bits, en total son 48 bit e identifican el equipo físico de transmisión. El número MAC debe ser único en la red física, muchas veces es necesario clonar un número MAC si se quiere que un equipo de transmisión escuche la comunicación de otro. Los software sniffer, espías, clonan el número MAC de una computadora para atrapar los paquetes entrantes y salientes. Es muy fácil clonar un número MAC y espiar una red física, cables o medios de transmisión, por tal motivo es muy importante cifrar, codificar, encriptar las comunicaciones en la red. Los dominios de colisión están formados por la porción de cable, medio de comunicación, donde los números MAC pueden colisionar. Los números MAC son parte del encabezado de una trama, es por tal motivo que se habla de colisión de tramas.

Resumen de dominio de difusión

El dominio de difusión es el conjunto de todos los dispositivos de comunicaciones en una red LAN que reciben tramas de broadcast que se originen en cualquier dispositivo del conjunto de equipos. Los conjuntos de broadcast generalmente están limitados por enrutadores, dado que los routers no envían tramas de broadcast, por definición un router administra redes y separa en dominios de difusión. Para que un router traslade paquetes entre redes y dominios de difusión hay que crear tablas de ruteos entre redes.
Un dominio de difusión (broadcast domain) es el área lógica en una red de computadoras en la que cualquier computadora conectada a la red puede transmitir directamente a cualquier otra computadora en el dominio sin precisar ningún dispositivo de encaminamiento, puerta de enlace, dado que comparten la misma subred, dirección de puerta de enlace y están en la misma red de área local (LAN) virtual o VLAN (predeterminada o instalada).
Ejemplo:
•    la dirección IP 192.168.2.5/24 tiene como dirección de broadcast el IP 192.168.2.255
•    la dirección IP 192.168.5.40/25 tiene como dirección de broadcast el IP 192.168.5.127
•    la dirección IP 192.168.8.140/25 tiene como dirección de broadcast el IP 192.168.8.255
La dirección de broadcast lógica queda definida por la máscara de red

Conclusión

Cuando se hace un ping de difusión a la IP broadcast definida por la máscara de red el paquete de datos queda confinado a la sub red definida en la máscara de red, es decir el paquete de datos no se difunde a otra red o subred. El motivo de la restricción está fundamentado en que las subredes se definen en el octeto de las computadoras y no en los octetos de la red según lo define la máscara de red. El conjunto de computadoras alcanzadas por el paquete de broadcast enviado por el comando ping se llama dominio de difusión. Al dominio de difusión se le puede hacer unicast, anycast y broadcast.
Para salvar la restricción y poder comunicar dos redes hay que instalar un router y configurar las tablas de rutas por un administrador de la red.

Práctica de laboratorio



Configurar la red lógica en los sistemas operativos de red de las computadoras y router. Dada la siguiente red de redes con cuatro dominios de difusión en diferentes redes configurar los rutes y computadoras para que se cumplan las siguientes reglas

Reglas de ruteo para que se cumpla:
1.    Todos los dominios de difusión pueden hacer ping al dominio de difusión 1
2.    El dominio de difusión 2 no puede hacer ping a los dominios de difusión 3 y 4
3.    El dominio de difusión 3 puede hacer ping al dominio de difusión 4
4.    No es posible hacer ping a los equipos del ISP (Proveedor de Servicios de Internet)

Edificio de casa central

  •     PC1
    •     IP=192.168.7.2/24; PE=192.168.7.1
  •     Servidor0
    •     IP=192.168.6.2/24; PE=192.168.6.1
  •     Router2
    •     Placas: Fa0/0 IP=192.168.6.1/24; Fa1/0 IP=192.168.4.2/24; Fa6/0 IP=192.168.5.1/24
    •     Tabla de rutas: 192.168.1.0/24 vía 192.168.4.1; 192.168.2.0/24 vía 192.168.4.1; 192.168.3.0/24 vía 192.168.4.1; 192.168.7.0/24 vía 192.168.5.2
  •     Router3
    •     Placas: Fa0/0 IP=192.168.7.1/24; Fa1/0 IP=192.168.5.2/24
    •     Tabla de rutas: 192.168.6.0/24 via 192.168.5.1
  •     Router0
    •     Placas: Fa0/0 IP=192.168.4.1/24; Fa6/0 IP=192.168.1.2/24
    •     Tabla de rutas: 192.168.2.0/24 vía 192.168.2.1; 192.168.3.0/24 vía 192.168.3.1; 192.168.6.0/24 vía 192.168.4.2

Edificio de trabajo remoto

  •     Router1
    •     Placas: Fa0/0 IP=192.168.2.1/24; Fa1/0 IP=192.168.3.3/24; Fa6/0 IP=192.168.1.1/24
    •     Tabla de rutas: 192.168.1.0/24 vía 192.168.4.1; 192.168.2.0/24 vía 192.168.4.1; 192.168.3.0/24 vía 192.168.4.1; 192.168.7.0/24 vía 192.168.5.2
  •     PC2
    •     IP=192.168.2.2/24; PE=192.168.2.1
  •     PC0
    • o    IP=192.168.3.2/24; PE=192.168.3.1

Proveedor de Servicios de Internet - PSI

  •     PC-PSI-01
    •     IP=Definida por DHCP; PE=No determinada
  •     Servidor-ISP-DHCP
    •     IP=192.168.1.1/24; PE=No determinada
    •     DHCP=Si, IP de inicio 192.168.1.50, número de usuarios 50

Para saber más de dominios de difusión visitar las siguientes publicaciones:


¿Cómo usar el componente JTable?

Ejemplo de uso del componente JTable con el IDE JDeveloper 11g 


Para entender el componente JTable se deben estudiar las siguientes capas de modelos

Modelos del componente JTable: 

  • Vista 
    • Datos 
      • Selección 
      • Edición 

Para cada modelo hay que crear una clase e implementar los métodos necesarios para operara con los datos y las relaciones de cada modelo. Existen modelos para filas y modelos para columnas y modelos para celdas, en este ejemplo se explicarán los modelos para operar para filas. 
Se deberán crear los respectivos modelos para celdas si se quiere trabajar con celdas y también se deberán crear para cada columna los modelos correspondientes si se quiere trabajar con las columnas de un JTable de Java. Por ejemplo: el modelo de edición es muy distinto para filas que para columnas y celdas.

Reutilización 


El componente JTable reutiliza e implementa el modelo del componente JList “ListSelectionListener”. Se recomienda practicar y estudiar primero el componente JList de Java y en segundo lugar practicar y estudiar el componente JTable. 

Para saber más sobre el componente JList ver la siguiente publicación: 


https://carlosprivitera.blogspot.com.ar/2017/05/ejemplo-del-componente-jlist-de-java.html

Para saber más sobre el componente JTable visitar los siguientes sitios: 


https://docs.oracle.com/javase/tutorial/uiswing/components/table.html
https://docs.oracle.com/javase/7/docs/api/javax/swing/JTable.html
https://docs.oracle.com/javase/8/docs/api/javax/swing/JTable.AccessibleJTable.html

Arquitectura del componente JTable de Java


 Nota: 


En esta publicación se hará un estudio detallado de los modelos de datos, selección y edición para las filas del componente JTable, Se dejará para otra publicación el estudio de los modelos de datos, selección y edición para las columnas y celdas del componente JTable de Java.   

Arquitectura para trabajar con el componente JTable de Java en una ambiente de bases de datos



Arquitectura de clases para los modelos vista, datos, selección y edición


 Vista Swing para la vista del componente JTable


Generador de contenidos para redes sociales

Herramienta para generar contenido web

Los juegos de desafíos son como un imán para los usuarios de las redes sociales, los administradores de redes sociales les encanta estimular la participación de los usuarios web.
Java es un lenguaje de propósito generar y excelente herramienta para construir un programa que automatice la generación de contenido web.

Java como constructor de herramientas que automaticen la generación de contenido para la web


Ejemplo 1: la imagen tiene un clásico problema donde hay que encontrar los valores correctos para x e y




Ejemplo 2: El siguiente ejercicio agrega una complejidad más, hay que calcular los valores faltantes



Ejemplo 3: Este ejemplo es de mayor complejidad, es necesario encontrar el valor de las letras para que se cumplan los valores indicados



Programa generador de contenido




Descargar el desarrollo del producto software realizado en JDeveloper 11g de Oracle y el archivo ejecutable JAR del siguiente enlace: Descargar desarrollo
Para ejecutar los archivos JAR debe tener la Maquina Virtual Java instalada en su computadora. Para descargar Java: https://java.com

Código fuente del desarrollo del producto software en Java

package client;

public class Main {
    public Main() {
        super();
    }
    private static VentanaPrincipal vp = new VentanaPrincipal();
    public static void main(String[] args) {
      vp.setDefaultCloseOperation(vp.EXIT_ON_CLOSE);
      vp.setLocationRelativeTo(null);
      vp.setVisible(true);
    }
}


package client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToolBar;

public class VentanaPrincipal extends JFrame {
    File file = new File(".");
    private String nl = System.getProperty("line.separator");
    private Imagenes imagenes = new Imagenes();
    private JPanel jPanel1 = new JPanel();
    private BorderLayout borderLayout1 = new BorderLayout();
    private GridLayout gridLayout1 = new GridLayout();
    private JLabel[][] jLabelMatriz = new JLabel[7][7];
    private Matriz matriz = null;
    private JToolBar jToolBar1 = new JToolBar();
    private JButton jButton2 = new JButton();
    private JButton jButton3 = new JButton();
    private JLabel jLabel1 = new JLabel();
    private JButton jButton4 = new JButton();
    private JCheckBox jCheckBox1 = new JCheckBox();
    private JCheckBox jCheckBox2 = new JCheckBox();
    private JCheckBox jCheckBox3 = new JCheckBox();

    public VentanaPrincipal() {
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void jbInit() throws Exception {
        this.getContentPane().setLayout(borderLayout1);
        this.setSize(new Dimension(448, 404));
        jPanel1.setLayout(gridLayout1);
        jPanel1.setBackground(new Color(255, 132, 0));
        gridLayout1.setRows(7);
        gridLayout1.setColumns(7);
        gridLayout1.setHgap(2);
        gridLayout1.setVgap(2);
        jButton2.setText("Nuevo");
        jButton2.setToolTipText("Genera un nuevo contenido");
        jButton2.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton2_actionPerformed(e);
                }
            });
        jButton3.setText("Guardar contenido");
        jButton3.setToolTipText("Pone el ejercicio en el porta papeles y guarda un archivo con la solución");
        jButton3.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton3_actionPerformed(e);
                }
            });
        jLabel1.setText("https://carlosprivitera.blogspot.com.ar/");
        jLabel1.setToolTipText("https://carlosprivitera.blogspot.com.ar/");
        jButton4.setText("Configurar");
        jButton4.setToolTipText("Permite elegir colores y tipo de letras");
        jButton4.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton4_actionPerformed(e);
                }
            });
        jCheckBox1.setText("Op");
        jCheckBox1.setToolTipText("Selecciona resolver las operaciones + -...");
        jCheckBox1.setSelected(true);
        jCheckBox2.setText("Div Mul");
        jCheckBox2.setToolTipText("Incluir división y multiplicación");
        jCheckBox2.setSelected(true);
        jCheckBox2.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jCheckBox2_actionPerformed(e);
                }
            });
        jCheckBox3.setText("xy");
        jCheckBox3.setToolTipText("Incluir variables x e y");
        jCheckBox3.setSelected(true);
        jCheckBox3.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jCheckBox3_actionPerformed(e);
                }
            });
        for(int x=0;x<7;x++){
            for(int y=0;y<7;y++){
                jLabelMatriz[x][y]=new JLabel();
                jLabelMatriz[x][y].setText(""+ x + "" + y);
                jLabelMatriz[x][y].setHorizontalAlignment(jLabelMatriz[x][y].CENTER);
                jLabelMatriz[x][y].setOpaque(true);
                jPanel1.add(jLabelMatriz[x][y], null);
            }
        }
        this.getContentPane().add(jPanel1, BorderLayout.CENTER);
        jToolBar1.add(jButton2, null);
        jToolBar1.add(jButton3, null);
        jToolBar1.add(jButton4, null);
        jToolBar1.add(jCheckBox1, null);
        jToolBar1.add(jCheckBox3, null);
        jToolBar1.add(jCheckBox2, null);
        this.getContentPane().add(jToolBar1, BorderLayout.NORTH);
        this.getContentPane().add(jLabel1, BorderLayout.SOUTH);
        this.setIconImage(imagenes.getImage());
        this.setTitle("Generador de contenido");
        matriz = new Matriz(jLabelMatriz);
        matriz.setS(this.jCheckBox2.isSelected(),this.jCheckBox3.isSelected());
    }

    private void jButton2_actionPerformed(ActionEvent e) {
        this.jButton2.setEnabled(false);
        matriz.setS(this.jCheckBox2.isSelected(),this.jCheckBox3.isSelected());
        this.jLabel1.setText("x="+matriz.getValorX()+" y=" + matriz.getValorY());
        this.jButton3.setEnabled(true);
        this.jButton2.setEnabled(true);
    }
    BufferedImage imagenPublicar = null;
    BufferedImage imagenPublicar2 = null;
    private void jButton3_actionPerformed(ActionEvent e) {
        jButton3.setEnabled(false);
        imagenPublicar = new BufferedImage(jPanel1.getWidth(), jPanel1.getHeight(), BufferedImage.TYPE_INT_RGB);
        imagenPublicar2 = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D)imagenPublicar.getGraphics();
        Graphics2D g2 = (Graphics2D)imagenPublicar2.getGraphics();
        paint(g2);
        try {
           SimpleDateFormat formateador = new SimpleDateFormat("dd-MM-yyyy HH_mm_ss");
           Date d = new Date();
           ImageIO.write(imagenPublicar2, "png", new File(formateador.format(d) + "Solucion.png"));
           matriz.borrarParaPublicar(jCheckBox1.isSelected(),jCheckBox3.isSelected());
           jPanel1.paint(g);
           ImageIO.write(imagenPublicar, "png", new File(formateador.format(d) + "Resolver.png"));
        } catch (IOException es) {
           String error = es.getMessage();
           JOptionPane.showMessageDialog(null, "Error de archivo: " + error);
        } catch (Exception es) {
            String error = es.getMessage();
            JOptionPane.showMessageDialog(null, "Error genérico de archivo: " + error);
        }   
        try {
          Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
          Transferable ponerEnPP = new Transferable(){
                        @Override
                        public Object getTransferData(DataFlavor flavor)
                                        throws UnsupportedFlavorException, IOException {
                                if (isDataFlavorSupported(flavor)) {
                                        return imagenPublicar;
                                }                     
                          throw new UnsupportedFlavorException(flavor);
                        }
                        @Override
                        public DataFlavor[] getTransferDataFlavors() {
                                // TODO Auto-generated method stub
                                return new DataFlavor[] { DataFlavor.imageFlavor };
                        }
                        @Override
                        public boolean isDataFlavorSupported(DataFlavor flavor) {
                                // TODO Auto-generated method stub
                                return DataFlavor.imageFlavor.equals(flavor);
                        }              
          };
          cb.setContents(ponerEnPP, null);
          } catch (Exception es) {
              String error = es.getMessage();
              JOptionPane.showMessageDialog(null, "Error genérico de portapapeles: " + error);
          }
        try {
            JOptionPane.showMessageDialog(this,
                "Se ha guardado en el portapapeles una imagen para publicar en redes sociales"+
                nl+
                "Se han guardado dos archivo en: " + file.getCanonicalPath()+
                nl+
                "Un archivo con la solución y otro con el desafio a publicar en redes sociales");
        } catch (IOException f) {
        }
    }
    Configurar configurar = new Configurar();
    private void jButton4_actionPerformed(ActionEvent e) {
       
        configurar.setLocationRelativeTo(null);
        configurar.setDefaultCloseOperation(configurar.HIDE_ON_CLOSE);
       
        configurar.jPanel1.setBackground(this.jPanel1.getBackground());
        configurar.jLabel1.setBackground(this.jLabelMatriz[0][0].getBackground());
        configurar.jLabel1.setFont(this.jLabelMatriz[0][0].getFont());
        configurar.jLabel1.setForeground(this.jLabelMatriz[0][0].getForeground());
        configurar.setVisible(true);
        if(configurar.getAplicar()==1){
            this.jPanel1.setBackground(configurar.jPanel1.getBackground());
            for(int x=0;x<7;x++){
                for(int y=0;y<7;y++){
                    jLabelMatriz[x][y].setBackground(configurar.jLabel1.getBackground()); //=new JLabel();
                    jLabelMatriz[x][y].setFont(configurar.jLabel1.getFont()); //setText(""+ x + "" + y);
                    jLabelMatriz[x][y].setForeground(configurar.jLabel1.getForeground()); //setHorizontalAlignment(jButton1[x][y].CENTER);
                }
            }
           
        }
        configurar.setAplicar(0);
    }

    private void jCheckBox3_actionPerformed(ActionEvent e) {
        this.jButton3.setEnabled(false);
    }

    private void jCheckBox2_actionPerformed(ActionEvent e) {
        this.jButton3.setEnabled(false);
    }
}


package client;

import javax.swing.JLabel;

public class Matriz {
    private Imagenes imagenes = new Imagenes();
    private EvaluarExpresion ee = new EvaluarExpresion();
    private String[][] s = new String[7][7];
    private JLabel[][]jb = new JLabel[7][7];
    private GenerarSimbolo g = new GenerarSimbolo();
    public Matriz(JLabel[][] jb){
        for(int x=0;x<7;x++){
            for(int y=0;y<7;y++){
                s[x][y]="";
            }
        }
        this.jb=jb;
    }
    public void borrarParaPublicar(boolean op1, boolean op2){
        if(op1==false){
            for(int x=0;x<7;x=x+1){
             //   jb[6][x].setText("");
                jb[x][6].setText("");
            }           
        }
        if(op2==false) {
            for(int x=0;x<5;x=x+1){
              for(int y=0;y<5;y=y+2){
                String letra = g.enteroALetra(s[x][y]);
                jb[x][y].setText(letra);
              }
            }
        }  
    }
    private int valorX = 0;
    private int valorY = 0;
    public void setS(boolean op1, boolean op2){
         int u=0;
        if(op2==true){
          valorX= Integer.parseInt(g.s(1));
          valorY= Integer.parseInt(g.s(1));
          u=4; //selecciona "123456789xy"
        }else{
          u=1; //selecciona "123456789"
        }
        int o = 2; //selecciona "+-*/"
        if(op1==false) {
            o=3; //selecciona "+-"
        }
        s[0][0]=g.s(u); s[0][1]=g.s(o);s[0][2]=g.s(u);s[0][3]=g.s(o);s[0][4]=g.s(u);s[0][5]="=";s[0][6]="0";
        s[1][0]=g.s(u); s[1][1]=g.s(o);s[1][2]=g.s(u);s[1][3]=g.s(o);s[1][4]=g.s(u);s[1][5]="=";s[1][6]="0";
        s[2][0]=g.s(u); s[2][1]=g.s(o);s[2][2]=g.s(u);s[2][3]=g.s(o);s[2][4]=g.s(u);s[2][5]="=";s[2][6]="0"; 
        s[3][0]=g.s(u); s[3][1]=g.s(o);s[3][2]=g.s(u);s[3][3]=g.s(o);s[3][4]=g.s(u);s[3][5]="=";s[3][6]="0";
        s[4][0]=g.s(u); s[4][1]=g.s(o);s[4][2]=g.s(u);s[4][3]=g.s(o);s[4][4]=g.s(u);s[4][5]="=";s[4][6]="0";
        s[5][0]=    ""; s[5][1]=    "";s[5][2]=    "";s[5][3]=    "";s[5][4]=    "";s[5][5]="=";s[5][6]= ""; 
        s[6][0]=   "0"; s[6][1]=    "";s[6][2]=   "0";s[6][3]=    "";s[6][4]=   "0";s[6][5]= "";s[6][6]="0"; 
        jb[5][0].setIcon(imagenes.getIcon());
        jb[5][2].setIcon(imagenes.getIcon());
        jb[5][4].setIcon(imagenes.getIcon());
        jb[5][1].setVisible(false);
        jb[6][1].setVisible(false);
        jb[5][3].setVisible(false);
        jb[6][3].setVisible(false);
        jb[6][5].setVisible(false);
        jb[5][6].setVisible(false);
        s[0][6]=ee.getResultado(s[0][0]+s[0][1]+s[0][2]+s[0][3]+s[0][4], valorX, valorY);
        s[1][6]=ee.getResultado(s[1][0]+s[1][1]+s[1][2]+s[1][3]+s[1][4], valorX, valorY);
        s[2][6]=ee.getResultado(s[2][0]+s[2][1]+s[2][2]+s[2][3]+s[2][4], valorX, valorY);
        s[3][6]=ee.getResultado(s[3][0]+s[3][1]+s[3][2]+s[3][3]+s[3][4], valorX, valorY);
        s[4][6]=ee.getResultado(s[4][0]+s[4][1]+s[4][2]+s[4][3]+s[4][4], valorX, valorY);

        s[6][0]=ee.getResultado(s[0][0]+"+"+s[1][0]+"+"+s[2][0]+"+"+s[3][0]+"+"+s[4][0], valorX, valorY);
        s[6][2]=ee.getResultado(s[0][2]+"+"+s[1][2]+"+"+s[2][2]+"+"+s[3][2]+"+"+s[4][2], valorX, valorY);
        s[6][4]=ee.getResultado(s[0][4]+"+"+s[1][4]+"+"+s[2][4]+"+"+s[3][4]+"+"+s[4][4], valorX, valorY);

        s[6][6]=ee.getResultado(s[0][0]+s[1][1]+s[2][2]+s[3][3]+s[4][4], valorX, valorY);
       
        for(int x=0;x<7;x++){
            for(int y=0;y<7;y++){
                jb[x][y].setText(s[x][y].toString());
            }
        }
    }

    public int getValorX() {
        return valorX;
    }

    public int getValorY() {
        return valorY;
    }
}


package client;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerListModel;
import javax.swing.SpinnerModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Configurar extends JDialog {
    private String vs[] =
     {"9","10","11","12","13","14","15","16","17","18","19","20","21","22",
      "23","24","25","26","27","28","29","30","31","32","33","34","35","36",
      "37","38","39","40","41","42","43","44","45","46","47","48"};
    private DefaultListModel dlm = new DefaultListModel();
    private SpinnerModel sm = new SpinnerListModel(vs);
    public JLabel jLabel1 = new JLabel();
    public JPanel jPanel1 = new JPanel();
    private JButton jButton1 = new JButton();
    private JButton jButton2 = new JButton();
    private JButton jButton3 = new JButton();
    private JList jList1 = new JList(dlm);
    private JSpinner jSpinner1 = new JSpinner(sm);
    private JScrollPane jScrollPane1 = new JScrollPane();
    private JButton jButton4 = new JButton();
    private JButton jButton5 = new JButton();
    private int aplicar = 0;

    public Configurar() {
        super();
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void jbInit() throws Exception {
        this.getContentPane().setLayout(null);
        this.setSize(new Dimension(466, 370));
        this.setTitle("Configurar");
        this.setResizable(false);
        this.setModal(true);
        jLabel1.setText("jLabel1");
        jLabel1.setBounds(new Rectangle(10, 40, 215, 110));
        jPanel1.setBounds(new Rectangle(220, 85, 235, 195));
        jPanel1.setLayout(null);
        jButton1.setText("Color de fondo");
        jButton1.setBounds(new Rectangle(15, 5, 210, 40));
        jButton1.setToolTipText("Establece un color de fondo para la ventana");
        jButton1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton1_actionPerformed(e);
                }
            });
        jButton2.setText("Color de fondo fuente");
        jButton2.setBounds(new Rectangle(240, 5, 210, 40));
        jButton2.setToolTipText("Establece un color de fondo para las fuentes");
        jButton2.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton2_actionPerformed(e);
                }
            });
        jButton3.setText("Color fuente");
        jButton3.setBounds(new Rectangle(5, 55, 135, 25));
        jButton3.setToolTipText("Establece un color de fuente para los números ");
        jButton3.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton3_actionPerformed(e);
                }
            });
        jList1.addListSelectionListener(new ListSelectionListener() {
                public void valueChanged(ListSelectionEvent e) {
                    jComboBox1_valueChanged(e);
                }
            });
        jSpinner1.setBounds(new Rectangle(145, 55, 70, 25));
        jSpinner1.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent e) {
                    jSpinner1_stateChanged(e);
                }
            });
        jScrollPane1.setBounds(new Rectangle(5, 85, 210, 255));
        jButton4.setText("Aplicar");
        jButton4.setBounds(new Rectangle(220, 300, 115, 40));
        jButton4.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton4_actionPerformed(e);
                }
            });
        jButton5.setText("Salir");
        jButton5.setBounds(new Rectangle(340, 300, 115, 40));
        jButton5.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton5_actionPerformed(e);
                }
            });
        jScrollPane1.getViewport().add(jList1, null);
        this.getContentPane().add(jButton5, null);
        this.getContentPane().add(jButton4, null);
        this.getContentPane().add(jScrollPane1, null);
        this.getContentPane().add(jSpinner1, null);
        this.getContentPane().add(jButton3, null);
        this.getContentPane().add(jButton2, null);
        this.getContentPane().add(jButton1, null);
        jPanel1.add(jLabel1, null);
        this.getContentPane().add(jPanel1, null);
        cargarFuentes();

        this.jLabel1.setFont(new Font(dlm.getElementAt(0).toString(),
                                      jLabel1.getFont().getStyle(),
                                      jLabel1.getFont().getSize()));
        int x = jLabel1.getFont().getSize();
        this.jSpinner1.setValue(""+x);
        jSpinner1.setToolTipText("Tamaño de la fuente");
        jLabel1.setOpaque(true);
        this.jList1.setSelectedIndex(0);
        jList1.setToolTipText("Fuentes instaladas en el sistema operativo");
    }

    private void jButton1_actionPerformed(ActionEvent e) {
        Color color = null; //new Color();
        JColorChooser ventanaDeColores=new JColorChooser();
        color=ventanaDeColores.showDialog(this, "Seleccione un Color", Color.gray);
        if(!(color==null)) {
            this.jPanel1.setBackground(color);   
        }
    }
    private void cargarFuentes(){
        String fuentes[];
        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
        fuentes= environment.getAvailableFontFamilyNames();
        for(int con=0;con<fuentes.length;con++) {
          this.dlm.addElement(fuentes[con]);
        }   
    }

    private void jButton2_actionPerformed(ActionEvent e) {
        Color color = null; //new Color();
        JColorChooser ventanaDeColores=new JColorChooser();
        color=ventanaDeColores.showDialog(this, "Seleccione un Color", Color.gray);
        if(!(color==null)) {
            this.jLabel1.setBackground(color);   
        }
    }

    private void jSpinner1_stateChanged(ChangeEvent e) {
        Font f = new Font(jLabel1.getFont().getName(),
                             jLabel1.getFont().getStyle(),
                             Integer.parseInt(jSpinner1.getValue().toString()));
        this.jLabel1.setFont(f);
    }

    private void jComboBox1_valueChanged(ListSelectionEvent e) {
        this.jLabel1.setText(dlm.getElementAt(jList1.getSelectedIndex()).toString());
        this.jLabel1.setFont(new Font(dlm.getElementAt(jList1.getSelectedIndex()).toString(),
                                      jLabel1.getFont().getStyle(),
                                      jLabel1.getFont().getSize()));
    }

    private void jButton3_actionPerformed(ActionEvent e) {
        Color color = null; //new Color();
        JColorChooser ventanaDeColores=new JColorChooser();
        color=ventanaDeColores.showDialog(this, "Seleccione un Color", Color.gray);
        if(!(color==null)) {
            this.jLabel1.setForeground(color);
        }
    }

    private void jButton4_actionPerformed(ActionEvent e) {
        aplicar=1;
        this.setVisible(false);
    }

    private void jButton5_actionPerformed(ActionEvent e) {
        this.setVisible(false);
    }

    public int getAplicar() {
        return aplicar;
    }

    public void setAplicar(int aplicar) {
        this.aplicar = aplicar;
    }
}

package client;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.JOptionPane;

public class EvaluarExpresion {
    private ScriptEngineManager manager = new ScriptEngineManager();
    private ScriptEngine engine = manager.getEngineByName("js");
    private String resultado = null;
    public EvaluarExpresion() {
        super();
    }
    public String getResultado(String expresion, float x, float y) {
        engine.put("x", x);
        engine.put("y", y);
        try {
          resultado = engine.eval(expresion).toString();
          resultado = String.format("%.2f", Float.valueOf(resultado)) ; 
        }catch(ScriptException e) {
            String error = e.getMessage();
            JOptionPane.showMessageDialog(null, "Error en expresión: " + expresion + " " + error);
            resultado = null;
        }catch(Exception e){
            String error = e.getMessage();
            JOptionPane.showMessageDialog(null, "Error genérico al evaluar expresión: " + error);
            resultado = null;               
        }
        return resultado;
    }
}


package client;

import java.util.Random;

public class GenerarSimbolo {
    private String simbolo = "";
    private String simbolos = "ABCDEFGHI";
    private String numeros  = "123456789";
    private String numerosXY  = "123456789xxyy";
    private String operador1 = "+-";
    private String operador2 = "+-*/";
    public GenerarSimbolo() {
        super();
    }
    public String enteroALetra(String numero) {
        String letra = "";
        int x=Integer.parseInt(numero)-1;
        letra = simbolos.substring(x, x+1);
        return letra;
    }
    public String s(int tipo) {
        Random rnd = new Random();
        int x = 0;
        simbolo="";
        switch(tipo){
            case 1: x=rnd.nextInt(numeros.length());
              simbolo = numeros.substring(x, x+1);
              break;
            case 2: x=rnd.nextInt(operador2.length());
              simbolo = operador2.substring(x, x+1);
              break;
            case 3: x=rnd.nextInt(operador1.length());
              simbolo = operador1.substring(x, x+1);
              break;
            case 4: x=rnd.nextInt(numerosXY.length());
              simbolo = numerosXY.substring(x, x+1);
              break;
            default:
        }
        return simbolo;
    }
}


package client;

import java.awt.Image;
import javax.swing.Icon;
import javax.swing.ImageIcon;

public class Imagenes {
    private ImageIcon image = new ImageIcon(getClass().getResource("sumatoria.png"));
    public Imagenes() {
        super();
    }

    public Image getImage() {
        return image.getImage();
    }
    public Icon getIcon() {
        return image;
    }
}



Diagrama de clases del producto software generador de contenido para redes sociales




Descargar el desarrollo del producto software realizado en JDeveloper 11g de Oracle y el archivo ejecutable JAR del siguiente enlace: Descargar desarrollo
Para ejecutar los archivos JAR debe tener la Maquina Virtual Java instalada en su computadora. Para descargar Java: https://java.com

¿Qué son las clases abstractas en Java?


Trabajando con clases abstractas en JDeveloper 11g

Una clase es abstracta si al menos contiene un método declarado como abstracto usando el modificador abstract. Los métodos declarados como abstractos no implementan código y difieren la implementación del código a otra clase.

Tabla de contenido

  • ¿Qué son las clases abstractas en Java?
  • Formas de diferir código Java
  • Características de una clase abstracta.
  • ¿Cuándo utilizar clases abstractas?
  • Para saber más sobre los diagramas Java de Oracle visitar los siguientes sitios
  • Para saber más sobre los diagramas UML.org visitar los siguientes sitios
  • ¿Qué son las interfaces en Java?
  • Relación entre una clase y una interfaz
  • En Java hay tres tipos de relaciones:
  • Heredar clases abstractas
  • Tres situaciones de heredar clases abstractas
  • Situación 1 - Se crearán instancias de la clase padre, superclase o abstracta
  • Situación 2 - Se crearán instancias de la clase  padre, superclase o abstracta pero usando los constructores de los hijos, subclases
  • Situación 3 - Se crearán instancias de los hijos, subclases

Formas de diferir código Java

Hay dos formas de diferir código de una clase abstracta a otra clase:
  • Forma 1 - Cuando se crea una referencia de objeto de una clase abstracta y se instancia usando el operador new
  • Forma 2 - Cuando se hereda una clase abstracta usando la palabra clave extends

Características de una clase abstracta.

  • Si una clase abstracta es instanciada el compilador dará un error de sintaxis, el compilador dejará de dar un error cuando la clase que crea la instancia de la clase abstracta sobrescriba, override, los métodos abstractos e implemente el código faltante que no se definió durante el proceso de abstracción cuando se creó la clase abstracta.
  • Si al menos un método de la clase es declarado abstract, es obligación que la clase completa sea definida como abstract, la clase puede tener el resto de los métodos no abstractos.
  • Los métodos abstract no llevan cuerpo, no llevan las llaves { … }, simplemente termina con un punto y coma “;” 
  • Si una clase hereda a una clase abstracta usando la palabra clave extends  el compilador dará un error de sintaxis, el compilador dejará de dar un error cuando la clase que hereda sobrescriba los métodos abstractos e implemente el código faltante que no se definió durante el proceso de abstracción cuando se creó la clase abstracta.
  • Existe el caso extremo de declarar todos los atributos de una clase con el modificador estático, static, y todos los métodos como abstractos, abstract. En estas clases no hace falta instanciar un objeto de la clase padre o heredada ya que las clases hijas o herederas se harán cargo de implementar todos los métodos abstractos, es suficiente con crear objetos de las clases herederas para acceder a los métodos. El compilador no da error si se crea un objeto de una clase totalmente abstracta, el compilador se queda a la espera que en el futuro se implemente un método no abstracto para la clase padre o que se utilice un constructor de alguno de los hijos al crear una instancia del padre. El compilador se queda esperando que se utilice el poder del polimorfismo.   

¿Cuándo utilizar clases abstractas?

  • Cuando se necesita implementar distintos comportamientos para un mismo método
  • En la fase de análisis, es cuando se intenta definir qué es el problema y se deja la implementación, programación, para más tarde
  • En la fase de diseño, es cuando se intenta definir cómo es el problema y se deja la implementación, programación, para más tarde
  • Cuando se desea usar el mecanismo del polimorfismo, es cuando un objeto cambia de tipo y de comportamiento.
  • Cuando el objetivo es producir código reutilizable por medio del polimorfismo
  • Cuando el objetivo es crear componentes reutilizables
  • Cuando se quiere relacionar dos clases y establecer un medio de comunicación entre las clases 

Forma 1 - Cómo diferir código de una clase abstracta a otra clase usando el operador new



package client1;
public class Main {
    public Main() {
        super();
    }
    private static Figura figura = null;
    public static void main(String[] args) {
        figura = new Figura(1){ //creando un tipo Figura
            @Override
            public float area() {
                return resultado;
            }
        };
       
        System.out.print("Área Figura: " + figura.tipoFigura + "=");
        System.out.println(figura.area()); //línea polimórfica del tipo Figura
       
        figura = new Figura(3, 4){ //creando un tipo Figura
            @Override
            public float area() {
                return resultado;
            }
        };
       
        System.out.print("Área Figura: " + figura.tipoFigura + "=");
        System.out.println(figura.area()); //línea polimórfica del tipo Figura
    }
}

package client1;

public abstract class Figura {
    public Figura() {
        super();
    }
    public Figura(int r) {
        super();
        this.r = r;
        resultado = (float)3.14 * (r * r);
        tipoFigura = "Círculo";
    }
    public Figura(int a, int b) {
        super();
        this.a = a;
        this.b = b;
        resultado = a * b;
        tipoFigura = "Cuadrilátero";
    }
   
    public float a=3, b=4, r=1, resultado=0;
    public String tipoFigura="";
   
    public abstract float area();
}


Para saber más sobre los diagramas Java de Oracle visitar los siguientes sitios



Para saber más sobre los diagramas UML.org visitar los siguientes sitios



¿Qué son las interfaces en Java?

Las interfaces son un tipo de clases Java donde todos sus métodos son abstractos. Una clase declarada como interfaz usando la palabra clave interface es una clase abstracta que tiene todos sus métodos declarados como abstractos. Un método abstracto no tiene código implementado y difiere a que otra clase implemente el código no implementado.
Java es un lenguaje que no permite la herencia múltiple, a acepción de las clases que son declaradas como interfaz. Una clase puede heredar muchas clases que sean declaradas como interfaz. Una clase puede heredar una o más clases del tipo interfaz y la clase que hereda está obligada a implementar el código de la clase heredada.
  •  Las clases abstractas del tipo interfaz no se pueden instanciar.
  • Las clases abstractas del tipo interfaz pueden tener declaraciones de valores constantes, static, final
  • Las clases abstractas del tipo interfaz pueden tener definiciones de métodos abstractos, abstract
  • Para acceder a un valor constante de una interfaz se utiliza su nombre y el operador punto o por medio de la clase que la herede
Las interfaces declaran definiciones de constantes y métodos abstractos, por definición una interfaz es una clase abstracta.
Las interfaces son usadas para definir partes de un producto software, las interfaces son definidas en la fase de análisis del desarrollo de un producto software. Durante la fase de análisis muchos casos de usos se agrupan para definir clases e interfaces. Las clases y las interfaces son consecuencia directa de la agrupación de los datos, casos de usos. Los métodos declarados en las clases y las interfaces serán los encargados de operar con los datos y producir la salida deseada según el problema a resolver.  

Relación entre una clase y una interfaz

La relación entre una interfaz y una clase es una relación que indica que la interfaz es parte de la clase.

En Java hay tres tipos de relaciones:


  1. Relación “Tiene”, es cuando se usa el operador new
  2. Relación “Es del mismo tipo”, es cuando se usa la palabra clave extends
  3. Relación “Es parte”, es cuando se usa la palabra clave implements

En un ambiente de programación Java las palabras agregación y composición se deben entender como actividades y tareas del proceso de abstracción en el desarrollo de un producto software.

Los conceptos de abstracción, agregación y composición no son relaciones en Java, Java tiene tres tipos de relaciones y sus correspondientes palabras claves.

Hay grandes diferencias entre los diagramas UML.org y los diagramas UML Java Oracle, definen distintos estereotipos.

Oracle toma el modelo de referencia UML.org y hereda muchos de los estereotipos definidos por el UML.org y los redefine para crear los diagramas de clases Java específicos para el desarrollo de productos software con el lenguaje Java


El diagrama se lee de la siguiente forma:

La clase VentanaPrincipal y la clase Reloj implementan una parte en común, la parte en común es el método notificarHora(…)
La clase VentanaPrincipal es la responsable de crear una instancia de la clase Reloj y de implementar el código faltante.
La clase Reloj notificará la hora a la clase VentanaPrincipal por medio del código implementado por la clase ventanaPrincipal
  
package client;

import java.awt.Dimension;

import java.awt.Rectangle;

import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class VentanaPrincipal extends JFrame implements MiNotificador {
    private JLabel jLabel1 = new JLabel();

    public VentanaPrincipal() {
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private Reloj reloj = null;
    private void jbInit() throws Exception {
        this.getContentPane().setLayout( null );
        this.setSize( new Dimension(400, 300) );
        jLabel1.setText("jLabel1");
        jLabel1.setBounds(new Rectangle(55, 50, 270, 30));
        this.getContentPane().add(jLabel1, null);
       
        reloj = new Reloj(){
            @Override
            public void notificarHora(Date date) {
                miNotificarHora(date);
            }
           
        };
        reloj.start();
    }
   
    public void miNotificarHora(Date date) {
        notificarHora(date);
    }

    @Override
    public void notificarHora(Date hora) {
        this.jLabel1.setText(hora.toString());
    }
   
    public static void main(String[] args) {
      VentanaPrincipal vp = new VentanaPrincipal();
      vp.setDefaultCloseOperation(vp.EXIT_ON_CLOSE);
      vp.setLocationRelativeTo(null);
      vp.setVisible(true);
    }
}

package client;
import java.util.Date;
public abstract class Reloj extends Thread implements MiNotificador {
    public Reloj() {
        super();
    }
    public void run() {
        super.run();
        Date date = null;
        do {
            date = new Date();
            notificarHora(date);
            try {
                this.sleep(500);
            } catch (InterruptedException e) {
            }
        } while (true);
    }
    public abstract void notificarHora(Date date);
}

package client;

import java.util.Date;

public interface MiNotificador {
   
    public void notificarHora(Date hora);

}

Heredar clases abstractas


Forma 2 - Cuando se hereda una clase abstracta usando la palabra clave extends

Tres situaciones de heredar clases abstractas


Existen tres situaciones cuando se heredan clases abstractas al momento de crear instancias con new
  1. Se crearán instancias de la clase padre, superclase o abstracta
  2. Se crearán instancias de la clase  padre, superclase o abstracta pero usando los constructores de los hijos, subclases
  3. Se crearán instancias de los hijos, subclases
Nota:
No se puede crear instancias de las clases abstractas, el motivo es que no tienen código implementado. Pero si la clase que intenta crear una instancia de la clase abstracta se hace cargo de implementar el código faltante si se puede crear una instancia de una clase declarada como abstracta.
De la única clase abstracta que no se puede crear instancias es de la clase tipo interfaz. Es obligación que las interfaces sean heredadas para que otra clase se haga cargo del código faltante.  


Situación 1 - Se crearán instancias de la clase padre, superclase o abstracta



La clase Main es la responsable de sobrescribir el método abstracto definido por la clase Figura

package client1;
public class Main {
    public Main() {
        super();
    }
    private static Figura figura = null;
    public static void main(String[] args) {
        figura = new Figura(1){ //creando un tipo Figura
            @Override
            public float area() {
                return resultado;
            }
        };
       
        System.out.print("Área Figura: " + figura.tipoFigura + "=");
        System.out.println(figura.area()); //línea polimórfica del tipo Figura
       
        figura = new Figura(3, 4){ //creando un tipo Figura
            @Override
            public float area() {
                return resultado;
            }
        };
       
        System.out.print("Área Figura: " + figura.tipoFigura + "=");
        System.out.println(figura.area()); //línea polimórfica del tipo Figura
    }
}

package client1;

public abstract class Figura {
    public Figura() {
        super();
    }
    public Figura(int r) {
        super();
        this.r = r;
        resultado = (float)3.14 * (r * r);
        tipoFigura = "Círculo";
    }
    public Figura(int a, int b) {
        super();
        this.a = a;
        this.b = b;
        resultado = a * b;
        tipoFigura = "Cuadrilátero";
    }
   
    public float a=3, b=4, r=1, resultado=0;
    public String tipoFigura="";
   
    public abstract float area();
}

Situación 2 - Se crearán instancias de la clase  padre, superclase o abstracta pero usando los constructores de los hijos, subclases



package client2;

public class Main {

    public Main() {
        super();
    }

    private static Figura figura = null;

    public static void main(String[] args) {

        figura = new Circulo(1); //Creando un tipo Círculo
        System.out.println(figura.area()); //línea polimórfica del tipo Círculo

        figura = new Cuadrilatero(2, 4); //Creando un tipo Cuadrilátero
        System.out.println(figura.area()); //línea polimórfica del tipo Cuadrilátero

    }
}


package client2;

public abstract class Figura {

    public Figura() {
        super();
    }
   
    public float a=3, b=4, r=1, resultado=0;
    public String tipoFigura="";
   
    public abstract float area();
}


package client2;

public class Circulo extends Figura{
    public Circulo(float r) {
        super();
        this.r = r;
        this.tipoFigura = "Círculo";
    }

    @Override
    public float area() {
        resultado = (float)3.14 * (r * r);
        return resultado;
    }
}


package client2;

public class Cuadrilatero extends Figura{
    public Cuadrilatero(int a, int b) {
        super();
        this.a = a;
        this.b = b;
        this.tipoFigura = "Cuadrilátero";
    }

    @Override
    public float area() {
        resultado = a * b;    
        return resultado;
    }   
}


Situación 3 - Se crearán instancias de los hijos, subclases



package client3;

public class Main {

    public Main() {
        super();
    }

    private static Circulo circulo = null;

    private static Cuadrilatero cuadrilatero = null;

    public static void main(String[] args) {

        circulo = new Circulo(1);
        System.out.println("Área círculo = " + circulo.area());

        cuadrilatero = new Cuadrilatero(3,4);
        System.out.println("Área cuadrilátero = " + cuadrilatero.area());

    }
}


package client3;

public abstract class Figura {

    public Figura() {
        super();
    }
   
    public float a=3, b=4, r=1, resultado=0;
    public String tipoFigura="";
   
    public abstract float area();
}


package client3;


public class Cuadrilatero extends Figura {
    public Cuadrilatero(int a, int b) {
        super();
        this.a = a;
        this.b = b;
        tipoFigura = "Cuadrilátero";
    }

    @Override
    public float area() {
        resultado = a * b;    
        return resultado;
    }   
}

package client3;

public class Circulo extends Figura {
    public Circulo(float r) {
        super();
        this.r = r;
        tipoFigura = "Círculo";
    }

    @Override
    public float area() {
        resultado = (float)3.14 * (r * r);
        return resultado;
    }
}