> For the complete documentation index, see [llms.txt](https://educacion.gitbook.io/programacion/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://educacion.gitbook.io/programacion/exercicios-java/ud7-solucions/clases-xenericas.md).

# Clases Xenéricas

1. Producto

```java
public class Producto<K, V> {
    
    private K codigo;
    private V descripcion;
    
    public Producto(K codigo, V descripcion) {
        this.codigo = codigo;
        this.descripcion = descripcion;
    }
    
    public Producto(K codigo) {
        this(codigo, (V) "Descripción por defecto");
    }
    
    // Getters e Setters
    public K getCodigo() {
        return codigo;
    }
    
    public void setCodigo(K codigo) {
        this.codigo = codigo;
    }
    
    public V getDescripcion() {
        return descripcion;
    }
    
    public void setDescripcion(V descripcion) {
        this.descripcion = descripcion;
    }
    
    @Override
    public String toString() {
        return "Producto [código=" + codigo + ", descripción=" + descripcion + "]";
    }
    
    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Producto<?,?> producto)) 
            return false;
        Producto<K,V> prod =  (Producto<K,V>) o;
        return this.getCodigo().equals(prod.getCodigo()) &&
                this.getDescripcion().equals(prod.getDescripcion());
    }
}
```

```java
public class App {
    public static void main(String[] args) {
        
        Producto<Integer, String> producto1 = new Producto<>(1001, "Portátil gaming con RTX 4060");

        // Dous obxectos con código tipo cadena (String) e descripción tipo cadena (String)
        Producto<String, String> producto2 = new Producto<>("A100", "Mouse inalámbrico");
        Producto<String, String> producto3 = new Producto<>("A100", "Mouse inalámbrico");
        
        // Mostrar información dos tres productos
        System.out.println("=== INFORMACIÓN DOS PRODUCTOS ===");
        System.out.println("Producto 1: " + producto1.toString());
        System.out.println("Producto 2: " + producto2.toString());
        System.out.println("Producto 3: " + producto3.toString());
        
        //Comparacions
        System.out.println("\n=== COMPARACIÓNS ===");

        // Comparar producto1 con producto2
        System.out.println("Producto1 é igual a Producto2? " + producto1.equals(producto2));

        // Comparar producto1 con producto3
        System.out.println("Producto1 é igual a Producto3? " + producto1.equals(producto3));

        // Comparar producto2 con producto3
        System.out.println("Producto2 é igual a Producto3? " + producto2.equals(producto3));  
    }
}
```

2. Código 1.
   1. T é un **tipo xenérico da clase** `Contenedor`. Declárase na definición da clase: `class Contenedor<T>`. Está dispoñible en **toda a clase**, incluíndo campos (`atributo`) e métodos (`metodo1` e tamén `metodo2`).
   2. Q é un **tipo xenérico do método** `metodo2`. Declárase dentro da definición do método: `public <Q> void metodo2(Q param)`. Só está dispoñible **dentro dese método**.
   3. * `T` declárase na clase porque queremos que **toda a clase use o mesmo tipo** que se decide ao instanciar.
      * `Q` declárase no método porque é **local a ese método**, podendo ser distinto cada vez que se chama, sen afectar o tipo `T` da clase
3. Restricción de herdanza

```java
package genericas;

import java.util.Objects;

public class Producto <K extends Integer, V> {  // K debe ser Number ou subclase
    private K codigo;
    private V descripcion;

    // Constructor con código e descripción
    public Producto(K codigo, V descripcion) {
        this.codigo = codigo;
        this.descripcion = descripcion;
    }

    // Constructor só con código (reutiliza o primeiro constructor)
    public Producto(K codigo) {
        this(codigo, (V) "Descripción por defecto");
    }

    // Getters e Setters
    public K getCodigo() {
        return codigo;
    }

    public void setCodigo(K codigo) {
        this.codigo = codigo;
    }

    public V getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(V descripcion) {
        this.descripcion = descripcion;
    }

    @Override
    public String toString() {
        return "Producto{" +
                "codigo=" + codigo +
                ", descripcion=" + descripcion +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Producto<?,?> producto))
            return false;
        Producto<K,V> prod =  (Producto<K,V>) o;
        return this.getCodigo().equals(prod.getCodigo()) &&
                this.getDescripcion().equals(prod.getDescripcion());
    }

    @Override
    public int hashCode() {
        return Objects.hash(codigo, descripcion);
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://educacion.gitbook.io/programacion/exercicios-java/ud7-solucions/clases-xenericas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
