JavaRush /Blog Java /Random-ES /Pausa para el café #133. Cómo obtener sólo una parte de u...

Pausa para el café #133. Cómo obtener sólo una parte de una matriz en Java. Interfaces y clases abstractas en Java

Publicado en el grupo Random-ES

Cómo obtener sólo una parte de una matriz en Java

Fuente: Asyncq Copiar parte de una matriz es una operación muy común que encuentra todo desarrollador. En este artículo, veremos código de estilo imperativo tradicional y estilo declarativo moderno con expresión lambda y API de transmisión. Pausa para el café #133.  Cómo obtener sólo una parte de una matriz en Java.  Interfaces y clases abstractas en Java - 1

Enfoque imperativo

El estilo de programación imperativo ha sido común durante mucho tiempo en Java. Por lo tanto, es natural que los desarrolladores de Java escriban el siguiente código para copiar una parte específica de la matriz original. Para hacer esto, simplemente recorra los elementos, filtrando solo aquellos que sean necesarios y escríbalos en la matriz final.
private static int[] copyArray(){
       int[] numbers = {1,2,3,4,5,6,7};
       int[] subArray = new int[numbers.length-3];
       int j =3;
       for (int i=0;i<subArray.length;i++){
           subArray[i] = numbers[j+i];
       }
       System.out.println(Arrays.toString(subArray));
       return subArray;
   }
Muchos de nosotros olvidamos a menudo que la biblioteca Java Arrays tiene un método copyOfRange conveniente . Este método se puede utilizar para copiar parte de una matriz pasando hacia y desde el índice.
private static int[] copyArray1(){
  int[] numbers = {1,2,3,4,5,6,7};
  int[] subArray = Arrays.copyOfRange(numbers,3,numbers.length);
  System.out.println(Arrays.toString(subArray));
  return subArray;
}

Enfoque declarativo

Desde Java 8 podemos usar la API Streams para copiar parte de una matriz. En el código siguiente, podemos pasar int[] y filtrar solo valores mayores que 3 y finalmente copiarlos en una matriz.
private static void copyArray2(){
        int[] numbers = {1,2,3,4,5,6,7};
        // copy with values
        int[] subArray = Arrays.stream(numbers).filter(a-> a>3).toArray();
        System.out.println(Arrays.toString(subArray));
    }
El código anterior es una copia basada en valores de una parte de la matriz, pero también podemos copiar según un índice. Debajo del código transmitimos Intstream desde i=0; i=len(matriz) . Normalmente, en código imperativo escribimos un bucle for desde el índice inicial hasta el índice final e iteramos sobre cada elemento. Podemos hacer lo mismo usando Intstream y acceder al elemento index .
// copy with index
int[] subArray1 = IntStream
                .range(0, numbers.length)
                .filter(i -> i > 3)
                .map(a->numbers[a]).toArray();

System.out.println(Arrays.toString(subArray1));
Si bien el método anterior funciona, tenemos otra forma en la que podemos usar AtomicInteger para copiar parte de la matriz. Tiene un método getAndIncrement que esencialmente proporciona un índice y lo incrementa en 1.
// copy with index
AtomicInteger atomicInteger = new AtomicInteger();
int[] subArray2 = Arrays.stream(numbers).filter(i -> atomicInteger.getAndIncrement() > 3).toArray();
System.out.println(Arrays.toString(subArray2));

Conclusión

En este artículo, analizamos cómo copiar parte de una matriz Java usando estilos imperativos y declarativos. Preferiría trabajar en un estilo declarativo ya que hace que mi código sea más legible y menos detallado.

Interfaces y clases abstractas en Java

Fuente: Devgenius Al aprender el lenguaje Java, ciertamente nos topamos con un concepto llamado Interfaces. Las interfaces son una de las características clave de Java, por lo que todo desarrollador debe saber cómo utilizarlas. Es importante recordar que las interfaces tienen ventajas y desventajas. Profundicemos en la comprensión de las interfaces. Al implementar interfaces, nos encontramos con clases abstractas. ¿Qué son las clases abstractas? ¿Para qué se necesitan? ¿Qué es una interfaz? ¿Cómo se utilizan? ¿Por qué las interfaces usan clases abstractas? Obtendrá respuestas a todas estas preguntas en este artículo. Pausa para el café #133.  Cómo obtener sólo una parte de una matriz en Java.  Interfaces y clases abstractas en Java - 2

¿Qué es una interfaz?

Una interfaz es un mecanismo especial en Java que describe el comportamiento y ayuda a lograr la abstracción. Es similar a una clase en muchos aspectos porque tiene constantes estáticas y métodos abstractos. Las interfaces sólo pueden tener métodos abstractos (métodos sin cuerpo). Breve diferencia entre interfaz y clase abstracta:
  • La interfaz no tiene ningún método implementado; todos son públicos y no hay variables de clase.
  • Una clase abstracta es una clase que no tiene uno o más métodos implementados.
Desde Java 9, también podemos usar métodos privados , predeterminados y estáticos en las interfaces . Ahora pasemos a la lógica de interfaz simple que se utiliza para lograr la abstracción.

¿Qué es la abstracción?

