Een inleiding tot Traits in Groovy

1. Overzicht

In deze tutorial onderzoeken we het concept van eigenschappen in Groovy. Ze werden geïntroduceerd in de Groovy 2.3-release.

2. Wat zijn eigenschappen?

Eigenschappen zijn herbruikbare componenten die een reeks methoden of gedragingen vertegenwoordigen die we kunnen gebruiken om de functionaliteit van meerdere klassen uit te breiden.

Om deze reden, ze worden beschouwd als interfaces, met zowel standaardimplementaties als status. Alle eigenschappen worden gedefinieerd met behulp van de eigenschap trefwoord.

3. Methoden

Een methode declareren in een eigenschap is vergelijkbaar met het declareren van een reguliere methode in een klasse. We kunnen echter geen beschermde of pakket-privé methoden declareren in een eigenschap.

Laten we eens kijken hoe openbare en privémethoden worden geïmplementeerd.

3.1. Openbare methoden

Om te beginnen zullen we onderzoeken hoe openbaar methoden worden geïmplementeerd in een eigenschap.

Laten we een eigenschap genaamd UserTrait en een openbaarzeg hallo methode:

eigenschap UserTrait {String sayHello () {retourneer "Hallo!" }}

Daarna maken we een Werknemer class, die implementeert UserTrait:

class Employee implementeert UserTrait {}

Laten we nu een test maken om te verifiëren dat een Werknemer instantie heeft toegang zeg hallo methode van de UserTrait:

def 'Moet een msg-string retourneren bij gebruik van de Employee.sayHello-methode geleverd door gebruikerstrek' () {wanneer: def msg = employee.sayHello () dan: msg msg instanceof String assert msg == "Hallo!" }

3.2. Privé-methoden

We kunnen ook een privaat methode in een eigenschap en verwijs ernaar in een andere openbaar methode.

Laten we de code-implementatie in het UserTrait:

private String greetingMessage () {retourneer 'Hallo, van een privémethode!' } String greet () {def msg = greetingMessage () println msg return msg} 

Merk op dat als we toegang hebben tot het privaat methode in de implementatieklasse, zal het een MissingMethodException:

def 'Moet MissingMethodException retourneren bij gebruik van de Employee.greetingMessage-methode' () {wanneer: def uitzondering probeer {employee.greetingMessage ()} catch (uitzondering e) {exception = e} dan: uitzondering uitzondering instantie van groovy.lang.MissingMethodException beweert uitzondering. message == "Geen handtekening van methode: com.baeldung.traits.Employee.greetingMessage ()" + "is van toepassing op argumenttypes: () waarden: []"}

In een eigenschap, een private methode kan essentieel zijn voor elke implementatie die niet mag worden overschreven door een klasse, hoewel vereist door andere openbare methoden.

3.3. Abstracte methoden

EEN eigenschap kan ook bevatten abstract methoden die vervolgens in een andere klasse kunnen worden geïmplementeerd:

eigenschap UserTrait {abstract String name () String showName () {return "Hallo, $ {naam ()}!" }}
class Employee implementeert UserTrait {String name () {return 'Bob'}} 

3.4. Standaardmethoden overschrijven

Meestal een eigenschap bevat standaardimplementaties van zijn openbare methoden, maar we kunnen ze overschrijven in de implementatieklasse:

eigenschap SpeakingTrait {String speak () {return "Speaking !!" }} 
class Dog implementeert SpeakingTrait {String speak () {return "Bow Bow !!" }} 

Eigenschappen ondersteunen niet beschermd en privaat scopes.

4. dit Trefwoord

Het gedrag van de dit trefwoord is vergelijkbaar met dat in Java. We kunnen de eigenschap als een super klasse.

We maken bijvoorbeeld een methode die terugkeert dit in een eigenschap:

eigenschap UserTrait {def self () {return this}}

5. Interfaces

EEN eigenschap kan ook interfaces implementeren, net als gewone klassen.

Laten we een koppel en implementeer het in een eigenschap:

interface Mens {String lastName ()}
eigenschap UserTrait implementeert Human {String showLastName () {return "Hallo, $ {lastName ()}!" }}

Laten we nu het abstract methode van de koppel in de implementatieklasse:

class Employee implementeert UserTrait {String lastName () {return "Marley"}}

6. Eigenschappen

We kunnen eigenschappen toevoegen aan een eigenschap net zoals we zouden doen in elke reguliere klas:

eigenschap UserTrait implementeert Human {String email String address}

7. Eigenschappen uitbreiden

Vergelijkbaar met een gewone Groovy klasse, een eigenschap kan een ander verlengen eigenschap de ... gebruiken strekt zich uit trefwoord:

eigenschap WheelTrait {int noOfWheels} eigenschap VehicleTrait breidt WheelTrait uit {String showWheels () {return "Num of Wheels $ noOfWheels"}} klasse Auto implementeert VehicleTrait {}

We kunnen ook meerdere eigenschappen uitbreiden met de werktuigen clausule:

eigenschap AddressTrait {String residenceAddress} eigenschap EmailTrait {String email} eigenschap Persoon implementeert AddressTrait, EmailTrait {}

8. Meerdere overervingsconflicten

Wanneer een klas twee of meer eigenschappen implementeert die methoden met dezelfde handtekening hebben, moeten we weten hoe we de conflicten kunnen oplossen. Laten we eens kijken hoe Groovy dergelijke conflicten standaard oplost, evenals een manier waarop we de standaardoplossing kunnen negeren.

8.1. Standaard conflictoplossing

Standaard is de methode van de laatst gedeclareerde eigenschap in de werktuigen clausule wordt opgehaald.

Daarom helpen eigenschappen ons om meerdere erfenissen te implementeren zonder het diamantprobleem tegen te komen.

Laten we eerst twee kenmerken maken met een methode met dezelfde handtekening:

eigenschap WalkingTrait {String basicAbility () {retourneer "Walking !!" }} eigenschap SpeakingTrait {String basicAbility () {retourneer "Speaking !!" }} 

Laten we vervolgens een klasse schrijven die beide eigenschappen implementeert:

klasse Hondenuitrusting WalkingTrait, SpeakingTrait {} 

Omdat SpeakingTrait wordt als laatste verklaard, zijn basicAbility implementatie van de methode wordt standaard opgepikt in de Hond klasse.

8.2. Expliciete conflictoplossing

Als we nu niet gewoon de standaardconflictoplossing van de taal willen gebruiken, kunnen we deze negeren doorexpliciet kiezen welke methode moet worden aangeroepen met behulp van de eigenschap. super.methode referentie.

Laten we bijvoorbeeld een andere methode met dezelfde handtekening toevoegen aan onze twee eigenschappen:

String speakAndWalk () {retourneer "Walk and speak !!" }
String speakAndWalk () {return "Spreken en lopen !!" }

Laten we nu de standaardoplossing van meerdere overervingsconflicten in ons Hond klasse met behulp van de super trefwoord:

klasse Hond implementeert WalkingTrait, SpeakingTrait {String speakAndWalk () {WalkingTrait.super.speakAndWalk ()}}

9. Traits implementeren tijdens runtime

Om een eigenschap dynamisch kunnen we gebruik de net zo trefwoord om een ​​object naar een eigenschap tijdens runtime.

Laten we bijvoorbeeld een AnimalTrait met de basisgedrag methode:

eigenschap AnimalTrait {String basicBehavior () {retourneer "Animalistic !!" }}

Om meerdere eigenschappen tegelijk te implementeren, kunnen we de met Traits methode in plaats van de net zo trefwoord:

def dog = new Dog () def dogWithTrait = dog.withTraits SpeakingTrait, WalkingTrait, AnimalTrait

10. Conclusie

In dit artikel hebben we gezien hoe we eigenschappen in Groovy kunnen creëren en hebben we enkele van hun handige functies onderzocht.

EEN eigenschap is een echt effectieve manier om algemene implementaties en functionaliteiten toe te voegen aan onze lessen. Bovendien kunnen we overtollige code minimaliseren en wordt het onderhoud van de code eenvoudiger.

Zoals gewoonlijk zijn de code-implementaties en unit-tests voor dit artikel beschikbaar op GitHub.