Hur ska jag använda Java Generics här - Objekt som argument för en konstruktör

Permalänk

Hur ska jag använda Java Generics här - Objekt som argument för en konstruktör

Hej!

Vi säger att jag har en klass A som har en konstruktör med klassen B

public class A { private B b; public A(B b){ this.b = b; } public void run(){ b.run(); } }

Men jag vill kunna använda denna klass A för klasserna C och D som också har en metod som heter run().

Är detta ett utmärkt tillfälle att använda Java Generics då? Ifall JA: Hur ska jag göra?

Permalänk
Medlem
Skrivet av heretic16:

Hej!

Vi säger att jag har en klass A som har en konstruktör med klassen B

public class A { private B b; public A(B b){ this.b = b; } public void run(){ b.run(); } }

Men jag vill kunna använda denna klass A för klasserna C och D som också har en metod som heter run().

Är detta ett utmärkt tillfälle att använda Java Generics då? Ifall JA: Hur ska jag göra?

Om det inte är en slump att klasserna B, C och D har en metod run (dvs, om run är definierat i någon gemensam basklass eller något interface) så känns det väl som att du bara skulle använda den typen i A istället. Känns inte uppenbart att du har något behov av generics i detta fall.

Om det är en slump att alla har run så är väl frågan om det är dina klasser, och du isf kan fixa till det i stil med vad jag var inne på. Annars lär det bli smutsigt.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Skrivet av evil penguin:

Om det inte är en slump att klasserna B, C och D har en metod run (dvs, om run är definierat i någon gemensam basklass eller något interface) så känns det väl som att du bara skulle använda den typen i A istället. Känns inte uppenbart att du har något behov av generics i detta fall.

Om det är en slump att alla har run så är väl frågan om det är dina klasser, och du isf kan fixa till det i stil med vad jag var inne på. Annars lär det bli smutsigt.

Okej. Då har jag inget behov utav generics. Då kanske flera konstruktörer passar bättre?

Permalänk
Medlem
Skrivet av heretic16:

Okej. Då har jag inget behov utav generics. Då kanske flera konstruktörer passar bättre?

Jag tycker inte det låter som att det skulle behövas heller...?

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Avstängd

i C# kan man ha en constraint att ett generiskt typ ska vara av en viss typ tex

public class MyClass<T> where T : IMyInterfcae

Borde gå även i Java. Nackdelen med att använda ett interface istället för en generisk typ är att du kommer inte åt de konkreta medlemmarna på T.

edit: I Java gör man MyClass<T extends IMyInterface>

Visa signatur
Permalänk
Medlem

Från din beskrivning av problemet låter det som att subtyping polymorphism med e.g. interfaces borde passa bra. Nu var det ett tag sedan jag använde Java, så syntaxen är säkert inte helt rätt, men du borde kunna skriva nåt sånt här:

interface Runnable { void run(); } class B extends Runnable { public void run() { // b implementation } } class C extends Runnable { public void run() { // c implementation } } class D extends Runnable { public void run() { // d implementation } } public class A extends Runnable { private Runnable r; public A(Runnable r){ this.r = r; } public void run() { r.run(); } }

Visa signatur

Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4

Permalänk
Avstängd

Om du vill ha generics eller klassisk polymofism beror helt på hur du vill använda din typ

Exempel från mitt spel, här har vi en generisk pool

public class AudioSourcePool : PollingPool<AudioSource> { public AudioSourcePool(AudioSource prefab) : base(prefab) { } protected override bool IsActive(AudioSource component) { return component.isPlaying; } public void PlayAtPoint(AudioClip clip, Vector3 point) { var source = Get(); source.transform.position = point; source.clip = clip; source.Play(); } }

Clip, Play och isPlaying är medlemmar som enbart subklassimplementaionen känner till. Detta hade inte gått lösa lika snyggt utan generics.

Visa signatur
Permalänk
Medlem
Skrivet av heretic16:

Hej!

Vi säger att jag har en klass A som har en konstruktör med klassen B

public class A { private B b; public A(B b){ this.b = b; } public void run(){ b.run(); } }

Men jag vill kunna använda denna klass A för klasserna C och D som också har en metod som heter run().

Är detta ett utmärkt tillfälle att använda Java Generics då? Ifall JA: Hur ska jag göra?

Om klasserna C och D ärver (extends) klass B kan du låta konstruktorn ta typ B och inte tänka mer på saken. I detta scenario är ett objekt av klass C eller D även ett objekt av klass B — arvet säkerställer att B, C och D har en run()-metod.

Visa signatur

Kom-pa-TI-bilitet