Tomemos un ejemplo de la vida real. Todos usamos aplicaciones en nuestros teléfonos móviles. Siempre que queramos utilizar cualquier aplicación, tenemos que crear una cuenta en ella. Cuando nos registramos a través de nuestro número de teléfono, se envía una contraseña de un solo uso a nuestro teléfono móvil. Sabemos que la contraseña se recibe después de hacer clic en el botón "Obtener contraseña" en la aplicación, pero no sabemos cómo funciona este sistema en el backend y qué sucede realmente después de hacer clic en el botón. Ahora, el proceso de completar tareas con éxito sin mostrarle al usuario lo que realmente está sucediendo en el backend se conoce como abstracción. En Java, podemos lograr la abstracción utilizando interfaces y clases abstractas.

¿Por qué utilizar la interfaz?

Hay tres razones para utilizar la interfaz:
  • Para lograr la abstracción.
  • Para admitir la funcionalidad de herencia múltiple.
  • Para lograr un acoplamiento flojo.

¿Cómo utilizar la interfaz?

Una interfaz se declara utilizando la palabra clave interfaz . Proporciona abstracción, es decir, declara la estructura de la clase. Todos los métodos en una interfaz son abstractos y están configurados como públicos, estáticos y finales de forma predeterminada ( public , static , final ). Cualquier clase que implemente una interfaz debe implementar todos los métodos declarados en la interfaz.
interface <interface_name>{

     // declare constant fields
     // declare methods that abstract
     // by default.
 }
De manera similar a la abstracción de la interfaz, la abstracción también se puede lograr utilizando clases abstractas.

¿Qué son las clases abstractas?

Las clases abstractas son clases con la palabra clave abstracta delante de ellas. Contienen métodos tanto abstractos como concretos (con cuerpo). No se pueden crear instancias de clases abstractas, se deben ampliar y se deben implementar sus métodos. Una clase abstracta describe algún objeto abstracto (automóvil, persona, etc.), no solo el comportamiento. Recordar:
  • Una clase abstracta debe declararse con la palabra clave abstracta .
  • Puede haber métodos abstractos y no abstractos.
  • No se puede crear una instancia de una clase abstracta.
  • Puede tener constructores y métodos estáticos.
  • Puede tener métodos finales que obligarán a la subclase a no cambiar el cuerpo del método.
Ejemplo de una clase abstracta con un método abstracto: en este ejemplo , Bike es una clase abstracta que contiene solo un método abstracto ejecutado. Su implementación la proporciona la clase Honda .
abstract class Bike{
  abstract void run();
}
class Honda4 extends Bike{
void run(){System.out.println("running safely");}
public static void main(String args[]){
 Bike obj = new Honda4();
 obj.run();
}
}
Clase abstracta que tiene un constructor, un miembro de datos y métodos: una clase abstracta puede tener un miembro de datos, un método abstracto, un cuerpo de método (método no abstracto), un constructor e incluso un método main() .
//Example of an abstract class that has abstract and non-abstract methods
 abstract class Bike{
   Bike(){System.out.println("bike is created");}
   abstract void run();
   void changeGear(){System.out.println("gear changed");}
 }
//Creating a Child class which inherits Abstract class
 class Honda extends Bike{
 void run(){System.out.println("running safely..");}
 }
//Creating a Test class which calls abstract and non-abstract methods
 class TestAbstraction2{
 public static void main(String args[]){
  Bike obj = new Honda();
  obj.run();
  obj.changeGear();
}
}
Ahora surge la pregunta principal. Si las interfaces y las clases abstractas ayudan con la abstracción, ¿cuál es mejor usar? La respuesta es que Java no soporta la herencia múltiple como lo hace C++. Es decir, si necesitamos lograr herencia múltiple, entonces deberíamos usar interfaces. En otras palabras, las clases abstractas ayudan del 1 al 100% de los casos y las interfaces ayudan en el 100% de los casos. Si necesitamos comportamiento, necesitamos usar una interfaz. Si hablamos de un objeto conceptual, debemos utilizar una clase abstracta.

Ejemplo de interfaz Java

En este ejemplo, la interfaz Drawable tiene solo un método. Su implementación la proporcionan las clases Rectángulo y Círculo . En un escenario real, la interfaz la define otra persona y su implementación la proporcionan diferentes proveedores de implementación. Además, otra persona lo está utilizando. El usuario que utiliza la interfaz oculta parte de la implementación.
//Interface declaration: by first user
interface Drawable{
void draw();
}
//Implementation: by second user
class Rectangle implements Drawable{
public void draw(){System.out.println("drawing rectangle");}
}
class Circle implements Drawable{
public void draw(){System.out.println("drawing circle");}
}
//Using interface: by third user
class TestInterface1{
public static void main(String args[]){
Drawable d=new Circle();//In real scenario, object is provided by method e.g. getDrawable()
d.draw();
}}

Herencia múltiple en Java usando la interfaz

Si una clase implementa múltiples interfaces o una interfaz extiende múltiples interfaces, se llama herencia múltiple.
interface Printable{
void print();
}
interface Showable{
void show();
}
class A7 implements Printable,Showable{
public void print(){System.out.println("Hello");}
public void show(){System.out.println("Welcome");}

public static void main(String args[]){
A7 obj = new A7();
obj.print();
obj.show();
 }
}
Pregunta: La herencia múltiple no se admite a través de una clase en Java, pero es posible a través de una interfaz, ¿por qué? Como ya se explicó en la sección sobre herencia, la herencia múltiple no se admite en el ejemplo de clase debido a ambigüedad. Sin embargo, el ejemplo de interfaz lo admite porque no hay ambigüedad en él. La razón es que su implementación la proporciona la clase de implementación.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION