Hoi! U weet al hoe u uw eigen klassen met velden en methoden kunt maken. Nu zullen we stilstaan bij methoden.
Natuurlijk hebben we dit al meer dan eens gedaan in onze lessen, maar we hebben het vooral over algemeenheden gehad. Vandaag gaan we methoden ontleden en bestuderen waar ze van gemaakt zijn, de verschillende manieren om ze te maken en hoe we het allemaal kunnen beheren. :) Laten we gaan!
Methode verklaring
Alle code die een methode definieert, wordt een methodedeclaratie genoemd . De algemene vorm van een methodedeclaratie kan als volgt worden beschreven:
access modifier, return type, method name (parameter list) {
// method body
}
Bekijk als voorbeelden de declaraties van de verschillende methoden van de Dog
klasse.
public class Dog {
String name;
public Dog(String name) {
this.name = name;
}
public static void main(String[] args) {
Dog max = new Dog("Max");
max.woof();
}
public void woof() {
System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}
public void run(int distanceInFeet) {
System.out.println("A dog named " + name + " ran " + distanceInFeet + " feet!");
}
public String getName() {
return name;
}
}
1. Toegangsmodificator
De toegangsmodifier wordt altijd als eerste aangegeven. AlleDog
methoden van de klasse zijn gemarkeerd met de public modifier. Dit betekent dat we ze vanuit elke andere klasse kunnen aanroepen:
public class Main {
public static void main(String[] args) {
Dog butch = new Dog("Butch");
butch.run(100);
}
}
Zoals u kunt zien, Dog
zijn de methoden van de klasse gemakkelijk toegankelijk in de Main
klasse. Dit is mogelijk dankzij de openbare modifier. In Java zijn er andere modifiers. Ze staan niet allemaal toe dat methoden in andere klassen worden gebruikt. We zullen er in andere lessen over praten. Het belangrijkste om te onthouden is waar de modifier verantwoordelijk voor is: of een methode toegankelijk is in andere klassen :)
2. statisch zoekwoord
Een van deDog
methoden, main()
, is gemarkeerd met het trefwoord statisch . Het maakt ook deel uit van de methodedeclaratie en we kennen de betekenis ervan al. We hebben het niet vermeld in het methodedeclaratiesjabloon dat aan het begin van de les is gegeven, omdat het optioneel is. Als het is opgegeven, moet het na de toegangsmodifier komen. Weet je nog dat we het de afgelopen lessen hadden over statische (klasse)variabelen? Toegepast op methoden heeft dit trefwoord ongeveer dezelfde betekenis. Als een methode statisch is , kan deze worden gebruikt zonder verwijzing naar een specifiek object van de klasse. En inderdaad, je hebt geen Dog
object nodig om de statische main()
methode in deDog
klas. Het zal prima werken zonder een. Als deze methode niet statisch zou zijn, zouden we eerst een object moeten maken om het uit te voeren.
3. Retourwaarde
Als onze methode iets moet retourneren, specificeren we het type van de geretourneerde waarde. Dit blijkt uit het voorbeeld van degetName()
getter:
public String getName() {
return name;
}
Het retourneert een String
object. Als een methode niets retourneert, wordt in plaats daarvan het trefwoord void gebruikt, zoals in de woof()
methode:
public void woof() {
System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}
Methoden met dezelfde naam
Er zijn situaties waarin we verschillende manieren willen om een methode aan te roepen. Waarom creëren we niet onze eigen kunstmatige intelligentie? Amazon heeft Alexa, Apple heeft Siri, dus waarom zouden wij er geen hebben? :) In de film Iron Man creëert Tony Stark zijn eigen ongelooflijke kunstmatige intelligentie, Jarvis. Laten we hulde brengen aan dat geweldige personage en onze AI ter ere van hem noemen. :) Het eerste wat we moeten doen, is Jarvis leren hallo te zeggen tegen mensen die de kamer binnenkomen (het zou raar zijn als zo'n geweldig intellect onbeleefd zou blijken te zijn).
public class Jarvis {
public void sayHi(String name) {
System.out.println("Good evening, " + name + ". How are you?");
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.sayHi("Tony Stark");
}
}
Console-uitvoer: Goedenavond, Tony Stark. Hoe is het met je? Erg goed! Jarvis kan nu gasten verwelkomen. Natuurlijk, vaker dan het zal zijn meester zijn, Tony Stark. Maar wat als hij niet alleen komt! Maar onze sayHi()
methode accepteert slechts één argument. En dus kan het maar één persoon begroeten die de kamer binnenkomt, en zal het de ander negeren. Niet erg beleefd, mee eens? :/ In dit geval kunnen we het probleem oplossen door simpelweg 2 methoden te schrijven met dezelfde naam, maar met verschillende parameters:
public class Jarvis {
public void sayHi(String firstGuest) {
System.out.println("Good evening, " + firstGuest + ". How are you?");
}
public void sayHi(String firstGuest, String secondGuest) {
System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
}
}
Dit wordt methode-overbelasting genoemd . Methode-overloading maakt ons programma flexibeler en biedt plaats aan verschillende manieren van werken. Laten we eens kijken hoe het werkt:
public class Jarvis {
public void sayHi(String firstGuest) {
System.out.println("Good evening, " + firstGuest + ". How are you?");
}
public void sayHi(String firstGuest, String secondGuest) {
System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.sayHi("Tony Stark");
jarvis.sayHi("Tony Stark", "Captain America");
}
}
Console-uitvoer: Goedenavond, Tony Stark. Hoe is het met je? Goedenavond, Tony Stark en Captain America. Hoe is het met je? Uitstekend, beide versies werkten. :) Maar we hebben het probleem niet opgelost! Wat als er drie gasten zijn? We zouden de methode natuurlijk sayHi()
opnieuw kunnen overbelasten, zodat deze drie gastnamen accepteert. Maar het kunnen er 4 of 5 zijn. Helemaal tot in het oneindige. Is er geen betere manier om Jarvis te leren omgaan met een willekeurig aantal namen, zonder de sayHi()
methode een miljoen keer te overbelasten()? :/ Natuurlijk is dat zo! Als dat niet zo was, zou Java dan de populairste programmeertaal ter wereld zijn? ;)
public class Jarvis {
public void sayHi(String...names) {
for (String name: names) {
System.out.println("Good evening, " + name + ". How are you?");
}
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.sayHi("Tony Stark");
System.out.println();
jarvis.sayHi("Tony Stark", "Captain America");
}
}
Wanneer ( String... names ) als parameter wordt gebruikt, geeft dit aan dat een verzameling Strings aan de methode zal worden doorgegeven. We hoeven niet van tevoren aan te geven hoeveel het er zullen zijn, dus nu is onze methode veel flexibeler:
public class Jarvis {
public void sayHi(String...names) {
for (String name: names) {
System.out.println("Good evening, " + name + ". How are you?");
}
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
}
}
Console-uitvoer: Goedenavond, Tony Stark. Hoe is het met je? Goedenavond, Kapitein Amerika. Hoe is het met je? Goedenavond, zwarte weduwe. Hoe is het met je? Goedenavond, Hulk. Hoe is het met je? Binnen de methode herhalen we alle argumenten en geven we zinnen weer die zijn opgemaakt met namen. Hier gebruiken we een vereenvoudigde for-each
lus (die je eerder hebt gezien). Het is hier perfect, omdat de notatie ( String... names ) eigenlijk betekent dat de compiler alle doorgegeven argumenten in een array plaatst. Hierdoor kunnen we werken met variabelenamenzoals we zouden werken met een array, inclusief door er in een lus doorheen te gaan. Bovendien werkt het met een willekeurig aantal doorgegeven strings! Twee, tien, zelfs duizend - de methode werkt goed met een willekeurig aantal gasten. Veel handiger dan de methode te overbelasten voor alle mogelijkheden, vind je niet? :) Hier is nog een voorbeeld van methode-overbelasting. Laten we Jarvis een printInfoFromDatabase()
methode geven. Het toont informatie over een persoon uit een database. Als de database aangeeft dat een persoon een superheld of superschurk is, geven we die informatie weer:
public class Jarvis {
public void printInfoFromDatabase (String bio) {
System.out.println(bio);
}
public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {
System.out.println(bio);
if (!isEvil) {
System.out.println("Also known as the superhero " + nickname);
} else {
System.out.println("Also known as the supervillain " + nickname);
}
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.printInfoFromDatabase("Laura Palmer. Date of birth: July 22, 1972. Twin Peaks, Washington");
System.out.println();
jarvis.printInfoFromDatabase("Max Eisenhardt. Height: 15.6 ft. Weight: 189 lbs. ", true, "Magneto");
}
}
Uitvoer: Laura Palmer. Geboortedatum: 22 juli 1972. Twin Peaks, Washington Max Eisenhardt. Hoogte: 15,6 ft. Gewicht: 189 lbs. Ook bekend als de superschurk Magneto . Het gedrag van onze methode hangt dus af van de gegevens die we eraan doorgeven. Hier is nog een belangrijk punt: de volgorde van de argumenten is belangrijk! Laten we zeggen dat onze methode een string en een nummer nodig heeft:
public class Person {
public static void sayYourAge(String greeting, int age) {
System.out.println(greeting + " " + age);
}
public static void main(String[] args) {
sayYourAge("My age is ", 33);
sayYourAge(33, "My age is "); // Error!
}
}
Als de methode Person
van de klasse sayYourAge()
een string en een getal als invoer heeft, dan is dit de volgorde waarin deze argumenten aan de methode moeten worden doorgegeven! Als we ze in een andere volgorde doorgeven, genereert de compiler een fout en kan de persoon zijn leeftijd niet zeggen. Trouwens, constructors, die we in de vorige les hebben behandeld, zijn ook methoden! Je kunt ze ook overbelasten (dwz verschillende constructors maken met verschillende sets parameters) en de volgorde van doorgegeven argumenten is ook voor hen van fundamenteel belang. Het zijn echte methoden! :)
Methoden aanroepen met vergelijkbare parameters
Zoals u weet,null
is een sleutelwoord in Java. Het is heel belangrijk om te begrijpen dat dit null
noch een object, noch een gegevenstype is . Stel je voor dat we een Person
klas en een introduce()
methode hebben die de naam en leeftijd van de persoon bekendmaakt. Verder kan de leeftijd worden doorgegeven als tekst of een cijfer.
public class Person {
public void introduce(String name, String age) {
System.out.println("My name is " + name + ". My age is " + age);
}
public void introduce(String name, Integer age) {
System.out.println("My name is " + name + ". My age is " + age);
}
public static void main(String[] args) {
Person alex = new Person();
alex.introduce ("Alex", "twenty-one");
Person mary = new Person();
mary.introduce("Mary", 32);
}
}
We zijn al bekend met overbelasting, dus we weten dat beide methoden werken zoals het hoort: Mijn naam is Alex. Mijn leeftijd is eenentwintig. Mijn naam is Mary. Mijn leeftijd is 32 Maar wat gebeurt er als we null
als tweede parameter doorgeven in plaats van een string of een getal?
public static void main(String[] args) {
Person victor = new Person();
victor.introduce("Victor", null);// Ambiguous method call!
}
We krijgen een compilatiefout! Waardoor wordt dit veroorzaakt en wat is precies de "ambiguïteit"? Eigenlijk is het allemaal heel simpel. Het probleem is dat we twee versies van de methode hebben: één met a String
als tweede argument en één met an Integer
als tweede argument. Maar a String
en an Integer
kunnen beide zijn null
! Omdat het referentietypen zijn, null
is dit de standaardwaarde voor beide. Daarom kan de compiler in deze situatie niet achterhalen welke versie van de methode hij moet aanroepen. De oplossing voor dit probleem is vrij eenvoudig. Null
kan expliciet worden geconverteerd naar een specifiek referentietype. Dus wanneer u een methode aanroept, kunt u tussen haakjes aangeven welk gegevenstype u wilt voor het tweede argument! De compiler begrijpt uw "hint" en roept de juiste methode aan:
public class Person {
public void introduce(String name, String age) {
System.out.println("Method with two strings!");
System.out.println("My name is " + name + ". My age is " + age);
}
public void introduce(String name, Integer age) {
System.out.println("Method with a string and a number!");
System.out.println("My name is " + name + ". My age is " + age);
}
public static void main(String[] args) {
Person victor = new Person();
victor.introduce("Victor", (String) null);
}
}
Uitvoer: Methode met twee snaren! Mijn naam is Victor. Mijn leeftijd is null Merk op dat als de parameter number een primitieve was int
, in plaats van een instantie van het Integer-referentietype, er niet zo'n fout zou zijn opgetreden.
public class Person {
public void introduce(String name, String age) {
System.out.println("Method with two strings!");
System.out.println("My name is " + name + ". My age is " + age);
}
public void introduce(String name, int age) {
System.out.println("Method with a string and a number!!");
System.out.println("My name is " + name + ". My age is " + age);
}
public static void main(String[] args) {
Person victor = new Person();
victor.introduce("Victor", null);
}
}
Kun je raden waarom? Als je raadt waarom, goed gedaan! :) Omdat primitieven dat niet kunnen zijn null
. Nu heeft de compiler nog maar één keuze, namelijk de methode aanroepen introduce()
met twee strings. Dit is de versie van de methode die wordt uitgevoerd telkens wanneer de methode wordt aangeroepen.
Meer lezen: |
---|
GO TO FULL VERSION